source: golgotha/src/i4/window/window.hh @ 608

Last change on this file since 608 was 80, checked in by Sam Hocevar, 15 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 11.6 KB
RevLine 
[80]1/********************************************************************** <BR>
2  This file is part of Crack dot Com's free source code release of
3  Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
4  information about compiling & licensing issues visit this URL</a>
5  <PRE> If that doesn't help, contact Jonathan Clark at
6  golgotha_source@usa.net (Subject should have "GOLG" in it)
7***********************************************************************/
8
9#ifndef __I4_WINDOW_HPP_
10#define __I4_WINDOW_HPP_
11
12class i4_image_class;
13class i4_cursor_class;
14
15#include "area/rectlist.hh"
16#include "device/device.hh"
17#include "area/rectlist.hh"
18#include "device/event.hh"
19#include "isllist.hh"
20#include "image/context.hh"
21
22//  Brief summary :
23//
24//    2 Main classes are defined here :
25//    i4_window_class :
26//    base object for most everything graphical. 
27//    An i4_window_class should only draw (using local_image) during draw().
28//    During draw(), proper clipping is setup. 
29//    local_image will transform local coordinates to global space for you.
30//    because a window is derived from i4_event_handler_class,
31//    it can receive events through receive_event (see device/device.hh
32//    for more info on this.  A the base window class does not process any events.
33//
34//    i4_parent_window_class :
35//    parent windows have a list of children window. 
36//    The draw order for children is painter's algorithm.  So the last
37//    child in the list gets drawn on top.  parent windows also
38//    maintain a dirty_area list so that redraw can be done
39//    more efficiently than redrawing themselves & their children completely.
40//    parent windows have a default behavior for responding to a
41//    number of events.  parent windows keep a mouse & keyboard
42//    focus.   The mouse focus is set automically through mouse_move events. 
43//    The key focus is not implemented yet.
44//
45
46class i4_parent_window_class;
47
48class i4_window_class : public i4_event_handler_class
49{
50protected:
51 
52  // Data members you need not worry about
53  i4_image_class     *global_image;  // pointer to the image associated with the display we draw on
54 
55  i4_coord global_x,global_y,   // returned by x() & y()
56           mouse_x, mouse_y;
57  w16 w,h;
58  i4_bool redraw_flag;
59
60 
61  i4_image_class *local_image;        /* this will transform all drawing coordinates
62                                   from local-space to glabal space
63                                   plus when drawing is done from draw()
64                                   proper clipping for you window is setup beforehand */
65  i4_parent_window_class *parent;     // this may be 0
66  i4_cursor_class *cursor;
67
68public:
69 
70  // next pointer is used by i4_parent_window_class's isl_list
71  i4_window_class *next;
72 
73  virtual void receive_event(i4_event *ev);
74
75  // initially when a window is created it has no parent
76  i4_window_class(w16 w, w16 h); 
77
78  i4_coord x() { return global_x; }
79  i4_coord y() { return global_y; }
80  w16 width() { return w; }
81  w16 height() { return h; }
82
83  i4_coord last_mouse_x() { return mouse_x; }  // last position in the window mouse was at
84  i4_coord last_mouse_y() { return mouse_y; }
85
86
87  // forget redraw is called by a parent if the child had ask for a redraw but
88  // when the parent got around to doing the redraw, the child was clipped away
89  virtual void forget_redraw() { redraw_flag=i4_F; }
90
91  // request draw should be called in the calculating part of a windows processing
92  // the windows draw() function will then be called later with the correct clip list
93  // 2 versions of request_redraw exist, one redraws
94  // everything, and one tells of a specific area to redraw
95  // a window may call request_redraw() within it's draw() to display continual animations
96
97  virtual void request_redraw(i4_bool for_a_child=i4_F);
98
99  // x1, y1, x2, y2 are in local-space coordinates
100  // this used to be called request_redraw, but it got confused with regular request_redraw
101  // this is called whan a window's area becomes visible when it wasn't before
102  virtual void note_undrawn(i4_coord x1, i4_coord y1, i4_coord x2, i4_coord y2,
103                            i4_bool propogate_to_children=i4_T);
104
105  // a parent uses this to determine that you need to have your draw() function called
106  virtual i4_bool need_redraw() { return redraw_flag; }
107
108  // draw is called by parent sometime after request_draw() is called
109  // this draw may not occur if window is clipped away, in which case forget_redraw() is called
110  virtual void draw(i4_draw_context_class &context);
111
112  // move can be used to a change window's position
113  // within a window, to give a window a draw_area and parent or both
114  // move will also send a notify_move event to it's parent
115  // (if it has one), whereas private_move will not
116  // if draw_under is false the parent will not draw under
117  //the dirty area the window's movement created
118  virtual void move(i4_coord x_offset, i4_coord y_offset, i4_bool draw_under=i4_T);
119
120  // private move will not notify it's parent, and should
121  // probably only be called by the parent.
122  virtual void private_move(i4_coord new_x, i4_coord new_y);
123
124  // private resize will not notify it's parent, and
125  // should probably only be called by your parent
126  virtual void private_resize(w16 new_width, w16 new_height);
127 
128  virtual void reparent(i4_image_class *draw_area, i4_parent_window_class *parent);
129
130  // resize will change the width and height of our window and notify our parent of the change
131  virtual void resize(w16 new_width, w16 new_height);
132
133
134  // this sets the mouse image to displayed when the cursor
135  // enters this window.  The actual act of changing the cursor
136  // is done by i4_window_class::receive_event() on GOT & LOST mouse
137  // focus events.  So a derived window must remember to call
138  // the shadowed receive_event or the cursor will not change.
139  // If cursor is 0, then the cursor will not change
140  // shape when it enters this window.
141    virtual void set_cursor(i4_cursor_class *cursor);
142
143
144  virtual ~i4_window_class();
145  void show_context(i4_draw_context_class &context);
146
147  i4_bool isa_parent(i4_window_class *who);
148  virtual i4_parent_window_class *root_window();
149
150  // if this is true, then parent will not clip you out when it draws
151  virtual i4_bool transparent() { return i4_F; }
152
153  i4_parent_window_class *get_parent() { return parent; }
154#ifndef I4_RETAIL
155  void debug_show();
156#endif
157};
158
159
160class i4_parent_window_class : public i4_window_class
161{
162private:
163  i4_bool mouse_focus_grabbed, have_mouse_focus;
164  i4_bool child_rerequested_redraw;
165  void send_event_to_child(i4_window_class *w, i4_event *ev);
166 
167protected:
168  i4_bool child_need_redraw;
169
170  virtual void private_move(i4_coord x_offset, i4_coord y_offset);
171
172 
173  typedef i4_isl_list<i4_window_class>           win_list;
174  typedef i4_isl_list<i4_window_class>::iterator win_iter;
175
176  win_list children;
177  win_iter key_focus, mouse_focus, drag_drop_focus;
178 
179
180  // Note:
181  // so a parent can refresh itself and children more efficiently it keeps a list of dirty area.
182  // this is kept in global coordinates for several reasons.   It is important to note that
183  // request_redraw(x1,y1,x2,y2) takes coordinates in local_space, but transforms them to
184  // local space when adding to dirty_area
185  i4_rect_list_class undrawn_area;   
186
187
188  // These functions shouldn't really be needed by derived classes
189  void change_key_focus(i4_window_class *new_focus);
190  void change_mouse_focus(i4_window_class *new_focus);
191  void redraw_area(i4_coord x1, i4_coord y1, i4_coord x2, i4_coord y2);   // in local coordinates
192  win_iter find_window(i4_coord mouse_x, i4_coord mouse_y);
193 
194  void drag_drop_move(i4_event *ev);
195  void mouse_move(i4_event *ev);
196
197public:
198  i4_bool has_mouse_focus() { return have_mouse_focus; }
199  virtual i4_bool find_new_mouse_focus();  // return true if focus changed
200
201  virtual i4_parent_window_class *root_window();
202
203  virtual void resize(w16 new_width, w16 new_height);
204  virtual void reparent(i4_image_class *draw_area, i4_parent_window_class *parent);
205
206  // these functions are called when REQUEST_NEXT_FOCUS, etc. events are recieved
207    // so that you can over-ride these event functionalities if you want
208  virtual void next_key_focus();
209  virtual void left_key_focus();
210  virtual void right_key_focus();
211  virtual void up_key_focus();
212  virtual void down_key_focus();
213 
214  // Because a parent window needs to tells it's children
215  // to draw() as well and setup proper clipping for itself
216  // a parent_draw() function is supplied which is called by draw() which is where all drawing
217  // done by a derived class of i4_window_class should go.  parent_draw() will have the correct clipping
218  // list (including the exclusion of it's children.
219    virtual void draw(i4_draw_context_class &context);
220
221  // see comment's above draw(), this function should be used by derived class instead of draw()
222  virtual void parent_draw(i4_draw_context_class &context);
223
224  // receive_event is a general event notification routine. 
225  // If you get a event and note that you cannot handle it, you should
226  // pass it on down to you derived parent so that functionality still works
227  // example receive_event :
228  // void receive_event(i4_event *ev)
229  // {
230  //   if (ev->type==i4_event::MOUSE_MOVE)
231  //   {
232  //     do something
233  //   } else i4_parent_window_class::receive_event(ev);
234  // } 
235  virtual void receive_event(i4_event *ev);
236 
237  //  forget redraw is called by a parent if the child had ask for a redraw but
238  // when the parent got around to doing the redraw, the child was clipped away
239  // for the parent window case, undrawn_area is discarded and all
240  // children's forget_redraw are called
241  virtual void forget_redraw();
242
243  i4_parent_window_class(w16 w, w16 h);
244
245  // x & y are relative to parent x,y (added to end of window list)
246  virtual void add_child(i4_coord x, i4_coord y, i4_window_class *child); 
247
248  // x & y are relative to parent x,y (added to front of window list)
249  virtual void add_child_front(i4_coord x, i4_coord y, i4_window_class *child); 
250
251  // does not delete the child, simply removes and request redraw under its area
252  virtual void remove_child(i4_window_class *child);                       
253
254  // removes all children from self and addes them into other_parent
255  void transfer_children(i4_parent_window_class *other_parent,
256                         i4_coord x_offset, i4_coord y_offset);
257
258  // arranges child windows from left to right then down
259  virtual void arrange_right_down();                                 
260
261  // arranges child windows from top to bottom then right
262  virtual void arrange_down_right();                                 
263
264  // makes the window the minimum size needed to fit all children
265  virtual void resize_to_fit_children();
266
267  // adds all local area to undrawn_area
268  virtual void request_redraw(i4_bool for_a_child=i4_F);                           
269
270  // adds this area to undrawn_area (in local coordinates)
271  virtual void note_undrawn(i4_coord x1, i4_coord y1, i4_coord x2, i4_coord y2,
272                            i4_bool propogate_to_children=i4_T);
273
274
275  virtual i4_bool need_redraw()
276  // returns true if we have any dirty area or childen report they need redrawing
277  { return (i4_bool)(!undrawn_area.empty()|
278                     child_need_redraw |
279                     i4_window_class::need_redraw()); }
280 
281  virtual i4_window_class *get_nth_window(w32 win_num);
282
283  i4_bool isa_child(i4_window_class *w);
284
285  virtual ~i4_parent_window_class();
286};
287
288#endif
289
Note: See TracBrowser for help on using the repository browser.