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
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
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
102void button_box::handle_event(event &ev, image *screen, input_manager *im)
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      {
112        b->area(x1,y1,x2,y2);
113        if (ev.mouse_move.x>=x1 && ev.mouse_move.x<=x2 &&
114            ev.mouse_move.y>=y1 && ev.mouse_move.y<=y2)
115        {
116          b->handle_event(ev,screen,im);
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();
133                  b2->draw_first(screen);
134                }
135            }
136            b->draw_first(screen);
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
156void button_box::arrange_left_right()
157{
158  button *b=buttons;
159  int x_on=x,x1,y1,x2,y2;
160  for (;b;b=(button *)b->next)
161  {
162    b->area(x1,y1,x2,y2);
163    b->x=x_on;
164    b->y=y;
165    x_on+=(x2-x1+1)+1;
166  } 
167}
168
169void button_box::arrange_up_down()
170
171  button *b=buttons;
172  int y_on=y,x1,y1,x2,y2;
173  for (;b;b=(button *)b->next)
174  {
175    b->area(x1,y1,x2,y2);
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
188void button::area(int &x1, int &y1, int &x2, int &y2)
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
211button::button(int X, int Y, int ID, char const *Text, ifield *Next)
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
238void text_field::change_data(char const *new_data, int new_cursor, // cursor==-1, does not change it.
239                             int active, image *screen)
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;
247  draw_first(screen);
248  draw(active,screen);
249}
250
251char *text_field::read()
252{
253  while (*data && data[strlen(data)-1]==' ') data[strlen(data)-1]=0;
254  return data;
255}
256
257void text_field::handle_event(event &ev, image *screen, input_manager *im)
258{
259  int xx;
260  if (ev.type==EV_KEY)
261  {
262    switch (ev.key)
263    {
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;
268      case JK_END : if (cur!=last_spot())
269                          { draw_cur(wm->dark_color(),screen); cur=last_spot();
270                            if (cur==(int)strlen(format)-1) cur--;
271                           draw_cur(wm->bright_color(),screen); } break;
272      case JK_HOME : if (cur)
273                          { draw_cur(wm->dark_color(),screen); cur=0;
274                           draw_cur(wm->bright_color(),screen); } break;
275      case JK_BACKSPACE : if (cur)
276         { draw_cur(wm->dark_color(),screen); cur--;
277           for (xx=cur;xx<(int)strlen(format)-1;xx++)
278             data[xx]=data[xx+1];
279           data[strlen(format)-1]=' ';
280           draw_text(screen);
281           draw_cur(wm->bright_color(),screen);
282           wm->push_event(new event(id,(char *)this));
283         } break;
284      default : if (ev.key>=' ' && ev.key<='~')
285         {
286           draw_cur(wm->dark_color(),screen);
287           for (xx=strlen(format)-1;xx>cur && xx>0;xx--)
288             data[xx]=data[xx-1];
289           data[cur]=ev.key;
290           if (cur<(int)strlen(format)-1)
291             cur++;
292           data[strlen(format)]=0;
293           draw_text(screen);
294           draw_cur(wm->bright_color(),screen);
295           wm->push_event(new event(id,(char *)this));
296         } break;
297    }
298  }
299}
300
301void text_field::draw(int active, image *screen)
302{
303  if (active)
304  {
305    screen->rectangle(xstart(),y,xend(),yend(),wm->bright_color());
306    draw_cur(wm->bright_color(),screen);
307  }
308  else
309  {
310    screen->rectangle(xstart(),y,xend(),yend(),wm->dark_color());
311    draw_cur(wm->dark_color(),screen);
312  }
313}
314
315void text_field::area(int &x1, int &y1, int &x2, int &y2)
316{
317  x1=x; y1=y;
318  x2=xend();
319  y2=yend();
320}
321
322text_field::text_field(int X, int Y, int ID, char const *Prompt,
323                       char const *Format, char const *Data, ifield *Next)
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
336text_field::text_field(int X, int Y, int ID, char const *Prompt,
337                       char const *Format, double Data, ifield *Next)
338{
339  char num[20];
340  sprintf(num,"%g",Data); 
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
355void button::handle_event(event &ev, image *screen, input_manager *im)
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;
361    area(x1,y1,x2,y2);
362    up=!up;
363    draw_first(screen);
364    draw(act,screen);
365    wm->push_event(new event(id,(char *)this));
366  }
367}
368
369void button::draw(int active, image *screen)
370{
371  int x1,y1,x2,y2,color=(active ? wm->bright_color() : wm->medium_color()); 
372  area(x1,y1,x2,y2);
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
393void button::draw_first(image *screen)
394{
395  if (pressed) 
396    draw(0,screen);
397  else
398  {
399
400    int x1,y1,x2,y2;
401    area(x1,y1,x2,y2);
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
433void text_field::draw_first(image *screen)
434{
435  wm->font()->put_string(screen,x,y+3,prompt);
436  screen->bar(xstart(),y,xend(),yend(),wm->dark_color());
437  wm->font()->put_string(screen,xstart()+1,y+3,data);
438}
439
440
441void text_field::draw_cur(int color, image *screen)
442{
443  screen->bar(xstart()+cur*wm->font()->width()+1,
444                      yend()-2,
445                      xstart()+(cur+1)*wm->font()->width(),
446                      yend()-1,color);
447}
448
449
450
451info_field::info_field(int X, int Y, int ID, char const *info, ifield *Next)
452{
453  x = X; y = Y; id = ID; next = Next;
454  text = strcpy((char *)jmalloc(strlen(info)+1,"info_field"), info);
455  w = -1;
456}
457
458
459void info_field::area(int &x1, int &y1, int &x2, int &y2)
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
483void info_field::put_para(image *screen, char const *st, int dx, int dy,
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
503void info_field::draw_first(image *screen)
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.