Max 5 API Reference
00001 /** 00002 @file 00003 uioptimized - demonstrate the drawing of various objects using jgraphics 00004 00005 @ingroup examples 00006 */ 00007 00008 #include <stdlib.h> 00009 #include "ext.h" 00010 #include "ext_obex.h" 00011 #include "jpatcher_api.h" 00012 #include "jgraphics.h" 00013 00014 00015 /**********************************************************************/ 00016 // Data Structures 00017 00018 typedef struct _uioptimized { 00019 t_jbox j_box; 00020 t_jrgba j_rectcolor; // rectangle color 00021 t_jrgba j_overcolor; // rectangle over color 00022 long j_rectangle; // number of rectangles to display 00023 t_rect *j_rects; // the location of the rectangles 00024 long j_overrect; // index of the over rectangle 00025 void *j_out; // index outlet 00026 } t_uioptimized; 00027 00028 00029 /**********************************************************************/ 00030 // Prototypes 00031 00032 void uioptimized_initclass(); 00033 t_uioptimized* uioptimized_new(t_symbol *s, short argc, t_atom *argv); 00034 void uioptimized_free(t_uioptimized *x); 00035 00036 void uioptimized_mousemove(t_uioptimized *x, t_object *patcherview, t_pt pt, long modifiers); 00037 void uioptimized_mouseleave(t_uioptimized *x, t_object *patcherview, t_pt pt, long modifiers); 00038 00039 void uioptimized_paint(t_uioptimized *x, t_object *view); 00040 void uioptimized_paint_background(t_uioptimized *x, t_object *view, t_rect *rect); 00041 t_max_err uioptimized_notify(t_uioptimized *x, t_symbol *s, t_symbol *msg, void *sender, void *data); 00042 void uioptimized_assist(t_uioptimized *x, void *b, long m, long a, char *s); 00043 t_max_err uioptimized_setattr_rectangle(t_uioptimized *x, void *attr, long ac, t_atom *av); 00044 00045 00046 /**********************************************************************/ 00047 // Globals and Statics 00048 00049 static t_class *s_uioptimized_class = NULL; 00050 00051 00052 /**********************************************************************/ 00053 // Class Definition and Life Cycle 00054 00055 int main(void) 00056 { 00057 t_class *c; 00058 00059 c = class_new("uioptimized", 00060 (method)uioptimized_new, 00061 (method)uioptimized_free, 00062 sizeof(t_uioptimized), 00063 (method)NULL, 00064 A_GIMME, 00065 0L); 00066 00067 c->c_flags |= CLASS_FLAG_NEWDICTIONARY; 00068 jbox_initclass(c, 0); 00069 00070 class_addmethod(c, (method) uioptimized_mousemove, "mousemove", A_CANT, 0); 00071 class_addmethod(c, (method) uioptimized_mouseleave, "mouseleave", A_CANT, 0); 00072 class_addmethod(c, (method) uioptimized_paint, "paint", A_CANT, 0); 00073 class_addmethod(c, (method) uioptimized_notify, "notify", A_CANT, 0); // so the PAINT attribute of the attribute redraws the object 00074 class_addmethod(c, (method) uioptimized_assist, "assist", A_CANT, 0); 00075 00076 CLASS_ATTR_RGBA(c, "rectcolor", 0, t_uioptimized, j_rectcolor); 00077 CLASS_ATTR_STYLE_LABEL(c, "rectcolor", 0, "rgba", "Rectangle Color"); 00078 CLASS_ATTR_DEFAULT_SAVE_PAINT(c, "rectcolor", 0, "0. 0. 0. 1."); 00079 00080 CLASS_ATTR_RGBA(c, "overcolor", 0, t_uioptimized, j_overcolor); 00081 CLASS_ATTR_STYLE_LABEL(c, "overcolor", 0, "rgba", "Rectangle Over Color"); 00082 CLASS_ATTR_DEFAULT_SAVE_PAINT(c, "overcolor", 0, "1. 0. 0. 1."); 00083 00084 CLASS_ATTR_LONG(c, "rectangle", 0, t_uioptimized, j_rectangle); 00085 CLASS_ATTR_LABEL(c, "rectangle", 0, "Number of Rectangles"); 00086 CLASS_ATTR_DEFAULT_SAVE_PAINT(c, "rectangle", 0, "74"); 00087 CLASS_ATTR_ACCESSORS(c, "rectangle", (method)NULL, (method)uioptimized_setattr_rectangle); 00088 00089 CLASS_ATTR_DEFAULT(c, "rect", 0, "0. 0. 128. 128."); 00090 00091 class_register(CLASS_BOX, c); 00092 s_uioptimized_class = c; 00093 return 0; 00094 } 00095 00096 00097 t_uioptimized* uioptimized_new(t_symbol *s, short argc, t_atom *argv) 00098 { 00099 t_uioptimized* x = (t_uioptimized*)object_alloc(s_uioptimized_class); 00100 t_dictionary *d = NULL; 00101 00102 if (!(d = object_dictionaryarg(argc,argv))) 00103 return NULL; 00104 00105 if (x) { 00106 long flags; 00107 flags = 0 00108 | JBOX_DRAWFIRSTIN 00109 // | JBOX_NODRAWBOX 00110 // | JBOX_DRAWINLAST 00111 | JBOX_TRANSPARENT 00112 // | JBOX_NOGROW 00113 // | JBOX_GROWY 00114 | JBOX_GROWBOTH 00115 // | JBOX_IGNORELOCKCLICK 00116 // | JBOX_HILITE 00117 // | JBOX_BACKGROUND 00118 // | JBOX_NOFLOATINSPECTOR 00119 // | JBOX_TEXTFIELD 00120 ; 00121 00122 jbox_new(&x->j_box, flags, argc, argv); 00123 x->j_box.b_firstin = (t_object*) x; 00124 00125 x->j_rects = NULL; 00126 x->j_overrect = -1; 00127 x->j_out = intout((t_object *)x); 00128 00129 // call this after initializing defaults 00130 attr_dictionary_process((t_object *)x, d); // handle attribute args 00131 00132 jbox_ready(&x->j_box); 00133 } 00134 return x; 00135 } 00136 00137 00138 void uioptimized_free(t_uioptimized *x) 00139 { 00140 if (x->j_rects) 00141 sysmem_freeptr(x->j_rects); 00142 jbox_free(&x->j_box); 00143 } 00144 00145 00146 /**********************************************************************/ 00147 // Methods 00148 00149 void uioptimized_mousemove(t_uioptimized *x, t_object *patcherview, t_pt pt, long modifiers) 00150 { 00151 t_rect rect; 00152 long i, last_over = x->j_overrect; 00153 x->j_overrect = -1; 00154 00155 jbox_get_rect_for_view((t_object *)x, patcherview, &rect); 00156 00157 for (i = 0; i < x->j_rectangle; i++) { 00158 if ( pt.x >= x->j_rects[i].x * rect.width - x->j_rects[i].width * (rect.width * 0.05) && 00159 pt.x <= x->j_rects[i].x * rect.width + x->j_rects[i].width * (rect.width * 0.05) && 00160 pt.y >= x->j_rects[i].y * rect.height - x->j_rects[i].height * (rect.height * 0.05) && 00161 pt.y <= x->j_rects[i].y * rect.height + x->j_rects[i].height * (rect.height * 0.05)) { 00162 00163 x->j_overrect = i; 00164 break; 00165 } 00166 } 00167 00168 if (last_over != x->j_overrect) { // redraw only if it's different 00169 outlet_int(x->j_out, x->j_overrect); 00170 jbox_redraw((t_jbox *)x); 00171 } 00172 } 00173 00174 void uioptimized_mouseleave(t_uioptimized *x, t_object *patcherview, t_pt pt, long modifiers) 00175 { 00176 x->j_overrect = -1; 00177 outlet_int(x->j_out, x->j_overrect); 00178 jbox_redraw((t_jbox *)x); 00179 } 00180 00181 void uioptimized_paint(t_uioptimized *x, t_object *view) 00182 { 00183 // paint the box grey 00184 t_rect rect; 00185 t_jgraphics *g; 00186 00187 g = (t_jgraphics*) patcherview_get_jgraphics(view); 00188 jbox_get_rect_for_view((t_object *)x, view, &rect); 00189 00190 // draw the background rectangles if necessary 00191 uioptimized_paint_background(x, view, &rect); 00192 00193 if (x->j_overrect != -1) { 00194 jgraphics_set_source_jrgba(g, &x->j_overcolor); 00195 jgraphics_rectangle_fill_fast(g, x->j_rects[x->j_overrect].x * rect.width - x->j_rects[x->j_overrect].width * (rect.width * 0.05), 00196 x->j_rects[x->j_overrect].y * rect.height - x->j_rects[x->j_overrect].height * (rect.height * 0.05), 00197 x->j_rects[x->j_overrect].width * (rect.width * 0.1), 00198 x->j_rects[x->j_overrect].height * (rect.height * 0.1)); 00199 } 00200 } 00201 00202 void uioptimized_paint_background(t_uioptimized *x, t_object *view, t_rect *rect) 00203 { 00204 long i; 00205 t_jgraphics *g = jbox_start_layer((t_object *)x, view, gensym("background_layer"), rect->width, rect->height); 00206 00207 if (g) { 00208 // when the layer has been invalidated using jbox_invalidate_layer, we redraw the contents of the layer 00209 jgraphics_set_source_jrgba(g, &x->j_rectcolor); // set the color 00210 00211 for (i = 0; i < x->j_rectangle; i++) { 00212 // jgraphics_rectangle_fill_fast() is the antialiased version of jgraphics_rectangle() 00213 // it's about 40 times faster than jgraphics_rectangle() 00214 jgraphics_rectangle_fill_fast(g, x->j_rects[i].x * rect->width - x->j_rects[i].width * (rect->width * 0.05), 00215 x->j_rects[i].y * rect->height - x->j_rects[i].height * (rect->height * 0.05), 00216 x->j_rects[i].width * (rect->width * 0.1), 00217 x->j_rects[i].height * (rect->height * 0.1)); 00218 } 00219 jbox_end_layer((t_object*)x, view, gensym("background_layer")); 00220 } 00221 jbox_paint_layer((t_object *)x, view, gensym("background_layer"), 0., 0.); // position of the layer 00222 } 00223 00224 t_max_err uioptimized_setattr_rectangle(t_uioptimized *x, void *attr, long ac, t_atom *av) 00225 { 00226 if (ac && av) { 00227 long rectangle = atom_getlong(av); 00228 if (rectangle < 1) 00229 rectangle = 1; 00230 if (rectangle > 8192) // it's slightly more impressive to use power of two ;-) 00231 rectangle = 8192; 00232 00233 if (rectangle != x->j_rectangle) { 00234 long i; 00235 00236 x->j_rectangle = rectangle; 00237 if (x->j_rects) 00238 sysmem_freeptr(x->j_rects); 00239 00240 x->j_rects = (t_rect *)sysmem_newptr(x->j_rectangle * sizeof(t_rect)); 00241 for (i = 0; i < x->j_rectangle; i++) { 00242 x->j_rects[i].x = (double)rand() / (double)RAND_MAX; 00243 x->j_rects[i].y = (double)rand() / (double)RAND_MAX; 00244 x->j_rects[i].width = (double)rand() / (double)RAND_MAX; 00245 x->j_rects[i].height = (double)rand() / (double)RAND_MAX; 00246 } 00247 jbox_invalidate_layer((t_object*)x, NULL, gensym("background_layer")); 00248 } 00249 } 00250 return MAX_ERR_NONE; 00251 } 00252 00253 t_max_err uioptimized_notify(t_uioptimized *x, t_symbol *s, t_symbol *msg, void *sender, void *data) 00254 { 00255 if (s == gensym("attr_modified")) { 00256 t_symbol *name = (t_symbol *)object_method((t_object *)data, gensym("getname")); 00257 00258 if (name == gensym("rectcolor")) 00259 jbox_invalidate_layer((t_object *)x, NULL, gensym("background_layer")); 00260 } 00261 return jbox_notify((t_jbox *)x, s, msg, sender, data); 00262 } 00263 00264 void uioptimized_assist(t_uioptimized *x, void *b, long m, long a, char *s) 00265 { 00266 if (m == ASSIST_INLET) // inlet 00267 sprintf(s, "Message in"); 00268 else // outlet 00269 sprintf(s, "(int) Index of the Over Rectangle"); 00270 } 00271
Copyright © 2008, Cycling '74