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

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