11clicks Max Object
     

11clicks

Name: 11clicks
Version: 2015/02/17
Published: 2014/02/15
Type: C external for Max
OS: Windows, Mac OS X
Compatibility: Max 6 or 7

Simulate mouse input. Create clicks, cursor movement or wheel movement.

Like 11strokes this can be useful in combination with (midi) controller devices.

Example: One note on your midi keyboard is mapped to a mouse click. You can rest the mousecursor on prev/next preset button of a plugin, instrument etc. and step through presets without moving one hand to the mouse and back to the keyboard again and again. 

 

Screenshots:
11clicks.maxhelp
Installation:

Copy the files into your Max search path.

Changelog:

2015/02/07:

  • bugfix: setting cursor position now uses the correct virtual screen size

2015/02/17:

  • added Mac version
  • all methods are now called with messages sent to inlet 1
  • the cursor can be changed for the patcher or objects (only some standard icons)
Windows Version Source Code:

/** simulate mouse input  
11oLsen, 2014,2015
*/

#include "ext.h"							// standard Max include, always required
#include "ext_obex.h"                       // required for new style Max object
#include "jpatcher_api.h"
#include "windows.h"



////////////////////////// object struct
typedef struct _clicky 
{
	t_object					ob;			// the object itself (must be first)

	t_object	*w_patcher;
    t_object	*w_patcherview;

} t_clicky;

///////////////////////// function prototypes
//// standard set
void *clicky_new(t_symbol *s, long argc, t_atom *argv);
void clicky_free(t_clicky *x);
void clicky_assist(t_clicky *x, void *b, long m, long a, char *s);
void clicky_doubleclick(t_clicky *x);

void clicky_set(t_clicky *x, t_symbol *s, long argc, t_atom *argv);
void clicky_move(t_clicky *x, t_symbol *s, long argc, t_atom *argv);
void clicky_wheel(t_clicky *x, long n);
void clicky_hwheel(t_clicky *x, long n);
void clicky_leftclick(t_clicky *x, long n);
void clicky_rightclick(t_clicky *x, long n);
void clicky_cursor(t_clicky *x, t_symbol *s, long argc, t_atom *argv);
void clicky_init(t_clicky *x);

//////////////////////// global class pointer variable
void *clicky_class;


int C74_EXPORT main(void)
{	
	
	t_class *c;
	
	c = class_new("11clicks", (method)clicky_new, (method)clicky_free, (long)sizeof(t_clicky), 0L /* leave NULL!! */, A_GIMME, 0);
	
	/* you CAN'T call this from the patcher */
    class_addmethod(c, (method)clicky_assist,			"assist",		A_CANT, 0);  
	class_addmethod(c, (method)clicky_doubleclick,		"doubleclick",		0);
	
	class_addmethod(c, (method)clicky_set,		"set",		A_GIMME, 0);	// the method for an int in the left inlet (inlet 0)
    class_addmethod(c, (method)clicky_move,		"move",		A_GIMME, 0);	// the method for an int in the left inlet (inlet 0)
	class_addmethod(c, (method)clicky_wheel,	"wheel",	A_LONG, 0);	
	class_addmethod(c, (method)clicky_hwheel,	"hwheel",	A_LONG, 0);	
	class_addmethod(c, (method)clicky_cursor,	"cursor",	A_GIMME, 0);

	class_addmethod(c, (method)clicky_leftclick,		"leftclick",		A_LONG, 0);	// the method for an int in the right inlet (inlet 1)
	class_addmethod(c, (method)clicky_rightclick,		"rightclick",		A_LONG, 0);	// (inlet 2)

	class_register(CLASS_BOX, c); /* CLASS_NOBOX */
	clicky_class = c;
	common_symbols_init();

	
	return 0;
}

