Jamoma API  0.6.0.a19
PureData/source/j.remote/j.remote.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup implementationPdExternals
4  *
5  * @brief j.remote : Bind to a parameter value
6  *
7  * @details Useful when designing views and more.
8  *
9  * @authors Théo de la Hogue, Trond Lossius, Antoine Villeret
10  *
11  * @copyright © 2010 by Théo de la Hogue @n
12  * Copyright © 2015, Antoine Villeret@n
13  * This code is licensed under the terms of the "New BSD License" @n
14  * http://creativecommons.org/licenses/BSD/
15  */
16 
17 
19 
20 // those stuffes are needed for handling patchers without using the pcontrol object
21 // #include "jpatcher_api.h"
22 
23 typedef struct dll {
24  t_object d_ob;
25  struct dll *d_next;
26  struct dll *d_prev;
27  void *d_x1;
28 } t_dll;
29 /*
30 typedef struct outlet {
31  struct tinyobject o_ob;
32  struct dll *o_dll;
33 } t_outlet;
34 */
35 
36 // This is used to store extra data
37 typedef struct extra {
38  TTAddress name; ///< the name to use for subscription
39  // TTPtr ui_qelem; ///< to output "qlim'd" data for ui object
40  t_clock* ui_clock;
41  t_object* connected; // our ui object
42  long x; // our ui object x presentation
43  long y; // our ui object y presentation
44  long w; // our ui object width presentation
45  long h; // our ui object heigth presentation
46  t_object* label; // label to display selection state
47  t_atom* color0; // label color for selection state == 0
48  t_atom* color1; // label color for selection state == 1
49  TTBoolean setting; // a flag to know if the remote is updated by a set message
50 } t_extra;
51 #define EXTRA ((t_extra*)x->extra)
52 
53 #define set_out 0
54 #define value_out 1
55 #define attach_out 2
56 #define dump_out 3
57 
58 // Definitions
59 void WrapTTViewerClass(WrappedClassPtr c);
60 void WrappedViewerClass_new(TTPtr self, long argc, t_atom *argv);
61 void WrappedViewerClass_free(TTPtr self);
62 void WrappedViewerClass_anything(TTPtr self, t_symbol *msg, long argc, t_atom *argv);
63 
64 void remote_assist(TTPtr self, void *b, long msg, long arg, char *dst);
65 
66 void remote_return_value(TTPtr self, t_symbol *msg, long argc, t_atom *argv);
67 void remote_return_model_address(TTPtr self, t_symbol *msg, long argc, t_atom *argv);
68 void remote_return_description(TTPtr self, t_symbol *msg, long argc, t_atom *argv);
69 
70 void remote_bang(TTPtr self);
71 void remote_float(TTPtr self, t_float value);
72 TTErr remote_list(TTPtr self, t_symbol *msg, long argc, t_atom *argv);
73 
74 void remote_set(TTPtr self, t_symbol *msg, long argc, t_atom *argv);
75 
76 void remote_address(TTPtr self, t_symbol *address);
77 void remote_loadbang(TTPtr self);
78 
79 void remote_attach(TTPtr self, int attach_output_id);
80 void remote_mousemove(TTPtr self, t_object *patcherview, t_pt pt, long modifiers);
81 void remote_mouseleave(TTPtr self, t_object *patcherview, t_pt pt, long modifiers);
82 void remote_mousedown(TTPtr self, t_object *patcherview, t_pt pt, long modifiers);
83 
84 void remote_subscribe(TTPtr self);
85 
86 void remote_ui_queuefn(TTPtr self);
87 
88 extern "C" void JAMOMA_EXPORT_MAXOBJ setup_j0x2eremote(void)
89 {
90  ModularSpec *spec = new ModularSpec;
91  spec->_wrap = &WrapTTViewerClass;
92  spec->_new = &WrappedViewerClass_new;
93  spec->_free = &WrappedViewerClass_free;
94  spec->_any = &WrappedViewerClass_anything;
95  spec->_notify = NULL;
96 
97  return (void)wrapTTModularClassAsPdClass(kTTSym_Viewer, "j.remote", NULL, spec);
98 }
99 
100 void WrapTTViewerClass(WrappedClassPtr c)
101 {
102  eclass_addmethod(c->pdClass, (method)remote_assist, "assist", A_CANT, 0L);
103 
104  // eclass_addmethod(c->pdClass, (method)remote_mousemove, "mousemove", A_CANT, 0);
105  // eclass_addmethod(c->pdClass, (method)remote_mouseleave, "mouseleave", A_CANT, 0);
106  // eclass_addmethod(c->pdClass, (method)remote_mousedown, "mousedown", A_CANT, 0);
107 
108  eclass_addmethod(c->pdClass, (method)remote_return_value, "return_value", A_CANT, 0);
109  eclass_addmethod(c->pdClass, (method)remote_return_model_address, "return_model_address", A_CANT, 0);
110  eclass_addmethod(c->pdClass, (method)remote_return_description, "return_description", A_CANT, 0);
111 
112  eclass_addmethod(c->pdClass, (method)remote_bang, "bang", A_NULL, 0L);
113  eclass_addmethod(c->pdClass, (method)remote_float, "float", A_FLOAT, 0L);
114  eclass_addmethod(c->pdClass, (method)remote_list, "list", A_GIMME, 0L);
115 
116  eclass_addmethod(c->pdClass, (method)remote_set, "set", A_GIMME, 0L);
117 
118  eclass_addmethod(c->pdClass, (method)remote_address, "address", A_SYM, 0);
119  eclass_addmethod(c->pdClass, (method)remote_loadbang, "loadbang", A_NULL, 0);
120 }
121 
122 void WrappedViewerClass_new(TTPtr self, long argc, t_atom *argv)
123 {
125  t_symbol *address;
126  long attrstart = attr_args_offset(argc, argv); // support normal arguments
127 
128  // read the address to bind from the first argument
129  if (attrstart > 0 && argv)
130  address = atom_getsym(argv);
131  else
132  address = _sym_nothing;
133 
134  // x->address = TTAddress(jamoma_parse_dieze((t_object*)x, address)->s_name);
135  x->address = TTAddress(address->s_name);
136  x->index = 0; // the index member is usefull to count how many time the external tries to bind
137 
138  // Prepare extra data
139  x->extra = (t_extra*)malloc(sizeof(t_extra));
140 
141  // read the name to use for subscription from the first argument
142  if (attrstart == 2 && argv)
143  EXTRA->name = TTAddress(atom_getsym(argv+1)->s_name);
144  else
145  EXTRA->name = kTTAdrsEmpty;
146 
147  EXTRA->connected = NULL;
148  EXTRA->label = NULL;
149 
150  EXTRA->color0 = (t_atom*)sysmem_newptr(sizeof(t_atom) * 4);
151  atom_setfloat(EXTRA->color0, 0);
152  atom_setfloat(EXTRA->color0+1, 0.);
153  atom_setfloat(EXTRA->color0+2, 0.);
154  atom_setfloat(EXTRA->color0+3, 1.);
155 
156  EXTRA->color1 = (t_atom*)sysmem_newptr(sizeof(t_atom) * 4);
157  atom_setfloat(EXTRA->color1, 0.62);
158  atom_setfloat(EXTRA->color1+1, 0.);
159  atom_setfloat(EXTRA->color1+2, 0.36);
160  atom_setfloat(EXTRA->color1+3, 0.70);
161 
162  EXTRA->setting = NO;
163 
164  jamoma_viewer_create((t_object*)x, x->wrappedObject);
165 
166  // Make two outlets
167  x->outlets = (TTHandle)sysmem_newptr(sizeof(TTPtr) * 3);
168  x->outlets[set_out] = outlet_new((t_object*)x, NULL); // anything outlet to output qlim data
169  x->outlets[value_out] = outlet_new((t_object*)x, NULL); // anything outlet to output data
170  x->outlets[attach_out] = outlet_new((t_object*)x, NULL); // anything outlet to select ui
171 
172  // Make qelem object
173  //EXTRA->ui_qelem = qelem_new(x, (method)remote_ui_queuefn);
174  EXTRA->ui_clock = clock_new(x,(t_method)remote_ui_queuefn);
175 
176  // clear support for qelem value
177  x->argc = 0;
178  x->argv = NULL;
179 
180  // handle attribute args
181  attr_args_process(x, argc, argv);
182 
183  // The following must be deferred because we have to interrogate our box,
184  // and our box is not yet valid until we have finished instantiating the object.
185  // Trying to use a loadbang method instead is also not fully successful (as of Max 5.0.6)
186 // defer_low((t_object*)x, (method)remote_subscribe, NULL, 0, 0);
187  // remote_subscribe(x);
188 }
189 
190 // Method for Assistance Messages
191 void remote_assist(TTPtr self, void *b, long msg, long arg, char *dst)
192 {
193  if (msg==1) // Inlet
194  strcpy(dst, "input");
195  else { // Outlets
196  switch(arg) {
197  case set_out:
198  strcpy(dst, "set: connect to ui object");
199  break;
200  case value_out:
201  strcpy(dst, "value");
202  break;
203  case attach_out:
204  strcpy(dst, "attach: connect this outlet to ui object if the set or the value outlets are not directly connected to it");
205  break;
206  case dump_out:
207  strcpy(dst, "dumpout");
208  break;
209  }
210  }
211 }
212 
213 void WrappedViewerClass_free(TTPtr self)
214 {
216 
217  clock_unset(EXTRA->ui_clock);
218  clock_free(EXTRA->ui_clock);
219 
220  x->wrappedObject.set(kTTSym_address, kTTAdrsEmpty);
221 
222  free(EXTRA);
223 }
224 
225 void remote_subscribe(TTPtr self)
226 {
228  TTValue v;
229  t_atom a[1];
230  TTAddress contextAddress = kTTAdrsEmpty;
231  TTAddress absoluteAddress, returnedAddress;
232  TTNodePtr returnedNode = NULL;
233  TTNodePtr returnedContextNode = NULL;
234  TTObject anObject, empty;
235  TTErr err;
236 
237  if (x->address == kTTAdrsEmpty)
238  return;
239 
240  // attach the j.remote to connected ui object
241  // TODO : this should be done when the an object is connected to one of the j.remote outlet
242  // (but this means we need to unsubscribe then subscribe with the new name)
243  remote_attach(self, set_out);
244 
245  // for absolute address we only bind the given address but we don't subscribe the remote into the namespace
246  if (x->address.getType() == kAddressAbsolute) {
247 
248  x->wrappedObject.set(kTTSym_address, x->address);
249 
250  // observe :description attribute
251  if (x->internals->lookup(TTSymbol(":description"), v))
252 
253  makeInternals_receiver(x, absoluteAddress, TTSymbol(":description"), gensym("return_description"), anObject, YES);
254 
255  else {
256  anObject = v[0];
257  anObject.set(kTTSym_address, absoluteAddress.appendAttribute(kTTSym_description));
258  }
259 
260  return;
261  }
262 
263  // for relative address
264  jamoma_patcher_get_info(((t_eobj*)x)->o_canvas, &x->patcherPtr, x->patcherContext, x->patcherClass, x->patcherName);
265 
266  // if no name is provided or can be edited in remote_attach() : use the address
267  if (EXTRA->name == kTTAdrsEmpty)
268  EXTRA->name = x->address;
269 
270  // if there is a context
271  if (x->patcherContext != kTTSymEmpty) {
272 
273  // Do we subscribe the Viewer ?
274  // View patcher case :
275  if (x->patcherContext == kTTSym_view) {
276 
277  // if the address refer to the j.model (only :attributeName) don't subscribe the Viewer
278  if (x->address.getParent() == NO_PARENT &&
279  x->address.getName() == NO_NAME &&
280  x->address.getInstance() == NO_INSTANCE &&
281  x->address.getAttribute() != NO_ATTRIBUTE)
282  err = jamoma_subscriber_create((t_eobj*)x, empty, x->address, x->subscriberObject, returnedAddress, &returnedNode, &returnedContextNode);
283 
284  // if the address refer to the "model" node don't subscribe the Viewer (to not have model.1)
285  else if (x->address.getName() == TTSymbol("model"))
286  err = jamoma_subscriber_create((t_eobj*)x, empty, x->address, x->subscriberObject, returnedAddress, &returnedNode, &returnedContextNode);
287 
288  // else try to subscribe the Viewer with its name
289  else
290  err = jamoma_subscriber_create((t_eobj*)x, x->wrappedObject, EXTRA->name, x->subscriberObject, returnedAddress, &returnedNode, &returnedContextNode);
291 
292  }
293  // Model patcher case :
294  // try to binds on the parameter|message|return of the model without subscribing the Viewer
295  else if (x->patcherContext == kTTSym_model)
296  err = jamoma_subscriber_create((t_eobj*)x, empty, x->address, x->subscriberObject, returnedAddress, &returnedNode, &returnedContextNode);
297 
298  // Any other case : give up
299  else
300  return;
301 
302  // if the subscription is succesfull
303  if (!err) {
304 
305  // get the context address to make
306  // a viewer on the contextAddress/model:address attribute
307  x->subscriberObject.get("contextAddress", v);
308  contextAddress = v[0];
309 
310  // observe model:address attribute (in view patcher : deferlow return_model_address)
311  makeInternals_receiver(x, contextAddress, TTSymbol("model:address"), gensym("return_model_address"), anObject, x->patcherContext == kTTSym_view);
312 
313  return;
314  }
315  }
316  // else, if no context, set address directly
317  else {
318  contextAddress = kTTAdrsRoot;
319  absoluteAddress = contextAddress.appendAddress(x->address);
320  x->wrappedObject.set(kTTSym_address, absoluteAddress);
321 
322  atom_setsym(a, gensym((char*)absoluteAddress.c_str()));
323  outlet_anything((t_outlet*)x->dumpOut, gensym("address"), 1, a);
324 
325  // observe :description attribute
326  if (x->internals->lookup(TTSymbol(":description"), v))
327 
328  makeInternals_receiver(x, absoluteAddress, TTSymbol(":description"), gensym("return_description"), anObject, YES);
329 
330  else {
331  anObject = v[0];
332  anObject.set(kTTSym_address, absoluteAddress.appendAttribute(kTTSym_description));
333  }
334 
335  return;
336  }
337 
338  // otherwise while the context node is not registered : try to binds again :(
339  // (to -- this is not a good way todo. For binding we should make a subscription
340  // to a notification mechanism and each time an TTObjet subscribes to the namespace
341  // using jamoma_subscriber_create we notify all the externals which have used
342  // jamoma_subscriber_create with NULL object to bind)
343 
344  // release the subscriber
345  x->subscriberObject = TTObject();
346 
347  x->index++; // the index member is usefull to count how many time the external tries to bind
348  if (x->index > 100) {
349  pd_error((t_object*)x, "couldn't bind to j.parameter %s", x->address.c_str());
350  outlet_anything((t_outlet*)x->dumpOut, gensym("error"), 0, NULL);
351  return;
352  }
353 
354  // The following must be deferred because we have to interrogate our box,
355  // and our box is not yet valid until we have finished instantiating the object.
356  // Trying to use a loadbang method instead is also not fully successful (as of Max 5.0.6)
357 // defer_low((t_object*)x, (method)remote_subscribe, NULL, 0, 0);
358  remote_subscribe(x);
359 }
360 
361 void remote_return_value(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
362 {
364 
365  // a gate to not output the value if it have been set by this j.remote
366  if (EXTRA->setting) {
367  EXTRA->setting = NO;
368  return;
369  }
370 
371  // avoid blank before data
372  if (msg == _sym_nothing)
373  outlet_anything((t_outlet*)x->outlets[value_out], NULL, argc, argv);
374  else
375  outlet_anything((t_outlet*)x->outlets[value_out], msg, argc, argv);
376 
377  // Copy msg and atom in order to avoid losing data
378  copy_msg_argc_argv(self, msg, argc, argv);
379 
380  clock_set(EXTRA->ui_clock,10);
381 }
382 
383 void remote_ui_queuefn(TTPtr self)
384 {
386 
387  if (x->argc && x->argv)
388  outlet_anything((t_outlet*)x->outlets[set_out], _sym_set, x->argc, x->argv);
389 }
390 
391 void remote_bang(TTPtr self)
392 {
393  remote_list(self, _sym_bang, 0, NULL);
394 }
395 
396 void remote_float(TTPtr self, t_float value)
397 {
398  t_atom a;
399 
400  atom_setfloat(&a, value);
401  remote_list(self, _sym_float, 1, &a);
402 }
403 
404 TTErr remote_list(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
405 {
407 
408  return jamoma_viewer_send(x->wrappedObject, msg, argc, argv);
409 }
410 
411 void remote_set(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
412 {
414 
415  EXTRA->setting = YES;
416 
417  if (remote_list(self, _sym_nothing, argc, argv))
418 
419  EXTRA->setting = NO;
420 }
421 
422 void WrappedViewerClass_anything(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
423 {
425  TTValue v;
426 
427  jamoma_viewer_send(x->wrappedObject, msg, argc, argv);
428 }
429 
430 void remote_return_model_address(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
431 {
433  TTAddress absoluteAddress;
434  TTObject anObject;
435  t_atom a[1];
436  TTSymbol service;
437  TTValue v;
438 
439  if (argc && argv && x->wrappedObject.valid()) {
440 
441  // set address attribute of the wrapped Viewer object
442  absoluteAddress = TTAddress(atom_getsym(argv)->s_name).appendAddress(x->address);
443  x->wrappedObject.set(kTTSym_address, absoluteAddress);
444  x->index = 0; // the index member is usefull to count how many time the external tries to bind
445 
446  // observe :description attribute
447  if (x->internals->lookup(TTSymbol(":description"), v))
448 
449  makeInternals_receiver(x, absoluteAddress, TTSymbol(":description"), gensym("return_description"), anObject, YES);
450 
451  else {
452  anObject = v[0];
453  anObject.set(kTTSym_address, absoluteAddress.appendAttribute(kTTSym_description));
454  }
455 
456  atom_setsym(a, gensym((char*)absoluteAddress.c_str()));
457  outlet_anything((t_outlet*)x->dumpOut, gensym("address"), 1, a);
458 
459  JamomaDebug logpost((t_object*)x,3, "binds on %s", absoluteAddress.c_str());
460  }
461 }
462 
463 void remote_return_description(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
464 {
466 
467  // if an ui object is connected
468  // if (EXTRA->connected)
469 
470  // set its annotation attribute
471  // there is no annotation on Pd, right ?
472  // object_attr_setvalueof(EXTRA->connected, _sym_annotation , argc, argv);
473 }
474 
475 void remote_address(TTPtr self, t_symbol *address)
476 {
478 
479  x->address = TTAddress(address->s_name);
480 
481  // unsubscribe the remote before
482  if (x->subscriberObject.valid())
483  x->subscriberObject = TTObject();
484 
485  remote_subscribe(self);
486 }
487 
488 void remote_loadbang(TTPtr self)
489 {
491  remote_subscribe(self);
492 }
493 
494 void remote_attach(TTPtr self, int attach_output_id)
495 {
497  t_outlet *myoutlet = NULL;
498  t_dll *connecteds = NULL;
499  t_object *object, *box;
500  t_symbol *maxclass = NULL;
501  long ac;
502  t_atom *av;
503 
504  /* TODO reenable this for Pd later
505  * but how to know on wich object it's connected ?
506  // get the first object connected to the given outlet
507  object_obex_lookup(x, _sym_pound_B, &box);
508 
509  myoutlet = (t_outlet*)jbox_getoutlet((t_jbox*)box, attach_output_id);
510  if (myoutlet)
511  connecteds = (t_dll*)myoutlet->o_dll;
512 
513  if (connecteds) {
514 
515  object = (t_object*)connecteds->d_x1;
516 
517  // check object class
518  if (object)
519  maxclass = object_attr_getsym(object, _sym_maxclass);
520 
521  EXTRA->connected = object;
522  if (EXTRA->connected && maxclass) {
523 
524  // get presentation object size
525  ac = 0;
526  av = NULL;
527  object_attr_getvalueof(EXTRA->connected, _sym_presentation_rect , &ac, &av);
528  if (ac && av) {
529  EXTRA->x = atom_getlong(av+0);
530  EXTRA->y = atom_getlong(av+1);
531  EXTRA->w = atom_getlong(av+2);
532  EXTRA->h = atom_getlong(av+3);
533  }
534 
535  // if no name is provided : edit the name.instance part of the address and the name of the ui object
536  if (EXTRA->name == kTTAdrsEmpty) {
537 
538  TTString editName = x->address.c_str();
539  editName += "(";
540  editName += maxclass->s_name;
541  editName += ")";
542 
543  EXTRA->name = TTAddress(editName);
544  }
545  }
546  }
547  */
548 
549  // if no ui object are connected to :
550  if (!connecteds || !object || !maxclass) {
551 
552  // the set outlet
553  if (attach_output_id == set_out)
554 
555  // try to see at the data outlet
556  return remote_attach(self, value_out);
557 
558  // the value outlet
559  else if (attach_output_id == value_out)
560 
561  // try to see at the attach outlet
562  return remote_attach(self, attach_out);
563 
564  // the attach outlet
565  else
566 
567  // give up
568  return;
569  }
570 }
571 
572 // When the mouse is moving on the j.ui (not our remote object !)
573 /* TODO : AV remove this for now, do we need it in Puredata ?
574 void remote_mousemove(TTPtr self, t_object *patcherview, t_pt pt, long modifiers)
575 {
576  WrappedModularInstancePtr x = (WrappedModularInstancePtr)self;
577  TTValue v;
578  TTBoolean selected;
579  t_object *patcher;
580  long ac;
581  t_atom *av;
582  t_atom a;
583 
584  if (EXTRA->connected) {
585 
586  // if the control key is pressed
587  if (modifiers & eShiftKey) {
588 
589  // hide gui
590  atom_setlong(&a, 1);
591  object_attr_setvalueof(EXTRA->connected, _sym_hidden, 1, &a);
592 
593  // create a comment object
594  if (!EXTRA->label) {
595  patcher = NULL;
596  ac = 0;
597  av = NULL;
598  object_obex_lookup(x, gensym("#P"), &patcher);
599  EXTRA->label = newobject_sprintf(patcher, "@maxclass comment @presentation 1 @textcolor 1. 1. 1. 1.");
600  object_attr_getvalueof(EXTRA->connected, _sym_presentation_rect , &ac, &av);
601  if (ac && av && EXTRA->label) {
602  object_method_long(EXTRA->label, _sym_fontsize, 10, &a);
603  object_method_sym(EXTRA->label, _sym_set, gensym((char*)x->address.c_str()), &a);
604  object_method_typed(EXTRA->label, _sym_presentation_rect, ac, av, &a);
605  }
606  }
607 
608  // display selected attribute by changing background color if selected
609  x->wrappedObject.get(kTTSym_highlight, v);
610  selected = v[0];
611 
612  if (EXTRA->label) {
613  if (selected)
614  object_attr_setvalueof(EXTRA->label, _sym_bgcolor, 4, (t_atom*)EXTRA->color1);
615  else
616  object_attr_setvalueof(EXTRA->label, _sym_bgcolor, 4, (t_atom*)EXTRA->color0);
617  }
618  }
619  // else set default color
620  // TODO : do this only one time !!!
621  else {
622 
623  // show gui
624  atom_setlong(&a, 0);
625  object_attr_setvalueof(EXTRA->connected, _sym_hidden, 1, &a);
626 
627  // delete label
628  if (EXTRA->label) {
629  object_free(EXTRA->label);
630  EXTRA->label = NULL;
631  }
632  }
633  }
634 }
635 
636 // When the mouse is leaving on the j.ui (not our remote object !)
637 void remote_mouseleave(TTPtr self, t_object *patcherview, t_pt pt, long modifiers)
638 {
639  WrappedModularInstancePtr x = (WrappedModularInstancePtr)self;
640  t_atom a;
641 
642  // if mouse leaves j.ui maybe it is on our object
643  if (pt.x > EXTRA->x && pt.x < EXTRA->x+EXTRA->w && pt.y > EXTRA->y && pt.y < EXTRA->y+EXTRA->h)
644  return;
645 
646  // else the mouse leaves outside the j.ui
647  else {
648 
649  // show gui
650  atom_setlong(&a, 0);
651  object_attr_setvalueof(EXTRA->connected, _sym_hidden, 1, &a);
652 
653  // delete label
654  if (EXTRA->label) {
655  object_free(EXTRA->label);
656  EXTRA->label = NULL;
657  }
658  }
659 }
660 
661 void remote_mousedown(TTPtr self, t_object *patcherview, t_pt pt, long modifiers)
662 {
663  WrappedModularInstancePtr x = (WrappedModularInstancePtr)self;
664  TTValue v;
665  TTBoolean selected;
666 
667  // if the control key is pressed
668  if (modifiers & eShiftKey) {
669 
670  // if mouse leave j.ui maybe it is on our object
671  if (pt.x > EXTRA->x && pt.x < EXTRA->x+EXTRA->w && pt.y > EXTRA->y && pt.y < EXTRA->y+EXTRA->h) {
672 
673  x->wrappedObject.get(kTTSym_highlight, v);
674  selected = v[0];
675 
676  // reverse selected attribute and change color
677  if (EXTRA->label) {
678  if (selected) {
679  x->wrappedObject.set(kTTSym_highlight, NO);
680  object_attr_setvalueof(EXTRA->label, _sym_bgcolor, 4, (t_atom*)EXTRA->color0);
681  }
682  else {
683  x->wrappedObject.set(kTTSym_highlight, YES);
684  object_attr_setvalueof(EXTRA->label, _sym_bgcolor, 4, (t_atom*)EXTRA->color1);
685  }
686  }
687  }
688  }
689 }
690 */
TTErr JAMOMA_EXPORT jamoma_patcher_get_info(t_object *obj, t_object **returnedPatcher, TTSymbol &returnedContext, TTSymbol &returnedClass, TTSymbol &returnedName)
Get all context info from an object (his patcher and the context, the class and the name of his patch...
TTAddress appendAddress(const TTAddress &toAppend)
Return a new TTAddress with the appended part.
Definition: TTAddress.h:167
TTObject subscriberObject
The instance of a TTSubscriber object used to register the wrapped object in the tree structure...
bool TTBoolean
Boolean flag, same as Boolean on the Mac.
Definition: TTBase.h:167
TTSymbol & getInstance()
Get the instance part.
Definition: TTAddress.h:124
TTAddress appendAttribute(TTSymbol anAttribute)
Return a new TTAddress with attribute part.
Definition: TTAddress.h:161
TTHandle outlets
an array of outlet
TTErr lookup(const TTSymbol key, TTValue &value)
Find the value for the given key.
Definition: TTHash.cpp:76
We build a directory of TTNodes, and you can request a pointer for any TTNode, or add an observer to ...
Definition: TTNode.h:59
TTAddress address
sometime external needs to store an address (e.g. send, receive, view, ...)
TTAddress getParent()
Get a pointer to the parent address.
Definition: TTAddress.h:112
TTSymbol patcherClass
the patcher class in which the external is
The TTAddress class is used to represent a string and efficiently pass and compare that string...
Definition: TTAddress.h:29
Create and use Jamoma object instances.
Definition: TTObject.h:29
Data structure for storing extra data.
void * extra
used to keep very specific things
t_object * patcherPtr
the patcher in which the external is (ignoring subpatcher)
TTHashPtr internals
An hash table to store any internal TTObjectBases (like TTData, TTViewer, ...)
void * TTPtr
A generic pointer.
Definition: TTBase.h:248
TTErr get(const TTSymbol aName, T &aReturnedValue) const
Get an attribute value for an object.
TTErr set(const TTSymbol aName, T aValue)
Set an attribute value for an object.
void copy_msg_argc_argv(TTPtr self, t_symbol *msg, long argc, const t_atom *argv)
tools to copy msg, argc and argv into the member msg, argc and argv of the WrappedModularInstance ...
The TTSymbol class is used to represent a string and efficiently pass and compare that string...
Definition: TTSymbol.h:26
TTObject wrappedObject
The instance of the Jamoma object we are wrapping.
TTSymbol & getAttribute()
Get the attribute part.
Definition: TTAddress.h:130
this flag means that an address have a leading slash
Definition: TTAddressBase.h:65
const char * c_str() const
Return a pointer to the internal string as a C-string.
Definition: TTSymbol.h:77
Wraps Jamoma Core classes as objects for PureData.
Data Structure for this object.
TTErr JAMOMA_EXPORT jamoma_viewer_create(t_object *x, TTObject &returnedViewer)
Create a #TTViewer object.
TTAddressType getType()
Get the type.
Definition: TTAddress.h:136
TTErr
Jamoma Error Codes Enumeration of error codes that might be returned by any of the TTBlue functions a...
Definition: TTBase.h:342
TTSymbol patcherContext
the patcher context in which the external is (model, view)
TTSymbol patcherName
the patcher name in which the external is
TTErr JAMOMA_EXPORT jamoma_subscriber_create(t_object *x, TTObject &anObject, TTAddress relativeAddress, TTObject &returnedSubscriber, TTSymbol &returnedAddress, TTNodePtr *returnedNode, TTNodePtr *returnedContextNode)
Create a #TTSubscriber object and register a TTObject into the tree or, if aTTObject is NULL...
long index
index of the inlet used
TTBoolean valid() const
Determine if the object contained by this TTObject is truly ready for use.
Definition: TTObject.cpp:179
TTSymbol & getName()
Get the name part.
Definition: TTAddress.h:118
TTErr JAMOMA_EXPORT jamoma_viewer_send(TTObject &aViewer, t_symbol *msg, long argc, const t_atom *argv)
Send Max data using a #TTViewer object.
WrappedModularInstance * WrappedModularInstancePtr
Pointer to a wrapped instance of our object.
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34
TTErr wrapTTModularClassAsPdClass(TTSymbol &ttblueClassName, const char *pdClassName, WrappedClassPtr *c, ModularSpec *specificities)
Wrap a Jamoma class as a Pd class.