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

Last change on this file since 56 was 56, checked in by Sam Hocevar, 15 years ago
  • Add licensing terms to most C / C++ files (Ref #5).
File size: 12.3 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, window_manager *wm)
63{
64  button *b=buttons;
65  if (!b) return ;
66  else
67  {
68    b->area(x1,y1,x2,y2,wm);
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,wm);
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, window_manager *wm)
82{
83  for (button *b=buttons;b;b=(button *)b->next)
84    b->draw_first(screen,wm);
85}
86
87void button_box::draw(int active, image *screen, window_manager *wm)
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, window_manager *wm, 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,wm);
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,wm,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,wm);
134                }
135            }
136            b->draw_first(screen,wm);
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(window_manager *wm)
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,wm);
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(window_manager *wm)
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,wm);
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, window_manager *wm)
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, window_manager *wm)
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,wm);
248  draw(active,screen,wm);
249}
250
251char *text_field::read()
252{
253  while (*data && data[strlen(data)-1]==' ') data[strlen(data)-1]=0;
254  return data;
255}
256
257#ifdef __MWERKS__
258#pragma global_optimizer on
259#endif
260
261void text_field::handle_event(event &ev, image *screen, window_manager *wm, input_manager *im)
262{
263  int xx;
264  if (ev.type==EV_KEY)
265  {
266    switch (ev.key)
267    {
268      case JK_LEFT : if (cur) { draw_cur(wm->dark_color(),screen,wm); cur--;
269                           draw_cur(wm->bright_color(),screen,wm); } break;
270      case JK_RIGHT : if (cur<(int)strlen(format)-1) { draw_cur(wm->dark_color(),screen,wm); cur++;
271                           draw_cur(wm->bright_color(),screen,wm); } break;
272      case JK_END : if (cur!=last_spot())
273                          { draw_cur(wm->dark_color(),screen,wm); cur=last_spot();
274                            if (cur==(int)strlen(format)-1) cur--;
275                           draw_cur(wm->bright_color(),screen,wm); } break;
276      case JK_HOME : if (cur)
277                          { draw_cur(wm->dark_color(),screen,wm); cur=0;
278                           draw_cur(wm->bright_color(),screen,wm); } break;
279      case JK_BACKSPACE : if (cur)
280         { draw_cur(wm->dark_color(),screen,wm); cur--;
281           for (xx=cur;xx<(int)strlen(format)-1;xx++)
282             data[xx]=data[xx+1];
283           data[strlen(format)-1]=' ';
284           draw_text(screen,wm);
285           draw_cur(wm->bright_color(),screen,wm);
286           wm->push_event(new event(id,(char *)this));
287         } break;
288      default : if (ev.key>=' ' && ev.key<='~')
289         {
290           draw_cur(wm->dark_color(),screen,wm);
291           for (xx=strlen(format)-1;xx>cur && xx>0;xx--)
292             data[xx]=data[xx-1];
293           data[cur]=ev.key;
294           if (cur<(int)strlen(format)-1)
295             cur++;
296           data[strlen(format)]=0;
297           draw_text(screen,wm);
298           draw_cur(wm->bright_color(),screen,wm);
299           wm->push_event(new event(id,(char *)this));
300         } break;
301    }
302  }
303}
304
305#ifdef __MWERKS__
306#pragma global_optimizer reset
307#endif
308
309void text_field::draw(int active, image *screen, window_manager *wm)
310{
311  if (active)
312  {
313    screen->rectangle(xstart(wm),y,xend(wm),yend(wm),wm->bright_color());
314    draw_cur(wm->bright_color(),screen,wm);
315  }
316  else
317  {
318    screen->rectangle(xstart(wm),y,xend(wm),yend(wm),wm->dark_color());
319    draw_cur(wm->dark_color(),screen,wm);
320  }
321}
322
323void text_field::area(int &x1, int &y1, int &x2, int &y2, window_manager *wm)
324{
325  x1=x; y1=y;
326  x2=xend(wm);
327  y2=yend(wm);
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, window_manager *wm, 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,wm);
370    up=!up;
371    draw_first(screen,wm);
372    draw(act,screen,wm);
373    wm->push_event(new event(id,(char *)this));
374  }
375}
376
377void button::draw(int active, image *screen, window_manager *wm)
378{
379  int x1,y1,x2,y2,color=(active ? wm->bright_color() : wm->medium_color()); 
380  area(x1,y1,x2,y2,wm);
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, window_manager *wm)
402{
403  if (pressed) 
404    draw(0,screen,wm);
405  else
406  {
407
408    int x1,y1,x2,y2;
409    area(x1,y1,x2,y2,wm);
410   
411
412    if (up)
413    {
414      screen->rectangle(x1,y1,x2,y2,wm->black());
415//      screen->wiget_bar(,wm->bright_color(),wm->medium_color(),wm->dark_color());
416      screen->wiget_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, window_manager *wm)
442{
443  wm->font()->put_string(screen,x,y+3,prompt);
444  screen->bar(xstart(wm),y,xend(wm),yend(wm),wm->dark_color());
445  wm->font()->put_string(screen,xstart(wm)+1,y+3,data);
446}
447
448
449void text_field::draw_cur(int color, image *screen, window_manager *wm)
450{
451  screen->bar(xstart(wm)+cur*wm->font()->width()+1,
452                      yend(wm)-2,
453                      xstart(wm)+(cur+1)*wm->font()->width(),
454                      yend(wm)-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, window_manager *wm)
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, window_manager *wm)
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.