void clicky_doubleclick(t_clicky *x)
{
	INPUT inp[1];
	
		inp[0].type= INPUT_MOUSE;
		inp[0].mi.time = 0;

		inp[0].mi.dwFlags  = MOUSEEVENTF_LEFTDOWN;
		SendInput(1, inp, sizeof(INPUT));

		inp[0].mi.dwFlags  = MOUSEEVENTF_LEFTUP;
		SendInput(1, inp, sizeof(INPUT));

		inp[0].mi.dwFlags  = MOUSEEVENTF_LEFTDOWN;
		SendInput(1, inp, sizeof(INPUT));

		inp[0].mi.dwFlags  = MOUSEEVENTF_LEFTUP;
		SendInput(1, inp, sizeof(INPUT));
}



void clicky_leftclick(t_clicky *x, long n)	// x = the instance of the object; n = the int received in the left inlet 
{
	INPUT inp[1];
	if (n) 
	{
		inp[0].type= INPUT_MOUSE;
		inp[0].mi.dwFlags  = MOUSEEVENTF_LEFTDOWN;
		inp[0].mi.time = 0;
		SendInput(1, inp, sizeof(INPUT));
	} 
	else 
	{
		inp[0].type= INPUT_MOUSE;
		inp[0].mi.dwFlags  = MOUSEEVENTF_LEFTUP;
		inp[0].mi.time = 0;
		SendInput(1, inp, sizeof(INPUT));
	}
}



void clicky_rightclick(t_clicky *x, long n)	// x = the instance of the object, n = the int received in the right inlet 
{
	INPUT inp[1];
	if (n) 
	{
		inp[0].type= INPUT_MOUSE;
		inp[0].mi.dwFlags  = MOUSEEVENTF_RIGHTDOWN;
		inp[0].mi.time = 0;
		SendInput(1, inp, sizeof(INPUT));
	} 
	else 
	{
		inp[0].type= INPUT_MOUSE;
		inp[0].mi.dwFlags  = MOUSEEVENTF_RIGHTUP;
		inp[0].mi.time = 0;
		SendInput(1, inp, sizeof(INPUT));
	}
}


void clicky_set(t_clicky *x, t_symbol *s, long argc, t_atom *argv)
{
	long h; long v;
	double fScreenWidth; 
	double fScreenHeight; 
	double fx;
	double fy;
	INPUT inp[1];

	h = (atom_getlong(argv+0));
	v = atom_getlong(argv+1);
	fScreenWidth    = GetSystemMetrics( SM_CXVIRTUALSCREEN )-1; 
	fScreenHeight  = GetSystemMetrics( SM_CYVIRTUALSCREEN )-1; 
	fx = h*(65535.0f/fScreenWidth);
	fy = v*(65535.0f/fScreenHeight);
	
	inp[0].type      = INPUT_MOUSE;
	inp[0].mi.dwFlags  = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK;
	inp[0].mi.dx = fx;
	inp[0].mi.dy = fy;
	inp[0].mi.time = 0;
	SendInput(1, inp, sizeof(INPUT));
}



void clicky_move(t_clicky *x, t_symbol *s, long argc, t_atom *argv)
{
	long h; long v;

	INPUT inp[1];

	h = (atom_getlong(argv+0));
	v = atom_getlong(argv+1);

	
	inp[0].type      = INPUT_MOUSE;
	inp[0].mi.dwFlags  = MOUSEEVENTF_MOVE;
	inp[0].mi.dx = h;
	inp[0].mi.dy = v;
	inp[0].mi.time = 0;
	SendInput(1, inp, sizeof(INPUT));
}


void clicky_wheel(t_clicky *x, long n)
{
	
	INPUT inp[1];

	inp[0].type      = INPUT_MOUSE;
	inp[0].mi.dwFlags  = MOUSEEVENTF_WHEEL;
	inp[0].mi.mouseData = n;
	inp[0].mi.time = 0;
	SendInput(1, inp, sizeof(INPUT));
}

