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

Last change on this file since 481 was 481, checked in by Sam Hocevar, 12 years ago

Fuck the history, I'm renaming all .hpp files to .h for my own sanity.

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