source: golgotha/src/i4/status/gui_stat.cc @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 14 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: 8.9 KB
Line 
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#include "status/status.hh"
10#include "window/window.hh"
11#include "window/style.hh"
12#include "math/num_type.hh"
13#include "window/wmanager.hh"
14#include "memory/array.hh"
15#include "window/style.hh"
16#include "time/time.hh"
17#include "window/win_evt.hh"
18#include "gui/button.hh"
19#include "gui/text.hh"
20#include "gui/deco_win.hh"
21#include "device/kernel.hh"
22
23class i4_gui_stat_handle : public i4_status_class
24{
25  int id;
26public:
27  i4_gui_stat_handle(int id, int flags) : id(id) {}
28  virtual i4_bool update(float percent);
29  virtual ~i4_gui_stat_handle();
30};
31
32class i4_gui_stat_window : public i4_parent_window_class
33{
34  i4_graphical_style_class *style;
35  i4_str *show_str;
36  int lx2;
37  i4_bool canceled;
38  int dir, flags;
39
40public:
41  i4_float percent;
42
43  i4_gui_stat_window(float percent,
44                     w16 w, w16 h,
45                     i4_graphical_style_class *style,
46                     const i4_const_str &str,
47                     int flags) :
48    i4_parent_window_class(w,h), style(style),
49    percent(percent),
50    flags(flags)
51  {
52    show_str=new i4_str(str);
53    lx2=0;
54    canceled=0;
55    dir=1;
56
57
58    if (flags & I4_STATUS_ALLOW_CANCEL)
59    {
60      i4_button_class *b;
61      b=new i4_button_class(0, new i4_text_window_class(i4gets("cancel_operation"), style),
62                            style, new i4_event_reaction_class(this, 1));
63
64      resize(width() < b->width() ? b->width() : width(), height() + b->height() + 6);
65     
66      add_child(width()/2-b->width()/2, height()-b->height()-3, b);   
67    }
68  }
69
70  void receive_event(i4_event *ev)
71  {
72    if (ev->type()==i4_event::USER_MESSAGE)
73      canceled=i4_T;
74    else i4_parent_window_class::receive_event(ev);
75  }
76 
77  void parent_draw(i4_draw_context_class &context)
78  {
79
80    int x1=2, x2=width()-3;
81    int y=10;
82    int bx2=(sw32)(x1+(x2-x1+1)*percent);
83
84    if (undrawn_area.empty() && bx2==lx2)
85      return;
86    lx2=bx2;
87
88    i4_font_class *f=style->font_hint->normal_font;
89    int fh=f->height(*show_str);
90
91    if (!undrawn_area.empty())
92    {
93      local_image->clear(style->color_hint->neutral(), context);
94
95
96      f->set_color(style->color_hint->text_foreground);
97
98      int fw=f->width(*show_str);
99
100      f->put_string(local_image, width()/2-fw/2, y, *show_str, context);
101    }
102
103   
104    y+=fh+10;
105
106    if (!undrawn_area.empty())
107    {
108      local_image->bar(x1-1, y-1, x2+1, y+6+1, 0, context);
109      local_image->bar(x1, y, x2, y+6, style->color_hint->window.active.dark, context);
110    }
111
112    x1++; x2--;
113    local_image->bar(x1, y, bx2, y+6,
114                     style->color_hint->window.active.bright,
115                     context);
116  }
117
118  i4_bool update_percent(float p)
119  {
120    if (flags & I4_STATUS_UNKNOWN_TOTAL)
121    {
122      if (dir>0)
123      {
124        percent+=0.05;
125        if (percent>1)
126        {
127          percent=1;
128          dir=-1;
129        }
130      }
131      else
132      {
133        percent-=0.05;
134        if (percent<0)
135        {
136          percent=0;
137          dir=1;
138        }
139      }
140    }
141    else   
142      percent=p;
143
144    request_redraw();
145    return !canceled;
146  }
147
148  ~i4_gui_stat_window()
149  {
150    delete show_str;
151  }
152 
153  char *name() { return "gui_stat_window"; }
154};
155
156int show_blts=0;
157
158class i4_gui_status_creator_class : public i4_event_handler_class
159{
160  i4_window_manager_class *wm;
161  i4_display_class *display;
162
163  struct stat
164  {
165    i4_gui_stat_window *win;
166    i4_bool allocated;
167    i4_time_class start_time;
168    i4_str *desc;
169    int flags;
170  };
171
172  i4_array<stat> wins;
173  i4_time_class last_update_time;
174  sw32 grab_id;
175
176  int get_window_y(i4_window_class *w)
177  {
178    int y= wm->height() - w->height();
179
180    for (int i=0; i<wins.size(); i++)
181      if (wins[i].allocated && wins[i].win)
182        y-=wins[i].win->height();
183
184    return y;
185  }
186
187
188public:
189  char *name() { return "gui_status"; }
190  i4_gui_status_creator_class(i4_window_manager_class *wm,
191                              i4_display_class *display)
192    : wins(2,10),
193      wm(wm), display(display)
194  {
195    grab_id=-1;
196  }
197
198
199
200  i4_status_class *create(const i4_const_str &description, int flags)
201  {
202    int id=0;
203    for (id=0; id<wins.size() && wins[id].allocated; id++);
204    if (id==wins.size())
205      wins.add();
206
207
208    stat st;
209    st.allocated=i4_T;
210    st.desc=new i4_str(description);
211    st.win=0;
212    st.flags=flags;
213
214    wins[id]=st;
215 
216
217    return new i4_gui_stat_handle(id, flags);
218  }
219
220
221  void ungrab_id(int id)
222  {
223    if (grab_id==id)
224    {
225      i4_parent_window_class *p=wins[id].win->get_parent();
226
227      i4_window_request_mouse_ungrab_class ungrab(wins[id].win);
228      i4_kernel.send_event(p, &ungrab);
229
230      grab_id=-1;
231    }
232  }
233
234  void grab_new_id()
235  {
236    for (int i=0; i<wins.size(); i++)
237      if (wins[i].allocated && wins[i].win)
238      {
239        grab_id=i;
240        i4_window_request_mouse_grab_class grab(wins[i].win);
241        i4_kernel.send_event(wins[i].win->get_parent(), &grab);
242        if (!grab.return_result)
243          grab_id=-1;
244      }
245   
246 
247  }
248
249  void receive_event(i4_event *ev)
250  {
251    if (ev->type()==i4_event::USER_MESSAGE)
252    {
253      CAST_PTR(uev, i4_user_message_event_class, ev);
254
255      int id=uev->sub_type;
256      if (id!=-1)
257        ungrab_id(id);
258
259      wins[id].win=0;
260
261      grab_new_id();
262
263    }
264  }
265 
266
267  void delete_stat(int id)
268  {
269    wins[id].allocated=i4_F;
270    delete wins[id].desc;
271
272    if (wins[id].win)
273    {
274      if (id!=-1)
275        ungrab_id(id);
276
277      i4_kernel.delete_handler(wins[id].win->get_parent());
278      wins[id].win=0;
279
280      grab_new_id();
281    }
282
283  }
284
285  i4_bool update(int id, float percent)
286  {
287    I4_ASSERT(wins[id].allocated, "id not allocated");
288
289    i4_time_class now;   
290    i4_bool ret=i4_T;
291
292    if (wins[id].win)
293    {
294      if (grab_id==-1)
295        grab_new_id();
296
297      if ((wins[id].flags & I4_STATUS_UNKNOWN_TOTAL) ||
298          percent-wins[id].win->percent>0.01)
299        ret=wins[id].win->update_percent(percent);
300     
301    }
302    else if (now.milli_diff(wins[id].start_time)>500 || percent==1.0)
303    {
304      i4_graphical_style_class *s=wm->get_style();
305      i4_font_class *f=s->font_hint->normal_font;
306
307      int fw=f->width(*wins[id].desc)+4;
308      if (fw<200) fw=200;
309      int fh=f->height(*wins[id].desc) + 30;
310
311      i4_deco_window_class *w;
312//       i4_user_message_event_class *uev=new i4_user_message_event_class(id);
313//       i4_event_reaction_class *re=new i4_event_reaction_class(this, uev);
314
315      i4_gui_stat_window *gs=new i4_gui_stat_window(percent, fw, fh, s, *wins[id].desc,
316                                                    wins[id].flags);
317   
318     
319      w=new i4_deco_window_class(gs->width(), gs->height(), i4_F, s);
320      w->add_child(w->get_x1(), w->get_y1(), gs);
321
322      int yp=get_window_y(w);
323      wm->add_child(wm->width()/2-w->width()/2, yp, w);
324
325      wins[id].win=gs;
326
327      if (grab_id==-1)
328      {
329        grab_id=id;
330        i4_window_request_mouse_grab_class grab(gs);
331        i4_kernel.send_event(w, &grab);
332        if (!grab.return_result)
333          grab_id=-1;
334      }
335
336    }
337
338
339    if (now.milli_diff(last_update_time)>100)  // only refresh 10 fps so we don't slow down process
340    {
341      show_blts=1;
342
343      if (!display->display_busy())
344        wm->root_draw();
345      show_blts=0;
346
347      i4_kernel.process_events();
348
349      last_update_time.get();
350    }
351
352    return ret;
353  }
354
355};
356
357
358i4_gui_status_creator_class *i4_gui_status_creator=0;
359
360
361i4_bool i4_gui_stat_handle::update(float percent)
362{
363  for (i4_idle_class *p=i4_idle_class::first; p;p=p->next)
364    p->idle();
365
366  return i4_gui_status_creator->update(id, percent);
367}
368
369i4_gui_stat_handle::~i4_gui_stat_handle()
370{
371  i4_gui_status_creator->delete_stat(id);
372}
373
374
375
376i4_status_class *i4_create_gui_stat(const i4_const_str &st, int flags)
377{
378  return i4_gui_status_creator->create(st, flags);
379}
380
381void i4_init_gui_status(i4_window_manager_class *wm,
382                        i4_display_class *display)
383{
384  if (i4_gui_status_creator)
385    i4_error("4_gui_status creator already created");
386
387  i4_gui_status_creator=new i4_gui_status_creator_class(wm, display);
388  i4_set_status_create_function(i4_create_gui_stat);
389}
390
391
392void i4_set_status_create_function(i4_status_create_function_type fun);
393
394
395void i4_uninit_gui_status()
396{
397  if (i4_gui_status_creator)
398  {
399    delete i4_gui_status_creator;
400    i4_gui_status_creator=0;
401  }
402}
Note: See TracBrowser for help on using the repository browser.