void clicky_hwheel(t_clicky *x, long n)
{
	
	INPUT inp[1];

	inp[0].type      = INPUT_MOUSE;
	inp[0].mi.dwFlags  = MOUSEEVENTF_HWHEEL;
	inp[0].mi.mouseData = n;
	inp[0].mi.time = 0;
	SendInput(1, inp, sizeof(INPUT));
}



////////////// CURSOR ///////////////////////////////////////////////
void clicky_cursor(t_clicky *x, t_symbol *s, long argc, t_atom *argv)
{
	
															/*typedef enum _jmouse_cursortype {
															JMOUSE_CURSOR_NONE, 						///< None
															JMOUSE_CURSOR_ARROW, 						///< Arrow
															JMOUSE_CURSOR_WAIT, 						///< Wait
															JMOUSE_CURSOR_IBEAM, 						///< I-Beam
															JMOUSE_CURSOR_CROSSHAIR, 					///< Crosshair
															JMOUSE_CURSOR_COPYING,						///< Copying
															JMOUSE_CURSOR_POINTINGHAND,					///< Pointing Hand
															JMOUSE_CURSOR_DRAGGINGHAND,					///< Dragging Hand
															JMOUSE_CURSOR_RESIZE_LEFTRIGHT,				///< Left-Right
															JMOUSE_CURSOR_RESIZE_UPDOWN,				///< Up-Down
															JMOUSE_CURSOR_RESIZE_FOURWAY,				///< Four Way
															JMOUSE_CURSOR_RESIZE_TOPEDGE,				///< Top Edge
															JMOUSE_CURSOR_RESIZE_BOTTOMEDGE,			///< Bottom Edge
															JMOUSE_CURSOR_RESIZE_LEFTEDGE,				///< Left Edge
															JMOUSE_CURSOR_RESIZE_RIGHTEDGE,				///< Right Edge
															JMOUSE_CURSOR_RESIZE_TOPLEFTCORNER,			///< Top-Left Corner
															JMOUSE_CURSOR_RESIZE_TOPRIGHTCORNER,		///< Top-Right Corner
															JMOUSE_CURSOR_RESIZE_BOTTOMLEFTCORNER,		///< Bottom-Left Corner
															JMOUSE_CURSOR_RESIZE_BOTTOMRIGHTCORNER		///< Bottom-Right Corner
														} t_jmouse_cursortype;*/ 


	t_object *jb;
	t_object *box;
	//t_rect jr;
	t_symbol *scriptingname;
	t_symbol *vname;
	long n;
	long i;
	
	jb = jpatcher_get_firstobject(x->w_patcher); // get the first BOX in the object list
    box = jpatcher_get_box(x->w_patcherview); // get box of firstview
	
	if  (!argc || !argv){object_post((t_object *)x, "missing arguments"); return;}
	
	if  (argc == 1) {               // apply to patcherview if only 1 arg
		n = atom_getlong(argv+0);		
		jmouse_setcursor (x->w_patcherview, box, n);
	
		object_method(x->w_patcher, _sym_refresh); //
		return;
	}

	//now the case of more than 1 arg
	if ((argv + 0)->a_type == A_LONG) {n = atom_getlong(argv+0);}
	else {object_post((t_object *)x, "first arg needs to be the cursor number 0-18");return;}
	
	if (atom_getsym(argv+1) == gensym("all")) // if second arg is "all", the defined cursor is applied to all objects in the patcher
	{
		while(jb) {
			jmouse_setcursor (x->w_patcherview, jb, n);
			jb = jbox_get_nextobject(jb);
		}
		object_method(x->w_patcher, _sym_refresh); return;
	}   
		
	for (i = 1; i < argc; i++) {			//for every argument starting with the second
		if ((argv + i)->a_type == A_SYM)		// if arg is a symbol
		{  
			vname = atom_getsym(argv+i); 
			jb = jpatcher_get_firstobject(x->w_patcher);	
			
	
			while(jb) {            // iterate to all objects in the patcher and apply cursor if name matches
		
				scriptingname = jbox_get_varname(jb);              // scripting name
				if (scriptingname  == vname)
				{
					jmouse_setcursor (x->w_patcherview, jb, n); 
		
				}	
			
				jb = jbox_get_nextobject(jb); 

			}// end while
	
	
		} else  {object_post((t_object *)x, "arg %ld is not a scripting-name", i+1);}       
	} // end for 
	// maybe upwards? jpatcher_get_parentpatcher(<#t_object * p#>)

	object_method(x->w_patcher, _sym_refresh);
}





