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 |
|
---|
23 | class i4_gui_stat_handle : public i4_status_class
|
---|
24 | {
|
---|
25 | int id;
|
---|
26 | public:
|
---|
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 |
|
---|
32 | class 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 |
|
---|
40 | public:
|
---|
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 |
|
---|
156 | int show_blts=0;
|
---|
157 |
|
---|
158 | class 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 |
|
---|
188 | public:
|
---|
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 |
|
---|
358 | i4_gui_status_creator_class *i4_gui_status_creator=0;
|
---|
359 |
|
---|
360 |
|
---|
361 | i4_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 |
|
---|
369 | i4_gui_stat_handle::~i4_gui_stat_handle()
|
---|
370 | {
|
---|
371 | i4_gui_status_creator->delete_stat(id);
|
---|
372 | }
|
---|
373 |
|
---|
374 |
|
---|
375 |
|
---|
376 | i4_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 |
|
---|
381 | void 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 |
|
---|
392 | void i4_set_status_create_function(i4_status_create_function_type fun);
|
---|
393 |
|
---|
394 |
|
---|
395 | void 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 | }
|
---|