source: abuse/trunk/src/imlib/input.cpp @ 112

Last change on this file since 112 was 112, checked in by Sam Hocevar, 11 years ago
  • Fix spelling errors all over the place.
File size: 11.9 KB
Line 
1/*
2 *  Abuse - dark 2D side-scrolling platform game
3 *  Copyright (c) 1995 Crack dot Com
4 *
5 *  This software was released into the Public Domain. As with most public
6 *  domain software, no warranty is made or implied by Crack dot Com or
7 *  Jonathan Clark.
8 */
9
10#include "config.h"
11
12#include "input.hpp"
13#include "macs.hpp"
14
15
16void button::remap(filter *f)
17{
18  if (visual)
19  {
20    f->apply(visual);
21    if (pressed)
22      f->apply(pressed);
23  }
24}
25
26void button_box::press_button(int id)      // if button box doesn't contain id, nothing happens
27{
28}
29
30void button_box::remap(filter *f)
31{
32  for (button *b=buttons;b;b=(button *)b->next)
33    b->remap(f);
34}
35
36ifield *button_box::find(int search_id)
37{
38  if (search_id==id) return this;
39  for (ifield *i=(ifield *)buttons;i;i=i->next)
40    if (search_id==i->id) return i;
41  return NULL;
42}
43
44button_box::button_box(int X, int Y, int ID, int MaxDown, button *Buttons, ifield *Next)
45{
46  x=X; y=Y; id=ID; next=Next;
47  buttons=Buttons;
48  maxdown=MaxDown;
49  if (buttons && maxdown) buttons->push();  // the first button is automatically selected!
50}
51
52button_box::~button_box()
53{
54  while (buttons)
55  {
56    button *b=buttons;
57    buttons=(button *)buttons->next;
58    delete b;
59  }
60}
61
62void button_box::area(int &x1, int &y1, int &x2, int &y2)
63{
64  button *b=buttons;
65  if (!b) return ;
66  else
67  {
68    b->area(x1,y1,x2,y2);
69    int xp1,yp1,xp2,yp2;
70    for (b=(button *)b->next;b;b=(button *)b->next)
71    {
72      b->area(xp1,yp1,xp2,yp2);
73      if (xp1<x1) x1=xp1;
74      if (xp2>x2) x2=xp2;
75      if (yp1<y1) y1=yp1;
76      if (yp2>y2) y2=yp2;
77    }         
78  }
79}
80
81void button_box::draw_first(image *screen)
82{
83  for (button *b=buttons;b;b=(button *)b->next)
84    b->draw_first(screen);
85}
86
87void button_box::draw(int active, image *screen)
88{
89  return ;
90}
91
92void button_box::move(int newx, int newy)
93{
94    for(button * b = buttons; b; b = (button *)b->next)
95        b->move(newx + b->x, newy + b->y);
96    x = newx;
97    y = newy;
98}
99
100char *button_box::read()
101{
102  for (button *b=buttons;b;b=(button *)b->next)
103  {
104    if (*((int *)b->read())==0)
105      return (char *)b;
106  }
107  return NULL;
108}
109
110void button_box::handle_event(event &ev, image *screen, input_manager *im)
111{
112  switch (ev.type)
113  {
114    case EV_MOUSE_BUTTON :
115    {
116      int x1,y1,x2,y2;
117      int found=0;
118      for (button *b=buttons;!found && b;b=(button *)b->next)  // see if the user clicked on a button
119      {
120        b->area(x1,y1,x2,y2);
121        if (ev.mouse_move.x>=x1 && ev.mouse_move.x<=x2 &&
122            ev.mouse_move.y>=y1 && ev.mouse_move.y<=y2)
123        {
124          b->handle_event(ev,screen,im);
125
126          int total=0;
127          button *b2=buttons;
128          for (;b2;b2=(button *)b2->next)
129            if (*((int *)b2->read())==0)
130              total++;
131
132          if (*((int *)b->read())==0)  // did the user press or release the button
133          {
134            if (total>maxdown)
135            {
136              for (b2=buttons;total>maxdown && b2;b2=(button *)b2->next)
137                if ((b!=b2 || maxdown==0) && *((int *)b2->read())==0)
138                {
139                  total--;
140                  b2->push();
141                  b2->draw_first(screen);
142                }
143            }
144            b->draw_first(screen);
145          } else if (total==0 && maxdown)
146            b->push();    // don't let the user de-press a button if non others are selected.     
147
148          found=1; // don't look at anymore buttons
149
150        }
151      }
152    } break;   
153  }
154}
155
156
157void button_box::add_button(button *b)
158{
159  b->next=buttons;
160  buttons=b;
161}
162
163
164void button_box::arrange_left_right()
165{
166  button *b=buttons;
167  int x_on=x,x1,y1,x2,y2;
168  for (;b;b=(button *)b->next)
169  {
170    b->area(x1,y1,x2,y2);
171    b->x=x_on;
172    b->y=y;
173    x_on+=(x2-x1+1)+1;
174  } 
175}
176
177void button_box::arrange_up_down()
178
179  button *b=buttons;
180  int y_on=y,x1,y1,x2,y2;
181  for (;b;b=(button *)b->next)
182  {
183    b->area(x1,y1,x2,y2);
184    b->y=y_on;
185    b->x=x;
186    y_on+=(y2-y1+1)+1;
187  } 
188}
189
190void button::change_visual(image *new_visual)
191{
192  CHECK(visual);
193  visual=new_visual;
194}
195
196void button::area(int &x1, int &y1, int &x2, int &y2)
197
198  x1=x; y1=y;
199  if (pressed)
200  {
201    x2=x+pressed->width()-1;
202    y2=y+pressed->height()-1;
203  }
204  else
205  {
206    if (text)
207    {   
208      x2=x+wm->font()->width()*strlen(text)+6;
209      y2=y+wm->font()->height()+6;
210    } else
211    {
212      x2=x+6+visual->width();
213      y2=y+6+visual->height();
214    }
215  }
216}
217
218
219button::button(int X, int Y, int ID, char const *Text, ifield *Next)
220
221  x=X; y=Y; id=ID;
222  act_id=-1;
223  text=strcpy((char *)jmalloc(strlen(Text)+1,"input button"),Text);
224  up=1; next=Next; act=0;
225  visual=NULL;
226  pressed=NULL;
227}
228
229
230button::button(int X, int Y, int ID, image *vis, ifield *Next)
231{ x=X; y=Y; id=ID; text=NULL;
232  act_id=-1;
233  visual=vis; up=1; next=Next; act=0;
234  pressed=NULL;
235}
236
237button::button(int X, int Y, int ID, image *Depressed, image *Pressed, image *active, ifield *Next)
238{ x=X; y=Y; id=ID; text=NULL;
239  act_id=-1;
240  visual=Depressed; up=1; next=Next; act=0;
241  pressed=Pressed;
242  act_pict=active;
243}
244
245
246void text_field::change_data(char const *new_data, int new_cursor, // cursor==-1, does not change it.
247                             int active, image *screen)
248{
249  if (strlen(format)<strlen(new_data))
250    data=(char *)jrealloc(data,strlen(new_data),"text field input");
251
252  strcpy(data,new_data);
253  if (new_cursor!=-1)
254    cur=new_cursor;
255  draw_first(screen);
256  draw(active,screen);
257}
258
259char *text_field::read()
260{
261  while (*data && data[strlen(data)-1]==' ') data[strlen(data)-1]=0;
262  return data;
263}
264
265void text_field::handle_event(event &ev, image *screen, input_manager *im)
266{
267  int xx;
268  if (ev.type==EV_KEY)
269  {
270    switch (ev.key)
271    {
272      case JK_LEFT : if (cur) { draw_cur(wm->dark_color(),screen); cur--;
273                           draw_cur(wm->bright_color(),screen); } break;
274      case JK_RIGHT : if (cur<(int)strlen(format)-1) { draw_cur(wm->dark_color(),screen); cur++;
275                           draw_cur(wm->bright_color(),screen); } break;
276      case JK_END : if (cur!=last_spot())
277                          { draw_cur(wm->dark_color(),screen); cur=last_spot();
278                            if (cur==(int)strlen(format)-1) cur--;
279                           draw_cur(wm->bright_color(),screen); } break;
280      case JK_HOME : if (cur)
281                          { draw_cur(wm->dark_color(),screen); cur=0;
282                           draw_cur(wm->bright_color(),screen); } break;
283      case JK_BACKSPACE : if (cur)
284         { draw_cur(wm->dark_color(),screen); cur--;
285           for (xx=cur;xx<(int)strlen(format)-1;xx++)
286             data[xx]=data[xx+1];
287           data[strlen(format)-1]=' ';
288           draw_text(screen);
289           draw_cur(wm->bright_color(),screen);
290           wm->push_event(new event(id,(char *)this));
291         } break;
292      default : if (ev.key>=' ' && ev.key<='~')
293         {
294           draw_cur(wm->dark_color(),screen);
295           for (xx=strlen(format)-1;xx>cur && xx>0;xx--)
296             data[xx]=data[xx-1];
297           data[cur]=ev.key;
298           if (cur<(int)strlen(format)-1)
299             cur++;
300           data[strlen(format)]=0;
301           draw_text(screen);
302           draw_cur(wm->bright_color(),screen);
303           wm->push_event(new event(id,(char *)this));
304         } break;
305    }
306  }
307}
308
309void text_field::draw(int active, image *screen)
310{
311  if (active)
312  {
313    screen->rectangle(xstart(),y,xend(),yend(),wm->bright_color());
314    draw_cur(wm->bright_color(),screen);
315  }
316  else
317  {
318    screen->rectangle(xstart(),y,xend(),yend(),wm->dark_color());
319    draw_cur(wm->dark_color(),screen);
320  }
321}
322
323void text_field::area(int &x1, int &y1, int &x2, int &y2)
324{
325  x1=x; y1=y;
326  x2=xend();
327  y2=yend();
328}
329
330text_field::text_field(int X, int Y, int ID, char const *Prompt,
331                       char const *Format, char const *Data, ifield *Next)
332{
333  int slen=(strlen(Format)>strlen(Data) ? strlen(Format) : strlen(Data));
334
335  x=X; y=Y; id=ID;
336  prompt=strcpy((char *)jmalloc(strlen(Prompt)+1,"text_field::prompt"),Prompt);
337  format=strcpy((char *)jmalloc(slen+1,"text_field::format"),Format);
338  data=strcpy((char *)jmalloc(slen+1,"text_field::data"),Data);
339  cur=strlen(data);
340  while (cur && data[cur-1]==' ') cur--;
341  next=Next;
342}
343
344text_field::text_field(int X, int Y, int ID, char const *Prompt,
345                       char const *Format, double Data, ifield *Next)
346{
347  char num[20];
348  sprintf(num,"%g",Data); 
349  int slen=(strlen(Format)>strlen(num) ? strlen(Format) : strlen(num));
350  x=X; y=Y; id=ID;
351  prompt=strcpy((char *)jmalloc(strlen(Prompt)+1,"text_field::prompt"),Prompt);
352  format=strcpy((char *)jmalloc(slen+1,"text_field::format"),Format);
353  data=strcpy((char *)jmalloc(slen+1,"text_field::data"),num);
354  cur=strlen(num);
355  while (cur && data[cur-1]==' ') cur--;
356  next=Next;
357}
358
359
360void button::push()
361{ up=!up; }
362
363void button::handle_event(event &ev, image *screen, input_manager *im)
364{
365  if ((ev.type==EV_KEY && ev.key==13) || (ev.type==EV_MOUSE_BUTTON &&
366                                         ev.mouse_button))
367  {
368    int  x1,y1,x2,y2;
369    area(x1,y1,x2,y2);
370    up=!up;
371    draw_first(screen);
372    draw(act,screen);
373    wm->push_event(new event(id,(char *)this));
374  }
375}
376
377void button::draw(int active, image *screen)
378{
379  int x1,y1,x2,y2,color=(active ? wm->bright_color() : wm->medium_color()); 
380  area(x1,y1,x2,y2);
381  if (active!=act  && act_id!=-1 && active)
382    wm->push_event(new event(act_id,NULL));
383   
384  if (pressed)
385  {
386    if (up)
387    {
388      if (!active)
389        visual->put_image(screen,x,y);
390      else
391        pressed->put_image(screen,x,y);
392    } else act_pict->put_image(screen,x,y);
393  }
394  else
395  {
396    screen->rectangle(x1+2,y1+2,x2-2,y2-2,color);
397    act=active;
398  }
399}
400
401void button::draw_first(image *screen)
402{
403  if (pressed) 
404    draw(0,screen);
405  else
406  {
407
408    int x1,y1,x2,y2;
409    area(x1,y1,x2,y2);
410   
411
412    if (up)
413    {
414      screen->rectangle(x1,y1,x2,y2,wm->black());
415//      screen->widget_bar(,wm->bright_color(),wm->medium_color(),wm->dark_color());
416      screen->widget_bar(x1+1,y1+1,x2-1,y2-1,wm->bright_color(),wm->medium_color(),wm->dark_color());
417      if (text)
418      {
419        wm->font()->put_string(screen,x+4,y+5,text,wm->black());
420        wm->font()->put_string(screen,x+3,y+4,text);
421      }
422      else visual->put_image(screen,x+3,y+3,1);
423    } else
424    {
425      screen->line(x1,y1,x2,y1,wm->dark_color());
426      screen->line(x1,y1,x1,y2,wm->dark_color());
427      screen->line(x2,y1+1,x2,y2,wm->bright_color());
428      screen->line(x1+1,y2,x2,y2,wm->bright_color());
429      screen->bar(x1+1,y1+1,x2-1,y2-1,wm->medium_color());
430      if (visual)
431        visual->put_image(screen,x1+3,y1+3,1);
432      else
433      {
434        wm->font()->put_string(screen,x+4,y+5,text,wm->black());
435        wm->font()->put_string(screen,x+3,y+4,text);
436      }
437    } 
438  }
439}
440
441void text_field::draw_first(image *screen)
442{
443  wm->font()->put_string(screen,x,y+3,prompt);
444  screen->bar(xstart(),y,xend(),yend(),wm->dark_color());
445  wm->font()->put_string(screen,xstart()+1,y+3,data);
446}
447
448
449void text_field::draw_cur(int color, image *screen)
450{
451  screen->bar(xstart()+cur*wm->font()->width()+1,
452                      yend()-2,
453                      xstart()+(cur+1)*wm->font()->width(),
454                      yend()-1,color);
455}
456
457
458
459info_field::info_field(int X, int Y, int ID, char const *info, ifield *Next)
460{
461  x = X; y = Y; id = ID; next = Next;
462  text = strcpy((char *)jmalloc(strlen(info)+1,"info_field"), info);
463  w = -1;
464}
465
466
467void info_field::area(int &x1, int &y1, int &x2, int &y2)
468{
469  if (w==-1)     // if we haven't calculated this yet
470  {
471    int fw=wm->font()->width(),fh=wm->font()->height(),maxw=0;
472    char *info=text;
473    for (w=fw,h=fh+1;*info;info++)
474    {
475      if (w>maxw) maxw=w;
476      if (*info=='\n')
477      {
478        h+=fh+1;
479        w=1;
480      }
481      else w+=fw;     
482    }
483    w=maxw;
484  }     
485  x1=x;
486  y1=y;
487  x2=x+w;
488  y2=y+h;
489}
490
491void info_field::put_para(image *screen, char const *st, int dx, int dy,
492                          int xspace, int yspace, JCFont *font, int color)
493{
494  int ox=dx;
495  while (*st)
496  {
497    if (*st=='\n')
498    {
499      dx=ox;
500      dy+=yspace;
501    }
502    else
503    {
504      font->put_char(screen,dx,dy,*st,color);
505      dx+=xspace;
506    }
507    st++;
508  }
509}
510
511void info_field::draw_first(image *screen)
512{
513  put_para(screen,text,x+1,y+1,wm->font()->width(),wm->font()->height(),wm->font(),wm->black());
514  put_para(screen,text,x,y,wm->font()->width(),wm->font()->height(),wm->font(),wm->bright_color());
515}
516
517
518
519
Note: See TracBrowser for help on using the repository browser.