void clicky_assist(t_clicky *x, void *b, long m, long a, char *s)
{
	//if (m==1) 
	//{ 	// Inlets
	//	switch (a) 
	//	{
	//		case 0: strcpy(s, "set [x y], move [x y], wheel [int], hwheel [int]"); break;
	//		case 1: strcpy(s, "int 1/0 - LEFT mousebutton press/release"); break;
	//		case 2: strcpy(s, "int 1/0 - RIGHT mousebutton press/release"); break;
	//	}
	//}
	;
}


void clicky_free(t_clicky *x)
{
	;
}



void *clicky_new(t_symbol *s, long argc, t_atom *argv)
{
	t_clicky *x = NULL;
    long i;
    
	if (x = (t_clicky *)object_alloc(clicky_class)) 
	{
        //intin(x,2);	 
		//intin(x,1);					// create a second int inlet (leftmost inlet is automatic - all objects have one inlet by default)

		object_post((t_object *)x, "by 11OLSEN, 2015-02-17", s->s_name);

		object_obex_lookup(x, _sym_pound_P, &x->w_patcher);   // assign w_patcher
		
		
		

		//object_post((t_object *)x, "a new %s object was instantiated: 0x%X", s->s_name, x);
        //object_post((t_object *)x, "it has %ld arguments", argc);
        
        /*for (i = 0; i < argc; i++) {
            if ((argv + i)->a_type == A_LONG) {
                object_post((t_object *)x, "arg %ld: long (%ld)", i, atom_getlong(argv+i));
            } else if ((argv + i)->a_type == A_FLOAT) {
                object_post((t_object *)x, "arg %ld: float (%f)", i, atom_getfloat(argv+i));
            } else if ((argv + i)->a_type == A_SYM) {
                object_post((t_object *)x, "arg %ld: symbol (%s)", i, atom_getsym(argv+i)->s_name);
            } else {
                object_error((t_object *)x, "forbidden argument");
            }
        }*/
		defer_low(x, (method)clicky_init, NULL, 0, NULL);
	}
	return (x);
}

void clicky_init(t_clicky *x)
{
    x->w_patcherview = object_attr_getobj(x->w_patcher, _sym_firstview); //get firstview object of w_patcher
}

Mac Version Source Code:
/** simulate mouse input  
11oLsen, 2014,2015
*/

#include "ext.h"							// standard Max include, always required
#include "ext_obex.h"						// required for new style Max object
#include "ApplicationServices/ApplicationServices.h"



////////////////////////// object struct
typedef struct _clicky 
{
	t_object					ob; // the object itself (must be first)
    t_object	*w_patcher;
    t_object	*w_patcherview;
} t_clicky;

///////////////////////// function prototypes
//// standard set
void *clicky_new(t_symbol *s, long argc, t_atom *argv);
void clicky_free(t_clicky *x);
void clicky_assist(t_clicky *x, void *b, long m, long a, char *s);
void clicky_doubleclick(t_clicky *x);

void clicky_set(t_clicky *x, t_symbol *s, long argc, t_atom *argv);
void clicky_move(t_clicky *x, t_symbol *s, long argc, t_atom *argv);
void clicky_wheel(t_clicky *x, long n);
void clicky_hwheel(t_clicky *x, long n);
void clicky_leftclick(t_clicky *x, long n);
void clicky_rightclick(t_clicky *x, long n);
void clicky_cursor(t_clicky *x, t_symbol *s, long argc, t_atom *argv);
void clicky_init(t_clicky *x);

