source: abuse/tags/pd/macabuse/imlib/input.c @ 49

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