]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/mothra/libpanel/slider.c
exec(2): fix prototypes
[plan9front.git] / sys / src / cmd / mothra / libpanel / slider.c
1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4 #include <event.h>
5 #include <panel.h>
6 #include "pldefs.h"
7 typedef struct Slider Slider;
8 struct Slider{
9         int dir;                        /* HORIZ or VERT */
10         int val;                        /* setting, in screen coordinates */
11         Point minsize;
12         void (*hit)(Panel *, int, int, int);    /* call back to user when slider changes */
13         int buttons;
14 };
15 void pl_drawslider(Panel *p){
16         Rectangle r;
17         Slider *sp;
18         sp=p->data;
19         r=pl_box(p->b, p->r, UP);
20         switch(sp->dir){
21         case HORIZ: pl_sliderupd(p->b, r, sp->dir, 0, sp->val); break;
22         case VERT:  pl_sliderupd(p->b, r, sp->dir, r.max.y-sp->val, r.max.y); break;
23         }
24 }
25 int pl_hitslider(Panel *p, Mouse *m){
26         int oldstate, oldval, len;
27         Point ul, size;
28         Slider *sp;
29         sp=p->data;
30         ul=p->r.min;
31         size=subpt(p->r.max, p->r.min);
32         pl_interior(p->state, &ul, &size);
33         oldstate=p->state;
34         oldval=sp->val;
35         SET(len);
36         if(m->buttons&OUT)
37                 p->state=UP;
38         else if(m->buttons&7){
39                 p->state=DOWN;
40                 sp->buttons=m->buttons;
41                 if(sp->dir==HORIZ){
42                         sp->val=m->xy.x-ul.x;
43                         len=size.x;
44                 }
45                 else{
46                         sp->val=ul.y+size.y-m->xy.y;
47                         len=size.y;
48                 }
49                 if(sp->val<0) sp->val=0;
50                 else if(sp->val>len) sp->val=len;
51         }
52         else    /* mouse inside, but no buttons down */
53                 p->state=UP;
54         if(oldval!=sp->val || oldstate!=p->state) pldraw(p, p->b);
55         if(oldval!=sp->val && sp->hit) sp->hit(p, sp->buttons, sp->val, len);
56         return 0;
57 }
58 void pl_typeslider(Panel *p, Rune c){
59         USED(p, c);
60 }
61 Point pl_getsizeslider(Panel *p, Point children){
62         USED(children);
63         return pl_boxsize(((Slider *)p->data)->minsize, p->state);
64 }
65 void pl_childspaceslider(Panel *g, Point *ul, Point *size){
66         USED(g, ul, size);
67 }
68 void plinitslider(Panel *v, int flags, Point size, void (*hit)(Panel *, int, int, int)){
69         Slider *sp;
70         sp=v->data;
71         v->r=Rect(0,0,size.x,size.y);
72         v->flags=flags|LEAF;
73         v->state=UP;
74         v->draw=pl_drawslider;
75         v->hit=pl_hitslider;
76         v->type=pl_typeslider;
77         v->getsize=pl_getsizeslider;
78         v->childspace=pl_childspaceslider;
79         sp->minsize=size;
80         sp->dir=size.x>size.y?HORIZ:VERT;
81         sp->hit=hit;
82         v->kind="slider";
83 }
84 Panel *plslider(Panel *parent, int flags, Point size, void (*hit)(Panel *, int, int, int)){
85         Panel *p;
86         p=pl_newpanel(parent, sizeof(Slider));
87         plinitslider(p, flags, size, hit);
88         return p;
89 }
90 void plsetslider(Panel *p, int value, int range){
91         Slider *sp;
92         sp=p->data;
93         if(value<0) value=0;
94         else if(value>range) value=range;
95         if(sp->dir==HORIZ) sp->val=value*(p->r.max.x-p->r.min.x)/range;
96         else sp->val=value*(p->r.max.y-p->r.min.y)/range;
97 }