//////////////////////// global class pointer variable
void *clicky_class;
CGEventTapLocation tapLocation;
CGEventSourceRef sourceRef;


int C74_EXPORT main(void)
{	
	// object initialization, OLD STYLE
	// setup((t_messlist **)&clicky_class, (method)clicky_new, (method)clicky_free, (short)sizeof(t_clicky), 
	//		0L, A_GIMME, 0);
    // addmess((method)clicky_assist,			"assist",		A_CANT, 0);  
	
	// object initialization, NEW STYLE
	t_class *c;
	
	c = class_new("11clicks", (method)clicky_new, (method)clicky_free, (long)sizeof(t_clicky), 0L /* leave NULL!! */, A_GIMME, 0);
	
	/* you CAN'T call this from the patcher */
    class_addmethod(c, (method)clicky_assist,			"assist",		A_CANT, 0);  
	class_addmethod(c, (method)clicky_doubleclick,		"doubleclick",		0);
	
	class_addmethod(c, (method)clicky_set,		"set",		A_GIMME, 0);	// the method for an int in the left inlet (inlet 0)
    class_addmethod(c, (method)clicky_move,		"move",		A_GIMME, 0);	// the method for an int in the left inlet (inlet 0)
	class_addmethod(c, (method)clicky_wheel,	"wheel",	A_LONG, 0);	
	class_addmethod(c, (method)clicky_hwheel,	"hwheel",	A_LONG, 0);
    class_addmethod(c, (method)clicky_cursor,	"cursor",	A_GIMME, 0);
	
	class_addmethod(c, (method)clicky_leftclick,		"leftclick",		A_LONG, 0);	// the method for an int in the right inlet (inlet 1)
	class_addmethod(c, (method)clicky_rightclick,		"rightclick",		A_LONG, 0);	// (inlet 2)

	class_register(CLASS_BOX, c); /* CLASS_NOBOX */
	clicky_class = c;

	//post("");
    tapLocation = kCGHIDEventTap; // used when specifying the tap location for CGEventPost
	sourceRef = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState);
    //CGEventSourceSetPixelsPerLine(sourceRef, 1.);
    common_symbols_init();
    
	return 0;
}

void clicky_doubleclick(t_clicky *x)
{
    // get the current mouse location
	CGEventRef mouseEvent = CGEventCreate(NULL);
	CGPoint mouseLoc = CGEventGetLocation(mouseEvent);
	CFRelease(mouseEvent);
	
	// NOTE: the first mouse down and mouse up are not really needed to perform a double click
	// I only do that because sometimes you have to click once to bring whatever you want to double-click to the front
	
	// first click mouse
	CGEventRef clickMouse = CGEventCreateMouseEvent(sourceRef, kCGEventLeftMouseDown, mouseLoc, 0);
	CGEventSetIntegerValueField(clickMouse, kCGMouseEventClickState, 1);
	CGEventPost(tapLocation, clickMouse);
	CFRelease(clickMouse);
	
	// first mouse up
	CGEventRef releaseMouse = CGEventCreateMouseEvent(sourceRef, kCGEventLeftMouseUp, mouseLoc, 0);
	CGEventSetIntegerValueField(releaseMouse, kCGMouseEventClickState, 1);
	CGEventPost(tapLocation, releaseMouse);
	CFRelease(releaseMouse);
	
	// second click mouse
	CGEventRef clickMouse2 = CGEventCreateMouseEvent(sourceRef, kCGEventLeftMouseDown, mouseLoc, 0);
	CGEventSetIntegerValueField(clickMouse2, kCGMouseEventClickState, 2);
	CGEventPost(tapLocation, clickMouse2);
	CFRelease(clickMouse2);
	
	// second mouse up
	CGEventRef releaseMouse2 = CGEventCreateMouseEvent(sourceRef, kCGEventLeftMouseUp, mouseLoc, 0);
	CGEventSetIntegerValueField(releaseMouse2, kCGMouseEventClickState, 2);
	CGEventPost(tapLocation, releaseMouse2);
	CFRelease(releaseMouse2);
}



