1 /* (C) Guenter Geiger <geiger@xdv.org> */
4 #include "../src/m_pd.h"
7 /* ------------------------ gcanvas ----------------------------- */
10 #define BACKGROUNDCOLOR "grey"
12 #define DEFAULTSIZE 80
14 static t_class
*gcanvas_class
;
16 typedef struct _gcanvas
31 static void rectangle(void* cv
,void* o
,char c
,int x
, int y
,int w
,int h
,char* color
) {
42 sys_vgui(".x%x.c create rectangle \
43 %d %d %d %d -tags %x%c -fill %s\n",cv
,x
,y
,x
+w
,y
+h
,o
,c
,color
);
47 static void move_object(void* cv
,void* o
,char c
,int x
, int y
,int w
,int h
) {
57 sys_vgui(".x%x.c coords %x%c %d %d %d %d\n",
62 static void color_object(void* cv
,void* o
,char c
,char* color
) {
69 sys_vgui(".x%x.c itemconfigure %x%c -fill %s\n", cv
,
74 static void delete_object(void* cv
,void* o
,char c
) {
80 sys_vgui(".x%x.c delete %x%c\n",
85 static void line(void* cv
,void* o
,char c
,int x
,int y
,int w
,int h
,char* color
) {
96 sys_vgui(".x%x.c create line \
97 %d %d %d %d -tags %x%c -fill %s\n",cv
,x
,y
,x
+w
,y
+h
,o
,c
,color
);
102 /* widget helper functions */
104 void gcanvas_drawme(t_gcanvas
*x
, t_glist
*glist
, int firsttime
)
108 rectangle(glist_getcanvas(glist
),x
,'a',
109 x
->x_obj
.te_xpix
, x
->x_obj
.te_ypix
,
110 x
->x_width
, x
->x_height
,BACKGROUNDCOLOR
);
111 for (i
=1;i
<x
->x_xgrid
;i
++)
112 line(glist_getcanvas(glist
),x
,'b'+ i
,
113 x
->x_obj
.te_xpix
+ x
->x_width
*i
/x
->x_xgrid
,
115 0, x
->x_height
,"red");
116 for (i
=1;i
<x
->x_ygrid
;i
++)
117 line(glist_getcanvas(glist
),x
,'B'+ i
,
119 x
->x_obj
.te_ypix
+ x
->x_height
*i
/x
->x_ygrid
,
120 x
->x_width
, 0,"blue");
124 glist_getcanvas(glist
),x
,'a',
125 x
->x_obj
.te_xpix
, x
->x_obj
.te_ypix
,
126 x
->x_width
, x
->x_height
);
127 for (i
=1;i
<x
->x_xgrid
;i
++)
128 move_object(glist_getcanvas(glist
),x
,'b'+ i
,
129 x
->x_obj
.te_xpix
+ x
->x_width
*i
/x
->x_xgrid
,
132 for (i
=1;i
<x
->x_ygrid
;i
++)
133 move_object(glist_getcanvas(glist
),x
,'B'+ i
,
135 x
->x_obj
.te_ypix
+ x
->x_height
*i
/x
->x_ygrid
,
143 nplus
= (n
== 1 ? 1 : n
-1);
144 for (i
= 0; i
< n
; i
++)
147 int onset
= x
->x_obj
.te_xpix
+ (x
->x_width
- IOWIDTH
) * i
/ nplus
;
149 sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xo%d\n",
150 glist_getcanvas(glist
),
151 onset
, x
->x_obj
.te_ypix
+ x
->x_height
- 1,
152 onset
+ IOWIDTH
, x
->x_obj
.te_ypix
+ x
->x_height
,
155 sys_vgui(".x%x.c coords %xo%d %d %d %d %d\n",
156 glist_getcanvas(glist
), x
, i
,
157 onset
, x
->x_obj
.te_ypix
+ x
->x_height
- 1,
158 onset
+ IOWIDTH
, x
->x_obj
.te_ypix
+ x
->x_height
);
163 nplus
= (n
== 1 ? 1 : n
-1);
164 for (i
= 0; i
< n
; i
++)
167 int onset
= x
->x_obj
.te_xpix
+ (x
->x_width
- IOWIDTH
) * i
/ nplus
;
169 sys_vgui(".x%x.c create rectangle %d %d %d %d -tags %xi%d\n",
170 glist_getcanvas(glist
),
171 onset
, x
->x_obj
.te_ypix
,
172 onset
+ IOWIDTH
, x
->x_obj
.te_ypix
+ 1,
175 sys_vgui(".x%x.c coords %xi%d %d %d %d %d\n",
176 glist_getcanvas(glist
), x
, i
,
177 onset
, x
->x_obj
.te_ypix
,
178 onset
+ IOWIDTH
, x
->x_obj
.te_ypix
+ 1);
188 void gcanvas_erase(t_gcanvas
* x
,t_glist
* glist
)
191 delete_object(glist_getcanvas(glist
),x
,'a');
192 for (i
=1;i
<x
->x_xgrid
;i
++)
193 delete_object(glist_getcanvas(glist
),x
,'b'+ i
);
194 for (i
=1;i
<x
->x_ygrid
;i
++)
195 delete_object(glist_getcanvas(glist
),x
,'B'+ i
);
200 sys_vgui(".x%x.c delete %xo%d\n",glist_getcanvas(glist
),x
,n
);
207 /* ------------------------ gcanvas widgetbehaviour----------------------------- */
210 static void gcanvas_getrect(t_gobj
*z
, t_glist
*owner
,
211 int *xp1
, int *yp1
, int *xp2
, int *yp2
)
217 t_gcanvas
* s
= (t_gcanvas
*)z
;
221 height
= s
->x_height
;
222 *xp1
= s
->x_obj
.te_xpix
;
223 *yp1
= s
->x_obj
.te_ypix
;
224 *xp2
= s
->x_obj
.te_xpix
+ width
;
225 *yp2
= s
->x_obj
.te_ypix
+ height
;
228 static void gcanvas_displace(t_gobj
*z
, t_glist
*glist
,
231 t_gcanvas
*x
= (t_gcanvas
*)z
;
232 x
->x_obj
.te_xpix
+= dx
;
233 x
->x_obj
.te_ypix
+= dy
;
234 gcanvas_drawme(x
, glist
, 0);
235 canvas_fixlinesfor(glist_getcanvas(glist
),(t_text
*) x
);
238 static void gcanvas_select(t_gobj
*z
, t_glist
*glist
, int state
)
240 t_gcanvas
*x
= (t_gcanvas
*)z
;
241 color_object(glist
,x
,'a',state
? "blue" : BACKGROUNDCOLOR
);
245 static void gcanvas_activate(t_gobj
*z
, t_glist
*glist
, int state
)
252 /* t_text *x = (t_text *)z;
253 t_rtext *y = glist_findrtext(glist, x);
254 if (z->g_pd != gatom_class) rtext_activate(y, state);*/
257 static void gcanvas_delete(t_gobj
*z
, t_glist
*glist
)
259 t_text
*x
= (t_text
*)z
;
260 canvas_deletelinesfor(glist_getcanvas(glist
), x
);
264 static void gcanvas_vis(t_gobj
*z
, t_glist
*glist
, int vis
)
266 t_gcanvas
* s
= (t_gcanvas
*)z
;
268 gcanvas_drawme(s
, glist
, 1);
270 gcanvas_erase(s
,glist
);
273 /* can we use the normal text save function ?? */
275 static void gcanvas_save(t_gobj
*z
, t_binbuf
*b
)
277 t_gcanvas
*x
= (t_gcanvas
*)z
;
278 binbuf_addv(b
, "ssiisiiii", gensym("#X"),gensym("obj"),
279 (t_int
)x
->x_obj
.te_xpix
, (t_int
)x
->x_obj
.te_ypix
,
280 gensym("gcanvas"),x
->x_width
,x
->x_height
,
287 t_widgetbehavior gcanvas_widgetbehavior
;
289 static void gcanvas_motion(t_gcanvas
*x
, t_floatarg dx
, t_floatarg dy
)
293 outlet_float(x
->out2
,x
->y
);
294 outlet_float(x
->x_obj
.ob_outlet
,x
->x
);
297 void gcanvas_key(t_gcanvas
*x
, t_floatarg f
)
307 static void gcanvas_click(t_gcanvas
*x
,
308 t_floatarg xpos
, t_floatarg ypos
, t_floatarg shift
, t_floatarg ctrl
,
309 t_floatarg doit
,int up
)
317 glist_grab(x
->x_glist
, &x
->x_obj
.te_g
, (t_glistmotionfn
) gcanvas_motion
,
318 (t_glistkeyfn
) NULL
, xpos
, ypos
);
320 x
->x
= xpos
- x
->x_obj
.te_xpix
;
321 x
->y
= ypos
- x
->x_obj
.te_ypix
;
322 outlet_float(x
->out2
,x
->y
);
323 outlet_float(x
->x_obj
.ob_outlet
,x
->x
);
324 outlet_float(x
->out3
,0);
327 static int gcanvas_newclick(t_gobj
*z
, struct _glist
*glist
,
328 int xpix
, int ypix
, int shift
, int alt
, int dbl
, int doit
)
334 gcanvas_click((t_gcanvas
*)z
, (t_floatarg
)xpix
, (t_floatarg
)ypix
,
335 (t_floatarg
)shift
, 0, (t_floatarg
)alt
,dbl
);
337 if (dbl
) outlet_float(((t_gcanvas
*)z
)->out3
,1);
341 void gcanvas_size(t_gcanvas
* x
,t_floatarg w
,t_floatarg h
) {
344 gcanvas_drawme(x
, x
->x_glist
, 0);
347 static void gcanvas_setwidget(void)
349 gcanvas_widgetbehavior
.w_getrectfn
= gcanvas_getrect
;
350 gcanvas_widgetbehavior
.w_displacefn
= gcanvas_displace
;
351 gcanvas_widgetbehavior
.w_selectfn
= gcanvas_select
;
352 gcanvas_widgetbehavior
.w_activatefn
= gcanvas_activate
;
353 gcanvas_widgetbehavior
.w_deletefn
= gcanvas_delete
;
354 gcanvas_widgetbehavior
.w_visfn
= gcanvas_vis
;
355 gcanvas_widgetbehavior
.w_clickfn
= gcanvas_newclick
;
356 class_setsavefn(gcanvas_class
,gcanvas_save
);
360 static void *gcanvas_new(t_symbol
* s
,t_int ac
,t_atom
* at
)
365 t_gcanvas
*x
= (t_gcanvas
*)pd_new(gcanvas_class
);
367 x
->x_glist
= (t_glist
*) canvas_getcurrent();
370 /* Fetch the width */
372 x
->x_width
= DEFAULTSIZE
;
374 if (at
->a_type
!= A_FLOAT
)
375 error("gcanvas: wrong argument type");
377 x
->x_width
= atom_getfloat(at
++);
379 if (x
->x_width
< 0 || x
->x_width
> 2000) {
380 error("gcanvas: unallowed width %f",x
->x_width
);
381 x
->x_width
= DEFAULTSIZE
;
385 /* Fetch the height */
387 x
->x_height
= DEFAULTSIZE
;
389 if (at
->a_type
!= A_FLOAT
)
390 error("gcanvas: wrong argument type");
392 x
->x_height
= atom_getfloat(at
++);
394 if (x
->x_height
< 0 || x
->x_height
> 2000) {
395 error("gcanvas: unallowed height %f",x
->x_height
);
396 x
->x_width
= DEFAULTSIZE
;
400 /* Fetch the xgrid */
404 if (at
->a_type
!= A_FLOAT
)
405 error("gcanvas: wrong argument type");
407 x
->x_xgrid
= atom_getfloat(at
++);
409 if (x
->x_xgrid
< 0 || x
->x_xgrid
> x
->x_width
/2) {
410 error("gcanvas: unallowed xgrid %f",x
->x_xgrid
);
415 /* Fetch the ygrid */
419 if (at
->a_type
!= A_FLOAT
)
420 error("gcanvas: wrong argument type");
422 x
->x_ygrid
= atom_getfloat(at
++);
424 if (x
->x_ygrid
< 0 || x
->x_ygrid
> x
->x_height
/2) {
425 error("gcanvas: unallowed xgrid %f",x
->x_ygrid
);
430 outlet_new(&x
->x_obj
, &s_float
);
431 x
->out2
= outlet_new(&x
->x_obj
, &s_float
);
432 x
->out3
= outlet_new(&x
->x_obj
, &s_float
);
438 void gcanvas_setup(void)
440 gcanvas_class
= class_new(gensym("gcanvas"), (t_newmethod
)gcanvas_new
, 0,
441 sizeof(t_gcanvas
),0, A_GIMME
,0);
443 class_addmethod(gcanvas_class
, (t_method
)gcanvas_click
, gensym("click"),
444 A_FLOAT
, A_FLOAT
, A_FLOAT
, A_FLOAT
, A_FLOAT
, 0);
445 class_addmethod(gcanvas_class
, (t_method
)gcanvas_size
, gensym("size"),
446 A_FLOAT
, A_FLOAT
, 0);
449 class_setwidget(gcanvas_class
,&gcanvas_widgetbehavior
);