Max 5 API Reference
00001 /** 00002 @file 00003 attrtester - a max object shell 00004 jeremy bernstein - jeremy@bootsquad.com 00005 00006 @ingroup examples 00007 */ 00008 00009 #include "ext.h" // standard Max include, always required 00010 #include "ext_obex.h" // required for new style Max object 00011 00012 ////////////////////////// object struct 00013 typedef struct _attrtester 00014 { 00015 t_object a_ob; // the object itself (must be first) 00016 long a_val; 00017 char a_usemin; 00018 char a_usemax; 00019 long a_min; 00020 long a_max; 00021 void *a_out; 00022 } t_attrtester; 00023 00024 ///////////////////////// function prototypes 00025 //// standard set 00026 void *attrtester_new(t_symbol *s, long argc, t_atom *argv); 00027 void attrtester_free(t_attrtester *x); 00028 void attrtester_assist(t_attrtester *x, void *b, long m, long a, char *s); 00029 //// additional methods 00030 void attrtester_int(t_attrtester *x, long n); 00031 void attrtester_float(t_attrtester *x, double f); 00032 void attrtester_bang(t_attrtester *x); // incoming bang message 00033 00034 t_max_err attrtester_min_get(t_attrtester *x, void *attr, long *ac, t_atom **av); 00035 t_max_err attrtester_min_set(t_attrtester *x, void *attr, long ac, t_atom *av); 00036 00037 //////////////////////// global class pointer variable 00038 void *attrtester_class; 00039 00040 // CLASS_ATTR_ORDER(c, "val", 0, "1"); 00041 // CLASS_ATTR_ORDER(c, "usemax", 0, "-1"); 00042 // CLASS_ATTR_ACCESSORS(c, "min", (method)attrtester_min_get, (method)attrtester_min_set); 00043 // CLASS_ATTR_STYLE_LABEL(c, "usemin", 0, "onoff", "Use Minimum"); 00044 // CLASS_ATTR_INVISIBLE(c, "val", 0); 00045 // CLASS_ATTR_SAVE(c, "min", 0, "0"); 00046 // CLASS_ATTR_ATTR_PARSE(c, "float", "undocumented", gensym("long"), 0, "1"); 00047 00048 int main(void) 00049 { 00050 t_class *c; 00051 00052 c = class_new("attrtester", (method)attrtester_new, (method)attrtester_free, (long)sizeof(t_attrtester), 0L, A_GIMME, 0); 00053 00054 class_addmethod(c, (method)attrtester_bang, "bang", 0); 00055 class_addmethod(c, (method)attrtester_int, "int", A_LONG, 0); 00056 class_addmethod(c, (method)attrtester_float, "float", A_FLOAT, 0); 00057 00058 class_addmethod(c, (method)attrtester_assist, "assist", A_CANT, 0); 00059 00060 /* Inspector items ARE ATTRIBUTES */ 00061 CLASS_ATTR_LONG(c, "min", 0, t_attrtester, a_min); 00062 CLASS_ATTR_SAVE(c, "min", 0); 00063 // override default accessors 00064 CLASS_ATTR_ACCESSORS(c, "min", (method)attrtester_min_get, (method)attrtester_min_set); 00065 00066 CLASS_ATTR_LONG(c, "max", 0, t_attrtester, a_max); 00067 // clip max value to 0-100 00068 CLASS_ATTR_FILTER_CLIP(c, "max", 0, 100); 00069 00070 CLASS_ATTR_CHAR(c, "usemin", 0, t_attrtester, a_usemin); 00071 CLASS_ATTR_CHAR(c, "usemax", 0, t_attrtester, a_usemax); 00072 00073 // read-only 00074 CLASS_ATTR_LONG(c, "val", 0 /*ATTR_SET_OPAQUE_USER*/, t_attrtester, a_val); 00075 00076 CLASS_ATTR_CATEGORY(c, "val", 0, "Value"); // define 'Value' category 00077 00078 CLASS_ATTR_ORDER(c, "val", 0, "1"); // top of the list 00079 CLASS_ATTR_ORDER(c, "usemax", 0, "-1"); // bottom of the list 00080 00081 // index-based enumeration style 00082 CLASS_ATTR_ENUMINDEX(c, "val", 0, "zero one two \"three four\" five"); 00083 // set the label without setting the style 00084 CLASS_ATTR_LABEL(c, "val", 0, "Enumerated Value"); 00085 CLASS_ATTR_INVISIBLE(c, "val", 0); // hide attribute from inspector 00086 00087 /* style */ /* label */ 00088 CLASS_ATTR_STYLE_LABEL(c, "usemin", 0, "onoff", "Use Minimum"); 00089 CLASS_ATTR_STYLE_LABEL(c, "usemax", 0, "onoff", "Use Maximum"); 00090 00091 class_register(CLASS_BOX, c); 00092 attrtester_class = c; 00093 00094 post("I am the attrtester object"); 00095 return 0; 00096 } 00097 00098 void attrtester_assist(t_attrtester *x, void *b, long m, long a, char *s) 00099 { 00100 if (m == ASSIST_INLET) { //inlet 00101 sprintf(s, "I am inlet %ld", a); 00102 } 00103 else { // outlet 00104 sprintf(s, "I am outlet %ld", a); 00105 } 00106 } 00107 00108 void attrtester_int(t_attrtester *x, long n) 00109 { 00110 if (x->a_usemin) 00111 n = n < x->a_min ? x->a_min : n; 00112 if (x->a_usemax) 00113 n = n > x->a_max ? x->a_max : n; 00114 x->a_val = n; 00115 00116 attrtester_bang(x); 00117 } 00118 00119 void attrtester_float(t_attrtester *x, double f) 00120 { 00121 attrtester_int(x, (long)f); 00122 } 00123 00124 void attrtester_bang(t_attrtester *x) 00125 { 00126 outlet_int(x->a_out, x->a_val); 00127 } 00128 00129 t_max_err attrtester_min_get(t_attrtester *x, void *attr, long *ac, t_atom **av) 00130 { 00131 if (ac && av) { 00132 char alloc; 00133 00134 if (atom_alloc(ac, av, &alloc)) { 00135 return MAX_ERR_GENERIC; 00136 } 00137 atom_setlong(*av, x->a_min); 00138 } 00139 return MAX_ERR_NONE; 00140 } 00141 00142 t_max_err attrtester_min_set(t_attrtester *x, void *attr, long ac, t_atom *av) 00143 { 00144 if (ac && av) { 00145 long min = atom_getlong(av); 00146 // for instance... 00147 if (min <= x->a_max) 00148 x->a_min = min; 00149 } 00150 return MAX_ERR_NONE; 00151 } 00152 00153 00154 void attrtester_free(t_attrtester *x) 00155 { 00156 ; 00157 } 00158 00159 void *attrtester_new(t_symbol *s, long argc, t_atom *argv) 00160 { 00161 t_attrtester *x = NULL; 00162 t_dictionary *d; 00163 00164 if (x = (t_attrtester *)object_alloc(attrtester_class)) { 00165 x->a_val = 0; 00166 x->a_min = -52; 00167 x->a_max = 0; 00168 x->a_usemin = 0; 00169 x->a_usemax = 0; 00170 x->a_out = outlet_new(x, NULL); // then to the left 00171 00172 d = (t_dictionary *)gensym("#D")->s_thing; 00173 if (d) { 00174 attr_dictionary_process(x, d); 00175 } 00176 } 00177 return (x); 00178 }
Copyright © 2008, Cycling '74