void clicky_leftclick(t_clicky *x, long n)	// x = the instance of the object; n = the int received in the left inlet
{
	
	if (n) 
	{
		
        
            // get the current mouse location
            CGEventRef mouseEvent = CGEventCreate(NULL);
            CGPoint mouseLoc = CGEventGetLocation(mouseEvent);
          CFRelease(mouseEvent);
            
            // click mouse
            CGEventRef clickMouse = CGEventCreateMouseEvent(sourceRef, kCGEventLeftMouseDown, mouseLoc, 0);
            CGEventPost(tapLocation, clickMouse);
         CFRelease(clickMouse);// left-click at current mouse location but do not release the mouse
        
        
        
        
	} 
	else 
	{
		// get the current mouse location
        CGEventRef mouseEvent = CGEventCreate(NULL);
        CGPoint mouseLoc = CGEventGetLocation(mouseEvent);
     CFRelease(mouseEvent);
        
        // release mouse
        CGEventRef releaseMouse = CGEventCreateMouseEvent(sourceRef, kCGEventLeftMouseUp, mouseLoc, 0);
        CGEventPost(tapLocation, releaseMouse);
      CFRelease(releaseMouse);
	}
}





void clicky_rightclick(t_clicky *x, long n)	// x = the instance of the object, n = the int received in the right inlet
{

	if (n) 
	{
        // get the current mouse location
        CGEventRef mouseEvent = CGEventCreate(NULL);
        CGPoint mouseLoc = CGEventGetLocation(mouseEvent);
      CFRelease(mouseEvent);
        
        // click mouse
        CGEventRef clickMouse = CGEventCreateMouseEvent(sourceRef, kCGEventRightMouseDown, mouseLoc, 0);
        CGEventPost(tapLocation, clickMouse);
     CFRelease(clickMouse);// click at current mouse location but do not release the mouse
	}
	else
	{
		// get the current mouse location
        CGEventRef mouseEvent = CGEventCreate(NULL);
        CGPoint mouseLoc = CGEventGetLocation(mouseEvent);
      CFRelease(mouseEvent);
        
        // release mouse
        CGEventRef releaseMouse = CGEventCreateMouseEvent(sourceRef, kCGEventRightMouseUp, mouseLoc, 0);
        CGEventPost(tapLocation, releaseMouse);
     CFRelease(releaseMouse);
	}
}


void clicky_set(t_clicky *x, t_symbol *s, long argc, t_atom *argv)
{
	long h; long v;


	h = atom_getfloat(argv+0);
	v = atom_getfloat(argv+1);

        //CGWarpMouseCursorPosition(CGPointMake(h, v));
        CGEventRef moveMouse = CGEventCreateMouseEvent(sourceRef, kCGEventMouseMoved, CGPointMake(h, v), 0);
        CGEventPost(tapLocation, moveMouse);
        CFRelease(moveMouse);
        // mouse jumps directly from its current position to the new position and becomes visible, origin of CGPoint must be top-left

}



void clicky_move(t_clicky *x, t_symbol *s, long argc, t_atom *argv)
{
    long h; long v;
    
    
	h = atom_getfloat(argv+0);
	v = atom_getfloat(argv+1);
    
    // get the current mouse location
	CGEventRef mouseEvent = CGEventCreate(NULL);
	CGPoint currentLoc = CGEventGetLocation(mouseEvent);
	CFRelease(mouseEvent);

    
    //CGWarpMouseCursorPosition(CGPointMake(h, v));
    CGEventRef moveMouse = CGEventCreateMouseEvent(sourceRef, kCGEventMouseMoved, CGPointMake((currentLoc.x+h), (currentLoc.y+v)), 0);
    CGEventPost(tapLocation, moveMouse);
    CFRelease(moveMouse);

}


