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

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