Max 5 API Reference
00001 #ifdef WIN_VERSION 00002 #define _CRT_SECURE_NO_DEPRECATE 00003 #endif 00004 00005 #include "ext.h" 00006 #include "ext_obex.h" 00007 #include "ext_common.h" 00008 #include "jpatcher_api.h" 00009 #include "jgraphics.h" 00010 00011 #ifdef WIN_VERSION 00012 #include <float.h> 00013 #endif 00014 00015 static t_class *s_jslider_class = 0; 00016 static t_symbol *ps_slider, *ps_hslider, *ps_preset; 00017 00018 // mouse tracking stuff 00019 00020 static t_pt s_jslider_cum; 00021 static double s_jslider_startval; 00022 00023 #define INRANGE(v,lo,hi) ((v)<=(hi)&&(v)>=(lo)) 00024 00025 #define JSLIDER_BORDERTHICKNESS (2.) 00026 #define JSLIDER_CORNERSIZE (6.) 00027 00028 #define JSLIDER_DISPLAYINSET 5 // amount subtracted from rect for value 00029 00030 typedef struct _jslider 00031 { 00032 t_jbox j_box; 00033 double j_min; 00034 double j_size; // number of steps 00035 double j_mult; 00036 double j_val; 00037 long j_floatoutput; 00038 char j_horiz; 00039 char j_relative; // relative mousing (like orig miller slider, but not like h/uslider) 00040 char j_orientation; // 0 = auto, 1 = horiz, 2 = vertical 00041 t_jrgba j_brgba; 00042 t_jrgba j_frgba; 00043 t_jrgba j_frgba2; 00044 } t_jslider; 00045 00046 void *jslider_new(t_symbol *s, short argc, t_atom *argv); 00047 void jslider_free(t_jslider *x); 00048 t_max_err jslider_notify(t_jslider *x, t_symbol *s, t_symbol *msg, void *sender, void *data); 00049 void jslider_assist(t_jslider *x, void *b, long m, long a, char *s); 00050 void jslider_preset(t_jslider *x); 00051 void *jslider_stdargs(t_dictionary *d, t_symbol *s, long argc, t_atom *argv); 00052 void jslider_paint(t_jslider *x, t_object *view); 00053 void jslider_bang(t_jslider *x); 00054 void jslider_int(t_jslider *x, long n); 00055 void jslider_float(t_jslider *x, double f); 00056 void jslider_set(t_jslider *x, t_symbol *s, long argc, t_atom *argv); 00057 void jslider_setminmax(t_jslider *x, t_symbol *s, long argc, t_atom *argv); 00058 t_max_err jslider_setattr_size(t_jslider *x, t_object *attr, long ac, t_atom *av); 00059 t_max_err jslider_setattr_floatoutput(t_jslider *x, t_object *attr, long ac, t_atom *av); 00060 t_max_err jslider_setvalueof(t_jslider *x, long ac, t_atom *av); 00061 t_max_err jslider_getvalueof(t_jslider *x, long *ac, t_atom **av); 00062 void jslider_assign(t_jslider *x, double f); 00063 double jslider_constrain(t_jslider *x, double f); 00064 void jslider_orientation(t_jslider *x, t_rect *r); 00065 double jslider_postoval(t_jslider *x, t_pt pt, t_rect *r); 00066 double jslider_valtopos(t_jslider *x, double val, t_rect *r); 00067 void jslider_mousedown(t_jslider *x, t_object *patcherview, t_pt pt, long modifiers); 00068 void jslider_mousedragdelta(t_jslider *x, t_object *patcherview, t_pt pt, long modifiers); 00069 void jslider_mouseup(t_jslider *x, t_object *patcherview, t_pt pt, long modifiers); 00070 void jslider_getdrawparams(t_jslider *x, t_object *patcherview, t_jboxdrawparams *params); 00071 00072 int main() 00073 { 00074 t_class *c; 00075 00076 common_symbols_init(); 00077 00078 c = class_new("slider", 00079 (method)jslider_new, 00080 (method)jslider_free, 00081 sizeof(t_jslider), 00082 (method)NULL, 00083 A_GIMME, 00084 0L); 00085 00086 c->c_flags |= CLASS_FLAG_NEWDICTIONARY; // to specify dictionary constructor 00087 00088 jbox_initclass(c, JBOX_FIXWIDTH | JBOX_COLOR); 00089 00090 class_addmethod(c, (method)jslider_paint, "paint", A_CANT, 0); 00091 class_addmethod(c, (method)jslider_stdargs, "stdargs", A_CANT, 0); 00092 00093 class_addmethod(c, (method)jslider_int, "int", A_LONG, 0); 00094 class_addmethod(c, (method)jslider_float, "float", A_FLOAT, 0); 00095 class_addmethod(c, (method)jslider_bang, "bang", 0); 00096 class_addmethod(c, (method)jslider_set, "set", A_GIMME, 0); 00097 class_addmethod(c, (method)jslider_setminmax, "setminmax", A_GIMME, 0); 00098 class_addmethod(c, (method)jslider_getdrawparams, "getdrawparams", A_CANT, 0); 00099 class_addmethod(c, (method)jslider_mousedown, "mousedown", A_CANT, 0); 00100 class_addmethod(c, (method)jslider_mousedragdelta, "mousedragdelta", A_CANT, 0); 00101 class_addmethod(c, (method)jslider_mouseup, "mouseup", A_CANT, 0); 00102 class_addmethod(c, (method)jslider_getvalueof, "getvalueof", A_CANT, 0); 00103 class_addmethod(c, (method)jslider_setvalueof, "setvalueof", A_CANT, 0); 00104 class_addmethod(c, (method)jslider_assist, "assist", A_CANT, 0); 00105 class_addmethod(c, (method)jslider_preset, "preset", 0); 00106 class_addmethod(c, (method)jslider_notify, "notify", A_CANT, 0); 00107 00108 CLASS_ATTR_DEFAULT(c,"patching_rect",0, "0. 0. 20. 140."); 00109 00110 CLASS_STICKY_ATTR(c,"category",0,"Value"); 00111 CLASS_ATTR_DOUBLE(c, "size", 0, t_jslider, j_size); 00112 CLASS_ATTR_ACCESSORS(c,"size",(method)NULL,(method)jslider_setattr_size); 00113 00114 CLASS_ATTR_DOUBLE(c, "min", 0, t_jslider, j_min); 00115 CLASS_ATTR_DOUBLE(c, "mult", 0, t_jslider, j_mult); 00116 00117 CLASS_ATTR_LONG(c, "floatoutput", 0, t_jslider, j_floatoutput); 00118 CLASS_ATTR_ACCESSORS(c, "floatoutput", (method)NULL, (method)jslider_setattr_floatoutput); 00119 00120 CLASS_ATTR_CHAR(c,"relative", 0, t_jslider, j_relative); 00121 CLASS_ATTR_LABEL(c,"relative", 0, "Mousing Mode"); 00122 CLASS_ATTR_ENUMINDEX(c, "relative", 0, "Absolute Relative"); 00123 CLASS_STICKY_ATTR_CLEAR(c, "category"); 00124 00125 CLASS_ATTR_CHAR(c,"orientation",0,t_jslider,j_orientation); 00126 CLASS_ATTR_LABEL(c,"orientation",0,"Orientation"); 00127 CLASS_ATTR_ENUMINDEX(c,"orientation", 0,"Automatic Horizontal Vertical"); 00128 CLASS_ATTR_DEFAULT_SAVE_PAINT(c, "orientation", 0, "0"); 00129 CLASS_ATTR_CATEGORY(c, "orientation", 0, "Appearance"); 00130 00131 CLASS_STICKY_ATTR(c, "category", 0, "Color"); 00132 CLASS_ATTR_RGBA_LEGACY(c, "bgcolor", "brgb", 0, t_jslider, j_brgba); 00133 CLASS_ATTR_ALIAS(c,"bgcolor", "brgba"); 00134 CLASS_ATTR_DEFAULTNAME_SAVE_PAINT(c,"bgcolor",0,"1. 1. 1. 1."); 00135 CLASS_ATTR_STYLE_LABEL(c, "bgcolor", 0, "rgba", "Background Color"); 00136 00137 CLASS_ATTR_RGBA_LEGACY(c,"knobcolor","frgb", 0, t_jslider, j_frgba); 00138 CLASS_ATTR_ALIAS(c,"knobcolor", "frgba"); 00139 CLASS_ATTR_DEFAULTNAME_SAVE_PAINT(c,"knobcolor",0,"0.2 0.2 0.2 1."); 00140 CLASS_ATTR_STYLE_LABEL(c, "knobcolor",0,"rgba","Knob Color"); 00141 00142 CLASS_ATTR_RGBA_LEGACY(c,"bordercolor", "rgb2",0, t_jslider, j_frgba2); 00143 CLASS_ATTR_ALIAS(c,"bordercolor", "rgba2"); 00144 CLASS_ATTR_DEFAULTNAME_SAVE_PAINT(c,"bordercolor",0,"0.5 0.5 0.5 1."); 00145 CLASS_ATTR_STYLE_LABEL(c,"bordercolor",0,"rgba","Border Color"); 00146 CLASS_STICKY_ATTR_CLEAR(c, "category"); 00147 00148 // hide the color attribute from the inspector 00149 // it's still posisble to set color via the color message or the "Color..." item menu 00150 CLASS_ATTR_INVISIBLE(c, "color", 0); 00151 CLASS_ATTR_ATTR_PARSE(c, "color","save", USESYM(long), 0, "0"); 00152 00153 CLASS_ATTR_DEFAULT_SAVE_PAINT(c,"size",0,"128"); 00154 CLASS_ATTR_DEFAULT_SAVE_PAINT(c,"min",0,"0"); 00155 CLASS_ATTR_DEFAULT_SAVE_PAINT(c,"mult",0,"1"); 00156 CLASS_ATTR_DEFAULT_SAVE_PAINT(c,"floatoutput",0,"0"); 00157 CLASS_ATTR_DEFAULT_SAVE(c,"relative",0,"0"); 00158 CLASS_ATTR_LABEL(c,"size", 0, "Range"); 00159 CLASS_ATTR_LABEL(c,"min", 0, "Output Minimum"); 00160 CLASS_ATTR_LABEL(c,"mult", 0, "Output Multiplier"); 00161 CLASS_ATTR_STYLE_LABEL(c,"floatoutput",0,"onoff","Float Output"); 00162 00163 CLASS_ATTR_ORDER(c, "floatoutput", 0, "1"); 00164 CLASS_ATTR_ORDER(c, "relative", 0, "2"); 00165 CLASS_ATTR_ORDER(c, "size", 0, "3"); 00166 CLASS_ATTR_ORDER(c, "min", 0, "4"); 00167 CLASS_ATTR_ORDER(c, "mult", 0, "5"); 00168 00169 class_register(CLASS_BOX, c); 00170 s_jslider_class = c; 00171 00172 ps_hslider = gensym("hslider"); 00173 ps_slider = gensym("slider"); 00174 ps_preset = gensym("_preset"); 00175 return 0; 00176 } 00177 00178 // slider has 6 args: x, y, w, size (height), min, and mult 00179 void *jslider_stdargs(t_dictionary *d, t_symbol *s, long argc, t_atom *argv) 00180 { 00181 long left, top, width, height, thin, length; 00182 short horiz, type; 00183 t_atom at[4]; 00184 00185 horiz = (s == ps_hslider) ? 1 : 0; 00186 type = (s == ps_slider) ? 0 : 1; // Miller's original slider (relative mousing by default) 00187 00188 if (d && argc>3 && argv) { 00189 00190 // all psaved versions should have the first 4 args, even if it's a really old patch 00191 left = atom_getlong(argv); 00192 top = atom_getlong(argv+1); 00193 thin = atom_getlong(argv+2); 00194 length = atom_getlong(argv+3); 00195 height = (horiz) ? thin : length+(type?16:7); // we need to add 16 because we have an 8 pixel border on either side of x->s_size 00196 width = (horiz) ? length+(16) : thin; // old vanilla slider was always vert so we don't need to check type 00197 00198 atom_setlong(at+0, left); 00199 atom_setlong(at+1, top); 00200 atom_setlong(at+2, width); 00201 atom_setlong(at+3, height); 00202 00203 dictionary_appendatoms(d, _sym_patching_rect, 4, at); // rect is x y width, height, like t_rect, but with long args 00204 00205 //dictionary_appendatom(d, gensym("max"), argv+3); // argv+3 is both the max and the height when importing from a miller slider 00206 // slider and u/hslider have different order... don't ask why... 00207 if (!type && argc > 5) { 00208 dictionary_appendatom(d, gensym("size"), argv+3); 00209 dictionary_appendatom(d, gensym("min"), argv+4); 00210 dictionary_appendatom(d, gensym("mult"), argv+5); 00211 } else if (type && argc > 6) { 00212 dictionary_appendatom(d, gensym("size"), argv+4); 00213 dictionary_appendatom(d, gensym("mult"), argv+5); 00214 dictionary_appendatom(d, gensym("min"), argv+6); 00215 } 00216 00217 // if it's an old slider and we're doing the stdargs then it's forced either horiz or vert, for compatibility 00218 if (horiz) 00219 dictionary_appendlong(d, gensym("orientation"), 1); // force horizontal 00220 else 00221 dictionary_appendlong(d, gensym("orientation"), 2); // force vertical 00222 00223 dictionary_appendlong(d, gensym("relative"), type ? 0 : 1); 00224 00225 // if it's hslider/uslider it does have an extra value which defines the color background 00226 if (type && argc > 7) { 00227 t_jrgba bgcolor; 00228 long color = CLIP(atom_getlong(argv+7), 0, 15); // constrains colors to 0-15 zone 00229 set_jrgba_from_boxcolor_index(color + 1, &bgcolor); 00230 00231 dictionary_appendjrgba(d, gensym("bgcolor"), &bgcolor); 00232 } 00233 } 00234 return 0; 00235 } 00236 00237 void *jslider_new(t_symbol *s, short argc, t_atom *argv) 00238 { 00239 t_jslider* x; 00240 long flags; 00241 t_dictionary *d=NULL; 00242 00243 if (!(d=object_dictionaryarg(argc,argv))) 00244 return NULL; 00245 00246 x = (t_jslider *) object_alloc(s_jslider_class); 00247 if (!x) 00248 return NULL; 00249 00250 flags = 0 00251 | JBOX_DRAWFIRSTIN 00252 | JBOX_NODRAWBOX 00253 | JBOX_DRAWINLAST // rbs -- I think we can turn this off 00254 // | JBOX_TRANSPARENT 00255 // | JBOX_NOGROW 00256 // | JBOX_GROWY 00257 | JBOX_GROWBOTH 00258 // | JBOX_HILITE 00259 | JBOX_DRAWBACKGROUND 00260 | JBOX_MOUSEDRAGDELTA 00261 | JBOX_DEFAULTNAMES 00262 // | JBOX_NOFLOATINSPECTOR 00263 ; 00264 00265 x->j_val = 0; 00266 00267 jbox_new(&x->j_box, flags, argc, argv); 00268 x->j_box.b_firstin = (t_object*) x; 00269 outlet_new((t_object *)x,NULL); 00270 00271 // make sure the floatoutput mode is set properly before asking for the size 00272 dictionary_getlong(d, gensym("floatoutput"), &x->j_floatoutput); 00273 00274 attr_dictionary_process(x,d); // handle attribute args 00275 jbox_ready(&x->j_box); 00276 return x; 00277 } 00278 00279 void jslider_assist(t_jslider *x, void *b, long m, long a, char *s) 00280 { 00281 if (m==ASSIST_INLET) { 00282 sprintf(s,"Displays Value Received"); 00283 } 00284 else { 00285 sprintf(s,"Outputs Value When Slider is Changed"); 00286 } 00287 } 00288 00289 void jslider_preset(t_jslider *x) 00290 { 00291 void *z; 00292 00293 if (!(z = ps_preset->s_thing)) 00294 return; 00295 00296 binbuf_vinsert(z,"ossf",x,object_classname(x), _sym_float, x->j_val); 00297 } 00298 00299 void jslider_free(t_jslider *x) 00300 { 00301 jbox_free(&x->j_box); 00302 } 00303 00304 00305 void jslider_paint(t_jslider *x, t_object *view) 00306 { 00307 t_rect rect; 00308 t_jgraphics *g; 00309 int pos; 00310 00311 g = (t_jgraphics*) patcherview_get_jgraphics(view); 00312 jbox_get_rect_for_view((t_object *)x, view, &rect); 00313 jslider_orientation(x, &rect); 00314 pos = jslider_valtopos(x, x->j_val, &rect); 00315 if (x->j_horiz) { 00316 jgraphics_move_to(g, pos,3); 00317 jgraphics_line_to(g, pos,rect.height - 3); 00318 } else { 00319 jgraphics_move_to(g, 3, pos); 00320 jgraphics_line_to(g, rect.width - 3, pos); 00321 } 00322 jgraphics_set_line_width(g,3); 00323 jgraphics_set_source_jrgba(g, &x->j_frgba); 00324 jgraphics_stroke(g); 00325 } 00326 00327 void jslider_bang(t_jslider *x) 00328 { 00329 double value; 00330 00331 value = x->j_val * x->j_mult; 00332 value += x->j_min; 00333 00334 if (x->j_floatoutput) 00335 outlet_float(x->j_box.b_ob.o_outlet, value); 00336 else { 00337 long iv; 00338 00339 iv = value + (value >= 0 ? 0.5 : -0.5); // rounding properly negative numbers too 00340 outlet_int(x->j_box.b_ob.o_outlet, iv); 00341 } 00342 } 00343 00344 void jslider_int(t_jslider *x, long n) 00345 { 00346 jslider_assign(x, (double)n); 00347 jslider_bang(x); 00348 } 00349 00350 void jslider_float(t_jslider *x, double f) 00351 { 00352 jslider_assign(x, f); 00353 jslider_bang(x); 00354 } 00355 00356 void jslider_setminmax(t_jslider *x, t_symbol *s, long argc, t_atom *argv) 00357 { 00358 double a, b; 00359 00360 if (argc > 1) { 00361 a = b = 0; 00362 00363 if (argv[0].a_type == A_LONG) 00364 a = (double)atom_getlong(&argv[0]); 00365 else if (argv[0].a_type == A_FLOAT) 00366 a = (double)atom_getfloat(&argv[0]); 00367 00368 if (argv[1].a_type == A_LONG) 00369 b = (double)atom_getlong(&argv[1]); 00370 else if (argv[1].a_type == A_FLOAT) 00371 b = (double)atom_getfloat(&argv[1]); 00372 00373 if (a == b) { 00374 x->j_min = 0.; 00375 x->j_size = 1.; 00376 } else if (a < b) { 00377 x->j_min = a; 00378 x->j_size = b - a; 00379 } else { 00380 x->j_min = b; 00381 x->j_size = a - b; 00382 } 00383 00384 x->j_floatoutput = 1; 00385 } 00386 } 00387 00388 void jslider_set(t_jslider *x, t_symbol *s, long argc, t_atom *argv) 00389 { 00390 if (argc && (argv->a_type == A_FLOAT || argv->a_type == A_LONG)) 00391 jslider_assign(x, atom_getfloat(argv)); 00392 } 00393 00394 t_max_err jslider_setattr_size(t_jslider *x, t_object *attr, long ac, t_atom *av) 00395 { 00396 double d; 00397 00398 if (ac && av) { 00399 d = atom_getfloat(av); 00400 if (x->j_floatoutput == 1) { 00401 if (d < 1) 00402 d = 1; 00403 } else if (x->j_floatoutput != -1) { 00404 d = (long)d; 00405 if (d < 2) 00406 d = 2; 00407 } 00408 x->j_size = d; 00409 x->j_val = jslider_constrain(x, x->j_val); 00410 } 00411 return MAX_ERR_NONE; 00412 } 00413 00414 t_max_err jslider_setattr_floatoutput(t_jslider *x, t_object *attr, long ac, t_atom *av) 00415 { 00416 if (ac && av) { 00417 x->j_floatoutput = atom_getlong(av) ? 1 : 0; 00418 object_attr_setfloat(x, gensym("size"), x->j_size); // make sure the range is correct 00419 } 00420 return MAX_ERR_NONE; 00421 } 00422 00423 t_max_err jslider_setvalueof(t_jslider *x, long ac, t_atom *av) 00424 { 00425 if (ac && av) { 00426 if (av->a_type == A_FLOAT) 00427 jslider_float(x, atom_getfloat(av)); 00428 else if (av->a_type == A_LONG) 00429 jslider_int(x, atom_getlong(av)); 00430 } 00431 return MAX_ERR_NONE; 00432 } 00433 00434 t_max_err jslider_getvalueof(t_jslider *x, long *ac, t_atom **av) 00435 { 00436 t_atom a; 00437 00438 if (ac && av) { 00439 if (*ac && *av) { 00440 //memory passed in use it 00441 } else { 00442 *av = (t_atom *)getbytes(sizeof(t_atom)); 00443 } 00444 *ac = 1; 00445 if (x->j_floatoutput) 00446 atom_setfloat(&a,x->j_val); 00447 else 00448 atom_setlong(&a,(long)x->j_val); 00449 **av = a; 00450 } 00451 return MAX_ERR_NONE; 00452 } 00453 00454 void jslider_assign(t_jslider *x, double f) 00455 { 00456 x->j_val = jslider_constrain(x,f); 00457 object_notify(x, _sym_modified, NULL); 00458 jbox_redraw(&x->j_box); 00459 } 00460 00461 double jslider_constrain(t_jslider *x, double f) 00462 { 00463 if (f < 0. || (f != f)) // rbs -- f != f tests for infinities and nans 00464 f = 0.; 00465 00466 if (x->j_floatoutput) { // constrain number between 0 and max, inclusive 00467 if (f > x->j_size) 00468 f = x->j_size; 00469 return f; 00470 } else { // constrain number from 0 and max - 1 00471 long val; 00472 long max = (long) x->j_size; 00473 00474 // rbs -- compare f to x->j_size which is a double. 00475 // This way, if f is very big (bigger than max value a long can take) 00476 // there won't be a problem. For example (long)(5672881664.) is actually negative! 00477 if (f > x->j_size) 00478 f = x->j_size; 00479 val = (long) f; // do cast now that we've limited the value 00480 if (val >= max) 00481 val = max - 1; 00482 return (double)val; 00483 } 00484 } 00485 00486 void jslider_orientation(t_jslider *x, t_rect *r) 00487 { 00488 if (x->j_orientation == 0) { // automatic mode 00489 if (r->height > r->width) 00490 x->j_horiz = 0; 00491 else 00492 x->j_horiz = 1; 00493 } else 00494 x->j_horiz = x->j_orientation == 2 ? 0 : 1; 00495 } 00496 00497 double jslider_postoval(t_jslider *x, t_pt pt, t_rect *r) 00498 { 00499 double pos, range; 00500 00501 if (x->j_horiz) { 00502 pos = pt.x; 00503 range = r->width; 00504 } else { 00505 pos = r->height - pt.y; 00506 range = r->height; 00507 } 00508 if (pos <= JSLIDER_DISPLAYINSET) 00509 pos = 0.; 00510 else { 00511 pos -= JSLIDER_DISPLAYINSET; 00512 pos = (pos / (range - (JSLIDER_DISPLAYINSET*2))) * x->j_size; 00513 } 00514 return jslider_constrain(x,pos); 00515 } 00516 00517 double jslider_valtopos(t_jslider *x, double val, t_rect *r) 00518 { 00519 double pos, range; 00520 double size; 00521 00522 if (x->j_horiz) 00523 range = r->width; 00524 else 00525 range = r->height; 00526 00527 if (x->j_floatoutput) 00528 size = x->j_size; 00529 else 00530 size = x->j_size - 1; 00531 00532 if (size < 0) 00533 size = 0; 00534 if (size) 00535 pos = (val / size) * (range - (JSLIDER_DISPLAYINSET*2)); 00536 else 00537 pos = 0; 00538 00539 pos += JSLIDER_DISPLAYINSET; 00540 if (x->j_horiz) 00541 return pos; 00542 else 00543 return r->height - pos; 00544 } 00545 00546 void jslider_mousedown(t_jslider *x, t_object *patcherview, t_pt pt, long modifiers) 00547 { 00548 t_rect rect; 00549 double val; 00550 00551 jbox_get_rect_for_view((t_object *)x, patcherview, &rect); 00552 s_jslider_cum.x = s_jslider_cum.y = 0; 00553 val = jslider_postoval(x,pt,&rect); 00554 if (!x->j_relative) 00555 jslider_float(x, val); // set value immediately 00556 s_jslider_startval = x->j_val; 00557 } 00558 00559 void jslider_mousedragdelta(t_jslider *x, t_object *patcherview, t_pt pt, long modifiers) 00560 { 00561 t_rect rect; 00562 double inc; 00563 double val, cval; 00564 double factor; 00565 00566 jbox_get_rect_for_view((t_object *)x, patcherview, &rect); 00567 00568 if (modifiers & eShiftKey) { 00569 pt.y *= 0.2; 00570 pt.x *= 0.2; 00571 } 00572 // need to cancel cum change if it is beyond zero or the max value 00573 s_jslider_cum.x += pt.x; 00574 s_jslider_cum.y -= pt.y; 00575 if (x->j_horiz) { 00576 factor = x->j_size / (rect.width - (JSLIDER_DISPLAYINSET*2)); 00577 inc = s_jslider_cum.x * factor; 00578 val = s_jslider_startval + inc; 00579 if (! x->j_floatoutput) // if shift is down, rounding make it work when the slider goes up in integer mode 00580 val = (long)(val + 0.5); 00581 cval = jslider_constrain(x,val); 00582 jslider_float(x,cval); 00583 // in case we were constrained, adjust the cum 00584 if (cval != val) 00585 s_jslider_cum.x = (cval-s_jslider_startval) / factor; 00586 } else { 00587 factor = x->j_size / (rect.height - (JSLIDER_DISPLAYINSET*2)); 00588 inc = s_jslider_cum.y * factor; 00589 val = s_jslider_startval + inc; 00590 if (! x->j_floatoutput) // if shift is down, rounding make it work when the slider goes up in integer mode 00591 val = (long)(val + 0.5); 00592 cval = jslider_constrain(x,val); 00593 jslider_float(x,cval); 00594 if (cval != val) 00595 s_jslider_cum.y = (cval - s_jslider_startval) / factor; 00596 } 00597 } 00598 00599 void jslider_mouseup(t_jslider *x, t_object *patcherview, t_pt pt, long modifiers) 00600 { 00601 double pos, vp; 00602 t_rect rect; 00603 double mx, my; 00604 00605 jbox_get_rect_for_view((t_object *)x, patcherview, &rect); 00606 jslider_orientation(x, &rect); 00607 pos = jslider_valtopos(x, x->j_val, &rect); 00608 vp = pos + 0.5; 00609 if (x->j_horiz) { 00610 mx = vp; 00611 my = pt.y; // have y position be same as where mouse down clicked 00612 } else { 00613 mx = pt.x; // have x position be same as where mouse down clicked 00614 my = vp; 00615 } 00616 00617 if (fabs(pt.x-mx) > 1. || fabs(pt.y-my) > 1.) // this make sure that if you click at the "same" location we don't move the mouse. 00618 jmouse_setposition_box(patcherview, (t_object*) x, mx, my); 00619 } 00620 00621 void jslider_getdrawparams(t_jslider *x, t_object *patcherview, t_jboxdrawparams *params) 00622 { 00623 params->d_borderthickness = JSLIDER_BORDERTHICKNESS; 00624 params->d_bordercolor = x->j_frgba2; 00625 params->d_cornersize = JSLIDER_CORNERSIZE; 00626 params->d_boxfillcolor = x->j_brgba; 00627 } 00628 00629 t_max_err jslider_notify(t_jslider *x, t_symbol *s, t_symbol *msg, void *sender, void *data) 00630 { 00631 long argc = 0; 00632 t_atom *argv = NULL; 00633 t_symbol *name; 00634 00635 if (msg == _sym_attr_modified) { 00636 name = (t_symbol *)object_method((t_object *)data,_sym_getname); 00637 if (name == _sym_color) { 00638 object_attr_getvalueof(x, _sym_color, &argc, &argv); 00639 if (argc && argv) { 00640 object_attr_setvalueof(x, _sym_bgcolor, argc, argv); 00641 sysmem_freeptr(argv); 00642 } 00643 } 00644 } 00645 return jbox_notify((t_jbox *)x, s, msg, sender, data); 00646 }
Copyright © 2008, Cycling '74