void clicky_wheel(t_clicky *x, long n)
{
    
    CGEventRef scrollWheel = CGEventCreateScrollWheelEvent(sourceRef, kCGScrollEventUnitPixel, 2, n, 0);
    CGEventPost(tapLocation, scrollWheel);
    CFRelease(scrollWheel);
}


void clicky_hwheel(t_clicky *x, long n)
{
    CGEventRef scrollWheel = CGEventCreateScrollWheelEvent(sourceRef, kCGScrollEventUnitPixel, 2, 0, n);
    CGEventPost(tapLocation, scrollWheel);
    CFRelease(scrollWheel);
}


////////////// CURSOR ///////////////////////////////////////////////
void clicky_cursor(t_clicky *x, t_symbol *s, long argc, t_atom *argv)
{
	
    /*typedef enum _jmouse_cursortype {
     JMOUSE_CURSOR_NONE, 						///< None
     JMOUSE_CURSOR_ARROW, 						///< Arrow
     JMOUSE_CURSOR_WAIT, 						///< Wait
     JMOUSE_CURSOR_IBEAM, 						///< I-Beam
     JMOUSE_CURSOR_CROSSHAIR, 					///< Crosshair
     JMOUSE_CURSOR_COPYING,						///< Copying
     JMOUSE_CURSOR_POINTINGHAND,					///< Pointing Hand
     JMOUSE_CURSOR_DRAGGINGHAND,					///< Dragging Hand
     JMOUSE_CURSOR_RESIZE_LEFTRIGHT,				///< Left-Right
     JMOUSE_CURSOR_RESIZE_UPDOWN,				///< Up-Down
     JMOUSE_CURSOR_RESIZE_FOURWAY,				///< Four Way
     JMOUSE_CURSOR_RESIZE_TOPEDGE,				///< Top Edge
     JMOUSE_CURSOR_RESIZE_BOTTOMEDGE,			///< Bottom Edge
     JMOUSE_CURSOR_RESIZE_LEFTEDGE,				///< Left Edge
     JMOUSE_CURSOR_RESIZE_RIGHTEDGE,				///< Right Edge
     JMOUSE_CURSOR_RESIZE_TOPLEFTCORNER,			///< Top-Left Corner
     JMOUSE_CURSOR_RESIZE_TOPRIGHTCORNER,		///< Top-Right Corner
     JMOUSE_CURSOR_RESIZE_BOTTOMLEFTCORNER,		///< Bottom-Left Corner
     JMOUSE_CURSOR_RESIZE_BOTTOMRIGHTCORNER		///< Bottom-Right Corner
     } t_jmouse_cursortype;*/
    
    
	t_object *jb;
	t_object *box;
	//t_rect jr;
	t_symbol *scriptingname;
	t_symbol *vname;
	long n;
	long i;
	
	jb = jpatcher_get_firstobject(x->w_patcher); // get the first BOX in the object list
    box = jpatcher_get_box(x->w_patcherview); // get box of firstview
	
	if  (!argc || !argv){object_post((t_object *)x, "missing arguments"); return;}
	
	if  (argc == 1) {               // apply to patcherview if only 1 arg
		n = atom_getlong(argv+0);
		jmouse_setcursor (x->w_patcherview, box, n);
        
		object_method(x->w_patcher, _sym_refresh); //
		return;
	}
    
	//now the case of more than 1 arg
	if ((argv + 0)->a_type == A_LONG) {n = atom_getlong(argv+0);}
	else {object_post((t_object *)x, "first arg needs to be the cursor number 0-18");return;}
	
	if (atom_getsym(argv+1) == gensym("all")) // if second arg is "all", the defined cursor is applied to all objects in the patcher
	{
		while(jb) {
			jmouse_setcursor (x->w_patcherview, jb, n);
			jb = jbox_get_nextobject(jb);
		}
		object_method(x->w_patcher, _sym_refresh); return;
	}
    
	for (i = 1; i < argc; i++) {			//for every argument starting with the second
		if ((argv + i)->a_type == A_SYM)		// if arg is a symbol
		{
			vname = atom_getsym(argv+i);
			jb = jpatcher_get_firstobject(x->w_patcher);
			
            
			while(jb) {            // iterate to all objects in the patcher and apply cursor if name matches
                
				scriptingname = jbox_get_varname(jb);              // scripting name
				if (scriptingname  == vname)
				{
					jmouse_setcursor (x->w_patcherview, jb, n);
                    
				}
                
				jb = jbox_get_nextobject(jb);
                
			}// end while
            
            
		} else  {object_post((t_object *)x, "arg %ld is not a scripting-name", i+1);}
	} // end for
	// maybe upwards? jpatcher_get_parentpatcher(<#t_object * p#>)
    
	object_method(x->w_patcher, _sym_refresh);
}




