source: abuse/branches/pd/imlib/input.c @ 597

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