void clicky_assist(t_clicky *x, void *b, long m, long a, char *s)
{
//	if (m==1)
//	{ 	// Inlets
//		switch (a) 
//		{
//			case 0: strcpy(s, "set [x y], move [x y], wheel [int], hwheel [int]"); break;
//			case 1: strcpy(s, "int 1/0 - LEFT mousebutton press/release"); break;
//			case 2: strcpy(s, "int 1/0 - RIGHT mousebutton press/release"); break;
//		}
//	}
}


void clicky_free(t_clicky *x)
{
	;}




void *clicky_new(t_symbol *s, long argc, t_atom *argv)
{
	t_clicky *x = NULL;
    long i;
    
	if ((x = (t_clicky *)object_alloc(clicky_class))) 
	{
        //intin(x,2);
		//intin(x,1);					// create a second int inlet (leftmost inlet is automatic - all objects have one inlet by default)
		
		object_post((t_object *)x, "%s by 11OLSEN, 2015-02-17", s->s_name);
        
		object_obex_lookup(x, _sym_pound_P, &x->w_patcher);   // assign w_patcher
		
		
        
        for (i = 0; i < argc; i++) {
            if ((argv + i)->a_type == A_LONG) {
                object_post((t_object *)x, "arg %ld: long (%ld)", i, atom_getlong(argv+i));
            } else if ((argv + i)->a_type == A_FLOAT) {
                object_post((t_object *)x, "arg %ld: float (%f)", i, atom_getfloat(argv+i));
            } else if ((argv + i)->a_type == A_SYM) {
                object_post((t_object *)x, "arg %ld: symbol (%s)", i, atom_getsym(argv+i)->s_name);
            } else {
                object_error((t_object *)x, "forbidden argument");
            }
        }
        defer_low(x, (method)clicky_init, NULL, 0, NULL);
	}
    
	return (x);
}


void clicky_init(t_clicky *x)
{
    x->w_patcherview = object_attr_getobj(x->w_patcher, _sym_firstview); //get firstview object of w_patcher
}



Files:

11clicks.maxhelp

11clicks.mxe

11clicks.mxe64

11clicks.mxo

 30.92 KB
 


Category: Max Objects

Comments   

Bernhard
0 # Bernhard wrote on Monday, 16 January 2017 21:36
wonderful!!! that what I´m looking for so long!
I´ve insertet it into a Max4live patcher.
Look here:
http://www.maxforlive.com/library/device/3962/automatet-mouseclick

Thak You 11olsen!!!!!!!!!!!
steve
0 # steve wrote on Friday, 06 February 2015 22:33
genius

Add comment


Security code
Refresh