//----------------------------------------------------------------------------------- static void DoTheTracking(EventRef inEvent, MTViewData* data) { MouseTrackingResult mouseResult; ControlPartCode part; Point qdPt; HIPoint where; // Extract the mouse location (local coordinates!) GetEventParameter(inEvent, kEventParamMouseLocation, typeHIPoint, NULL, sizeof(HIPoint), NULL, &where); CGAffineTransform m = CGAffineTransformIdentity; // Reset the path if (data->thePath != NULL) CGPathRelease(data->thePath); data->thePath = CGPathCreateMutable(); #if CG_COORDINATES where.y = FlipHIViewYCoordinate(data->theView, where.y); #endif CGPathMoveToPoint(data->thePath, &m, where.x, where.y); // fprintf(stderr, "StartPt: (%g, %g\n", where.x, where.y); while (true) { // Watch the mouse for change: qdPt comes back in global coordinates! TrackMouseLocation((GrafPtr)(-1), &qdPt, &mouseResult); // Bail out when the mouse is released if ( mouseResult == kMouseTrackingMouseReleased ) { HIViewSetNeedsDisplay(data->theView, true); break; } // Need to convert from global where = QDGlobalToHIViewLocal(qdPt, data->theView); #if CG_COORDINATES where.y = FlipHIViewYCoordinate(data->theView, where.y); #endif CGPathAddLineToPoint(data->thePath, &m, where.x, where.y); // fprintf(stderr, "TrackPt: (%g, %g\n", where.x, where.y); part = 0; SetEventParameter(inEvent, kEventParamControlPart, typeControlPartCode, sizeof(ControlPartCode), &part); HIViewSetNeedsDisplay(data->theView, true); } // Send back the part upon which the mouse was released part = kControlEntireControl; SetEventParameter(inEvent, kEventParamControlPart, typeControlPartCode, sizeof(ControlPartCode), &part); }
void change_model_wind(Point start_pt) { int old_shift_x,old_shift_y,old_magnify_z; float old_ang_y,old_ang_x; Point pt,last_pt; MouseTrackingResult track; // rotate the model last_pt.h=last_pt.v=-1; old_shift_x=shift_x; old_shift_y=shift_y; old_ang_y=ang_y; old_ang_x=ang_x; old_magnify_z=magnify_z; do { TrackMouseLocation(NULL,&pt,&track); model_wind_offset_click(&pt); if (memcmp(&last_pt,&pt,sizeof(Point))==0) continue; memmove(&last_pt,&pt,sizeof(Point)); if (shift_on) { shift_x=old_shift_x+((last_pt.h-start_pt.h)*4); shift_y=old_shift_y-((last_pt.v-start_pt.v)*4); } if (rotate_on) { ang_y=old_ang_y+(float)((last_pt.h-start_pt.h)/5); ang_x=old_ang_x-(float)((last_pt.v-start_pt.v)/5); } if (size_on) { magnify_z=old_magnify_z+((last_pt.v-start_pt.v)*2); } if (!play_animate) draw_model_wind_pose(&model,cur_mesh,cur_pose); } while (track!=kMouseTrackingMouseReleased); if (!play_animate) draw_model_wind_pose(&model,cur_mesh,cur_pose); }
// ----------------------------------------------------------------------------- // HITestViewTrack // ----------------------------------------------------------------------------- // This is overkill, and probably #ifdef'd out, but is here as an example of // a custom tracking handler. // OSStatus HITestViewTrack( EventRef inEvent, HITestViewData* inData ) { OSStatus err; HIRect bounds; HIPoint where; ControlPartCode part; Boolean inside; Boolean wasInside; Point qdPt; MouseTrackingResult mouseResult; PixMapHandle portPixMap; // Extract the mouse location err = GetEventParameter( inEvent, kEventParamMouseLocation, typeHIPoint, NULL, sizeof( HIPoint ), NULL, &where ); require_noerr( err, ParameterMissing ); // Is the mouse location in the view? err = HIViewGetBounds( inData->view, &bounds ); if ( CGRectContainsPoint( bounds, where ) ) part = 1; else part = kControlNoPart; HiliteControl( inData->view, part ); wasInside = true; // Need the port's pixMap's bounds to convert the mouse location portPixMap = GetPortPixMap( GetWindowPort( GetControlOwner( inData->view ) ) ); // The tracking loop while ( true ) { // Check again to see if the mouse is in the view if ( CGRectContainsPoint( bounds, where ) ) part = 1; else part = kControlNoPart; inside = ( part != kControlNoPart ); // If that changed, update if ( inside != wasInside ) HiliteControl( inData->view, part ); wasInside = inside; // Watch the mouse for change err = TrackMouseLocation( (GrafPtr)-1L, &qdPt, &mouseResult ); // Need to convert from global QDGlobalToLocalPoint( GetWindowPort( GetControlOwner( inData->view ) ), &qdPt ); where.x = qdPt.h - (**portPixMap).bounds.left; where.y = qdPt.v - (**portPixMap).bounds.top; HIViewConvertPoint( &where, NULL, inData->view ); // Bail out when the mouse is released if ( mouseResult == kMouseTrackingMouseReleased ) break; } // Restore the original highlight HiliteControl( inData->view, kControlNoPart ); // Send back the part upon which the mouse was released err = SetEventParameter( inEvent, kEventParamControlPart, typeControlPartCode, sizeof( ControlPartCode ), &part ); ParameterMissing: return err; }
static pascal OSStatus CustomSpotViewHandler(EventHandlerCallRef inCaller, EventRef inEvent, void* inRefcon) { OSStatus result = eventNotHandledErr; CustomSpotViewData* myData = (CustomSpotViewData*)inRefcon; switch (GetEventClass(inEvent)) { case kEventClassHIObject: switch (GetEventKind(inEvent)) { case kEventHIObjectConstruct: { myData = (CustomSpotViewData*) calloc(1, sizeof(CustomSpotViewData)); GetEventParameter(inEvent, kEventParamHIObjectInstance, typeHIObjectRef, NULL, sizeof(myData->view), NULL, &myData->view); result = SetEventParameter(inEvent, kEventParamHIObjectInstance, typeVoidPtr, sizeof(myData), &myData); break; } case kEventHIObjectInitialize: { HIRect bounds; GetEventParameter(inEvent, kEventParamBounds, typeHIRect, NULL, sizeof(bounds), NULL, &bounds); myData->spot.x = CGRectGetMidX(bounds) - CGRectGetMinX(bounds); myData->spot.y = CGRectGetMidY(bounds) - CGRectGetMinY(bounds); HIViewSetVisible(myData->view, true); break; } case kEventHIObjectDestruct: { free(myData); result = noErr; break; } default: break; } break; case kEventClassControl: switch (GetEventKind(inEvent)) { case kEventControlDraw: { CGContextRef context; HIRect bounds; result = GetEventParameter(inEvent, kEventParamCGContextRef, typeCGContextRef, NULL, sizeof(context), NULL, &context); HIViewGetBounds(myData->view, &bounds); if (!IsControlActive(myData->view)) { CGContextSetGrayStrokeColor(context, 0.5, 0.3); CGContextSetGrayFillColor(context, 0.5, 0.3); } else { CGContextSetRGBStrokeColor(context, 0.0, 0.0, 0.0, 0.7); CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 0.7); } CGContextSetLineWidth(context, 3.0); CGContextStrokeRect(context, bounds); HIRect spot = { {myData->spot.x - 4.0, myData->spot.y - 4.0}, {8.0, 8.0} }; CGContextFillRect(context, spot); result = noErr; break; } case kEventControlBoundsChanged: { HIRect newHIBounds; GetEventParameter(inEvent, kEventParamCurrentBounds, typeHIRect, NULL, sizeof(newHIBounds), NULL, &newHIBounds); myData->spot.x = CGRectGetMidX(newHIBounds) - CGRectGetMinX(newHIBounds); myData->spot.y = CGRectGetMidY(newHIBounds) - CGRectGetMinY(newHIBounds); break; } case kEventControlHitTest: { HIPoint pt; HIRect bounds; GetEventParameter(inEvent, kEventParamMouseLocation, typeHIPoint, NULL, sizeof(pt), NULL, &pt); HIViewGetBounds(myData->view, &bounds); ControlPartCode part = (CGRectContainsPoint(bounds, pt))?kControlButtonPart:kControlNoPart; result = SetEventParameter(inEvent, kEventParamControlPart, typeControlPartCode, sizeof(part), &part); break; } case kEventControlTrack: { Point qdPoint; Rect qdWindowBounds; HIPoint hiPoint; HIRect hiViewBounds; MouseTrackingResult mouseStatus = kMouseTrackingMouseDown; HIViewGetBounds(myData->view, &hiViewBounds); GetWindowBounds(GetControlOwner(myData->view), kWindowStructureRgn, &qdWindowBounds); // handle the first mouseDown before moving GetEventParameter(inEvent, kEventParamMouseLocation, typeHIPoint, NULL, sizeof(hiPoint), NULL, &hiPoint); while (mouseStatus != kMouseTrackingMouseUp) { if (CGRectContainsPoint(hiViewBounds, hiPoint)) { if (hiPoint.x < hiViewBounds.origin.x+4) hiPoint.x = hiViewBounds.origin.x+4; if (hiPoint.x > hiViewBounds.origin.x+hiViewBounds.size.width-4) hiPoint.x = hiViewBounds.origin.x+hiViewBounds.size.width-4; if (hiPoint.y < hiViewBounds.origin.y+4) hiPoint.y = hiViewBounds.origin.y+4; if (hiPoint.y > hiViewBounds.origin.y+hiViewBounds.size.height-4) hiPoint.y = hiViewBounds.origin.y+hiViewBounds.size.height-4; myData->spot = hiPoint; HIViewSetNeedsDisplay(myData->view, true); } // a -1 GrafPtr to TrackMouseLocation yields global coordinates TrackMouseLocation((GrafPtr)-1L, &qdPoint, &mouseStatus); // convert to window-relative coordinates hiPoint.x = qdPoint.h - qdWindowBounds.left; hiPoint.y = qdPoint.v - qdWindowBounds.top; // convert to view-relative coordinates HIViewConvertPoint(&hiPoint, NULL, myData->view); } break; } default: break; } break; default: break; } return result; }
// ----------------------------------------------------------------------------- int screen_coord_mousepos(Point *pt) { MouseTrackingResult trackingRes; OSStatus err = TrackMouseLocation(NULL, pt, &trackingRes); return err; }
void LineTool( WindowRef window ) { OSStatus err; Point endPt; MouseTrackingResult trackingResult; Point beginPt; Rect windowRect; WindowRef overlayWindow; CGRect cgRect; CGContextRef cgContext; Boolean isStillDown = true; SetThemeCursor( kThemeCrossCursor ); SetPortWindowPort( window ); GetWindowPortBounds( window, &windowRect ); LocalToGlobalRect( &windowRect ); (void) CreateNewWindow( kOverlayWindowClass, kWindowHideOnSuspendAttribute | kWindowIgnoreClicksAttribute, &windowRect, &overlayWindow ); SetPortWindowPort( overlayWindow ); SetWindowGroup( overlayWindow, GetWindowGroup(window) ); // This assures we draw into the same layer as the window ShowWindow( overlayWindow ); GetMouse( &beginPt ); cgRect = CGRectMake( 0, 0, windowRect.right - windowRect.left+1, windowRect.bottom - windowRect.top+1 ); CreateCGContextForPort( GetWindowPort(overlayWindow), &cgContext ); CGContextSetLineWidth( cgContext, 3 ); // Line is 3 pixels wide CGContextSetRGBStrokeColor( cgContext, 1.0, .45, .3, .4 ); // Make it orange with alpha = 0.4 SyncCGContextOriginWithPort( cgContext, GetWindowPort(overlayWindow) ); CGContextTranslateCTM( cgContext, 0, windowRect.bottom - windowRect.top ); // Flip & rotate the context to use QD coordinates CGContextScaleCTM( cgContext, 1.0, -1.0 ); do { err = TrackMouseLocation( GetWindowPort(window), &endPt, &trackingResult ); switch ( trackingResult ) { case kMouseTrackingMouseDragged: CGContextClearRect( cgContext, cgRect ); // "Erase" the window #if ( 1 ) CGContextMoveToPoint( cgContext, beginPt.h, beginPt.v ); // Draw the line CGContextAddLineToPoint( cgContext, endPt.h, endPt.v ); CGContextStrokePath( cgContext ); #else MoveTo( beginPt.h, beginPt.v ); // We could use QuickDraw and draw opaque lines LineTo( endPt.h, endPt.v ); #endif CGContextFlush( cgContext ); // Flush our drawing to the screen break; case kMouseTrackingMouseDown: break; case kMouseTrackingMouseUp: case kMouseTrackingUserCancelled: isStillDown = false; break; } } while( isStillDown == true ); CGContextRelease( cgContext ); DisposeWindow( overlayWindow ); SetThemeCursor( kThemeArrowCursor ); return; }
bool drag_bone_model_wind(Point start_pt) { int n,k,drag_handle; float x,y,z,hx,hy,hz,org_ang,org_mov, bone_drag_handle_offset; float *ang,*mov; Point pt,last_pt; d3vct vct; d3ang hang,rot; model_draw_bone_type *draw_bone; MouseTrackingResult track; model_wind_play(FALSE,FALSE); // setup the draw pose draw_model_setup_pose(&model,&draw_setup,cur_pose); model_create_draw_bones(&model,&draw_setup); // setup transforms draw_model_gl_setup(&model); // click on any drag handles? drag_handle=drag_handle_none; if ((cur_pose==-1) || (cur_bone!=-1)) { draw_bone=&draw_setup.bones[cur_bone]; x=draw_bone->fpnt.x+draw_setup.move.x; y=draw_bone->fpnt.y+draw_setup.move.y; z=draw_bone->fpnt.z+draw_setup.move.z; bone_drag_handle_offset=draw_model_bones_drag_handle_offset(&model); draw_model_bones_get_handle_rot(&model,&draw_setup,cur_bone,&rot); // x drag bone vct.x=bone_drag_handle_offset; vct.y=0; vct.z=0; hang.x=0; hang.y=rot.y; hang.z=rot.z; draw_model_bones_drag_handle_calc(x,y,z,&vct,&hang,&hx,&hy,&hz); if (draw_bone_model_wind_click_box(start_pt,hx,hy,hz)) drag_handle=drag_handle_x; // y drag bone vct.x=0; vct.y=bone_drag_handle_offset; vct.z=0; hang.x=rot.x; hang.y=0; hang.z=rot.z; draw_model_bones_drag_handle_calc(x,y,z,&vct,&hang,&hx,&hy,&hz); if (draw_bone_model_wind_click_box(start_pt,hx,hy,hz)) drag_handle=drag_handle_y; // z drag bone vct.x=0; vct.y=0; vct.z=bone_drag_handle_offset; hang.x=rot.x; hang.y=rot.y; hang.z=0; draw_model_bones_drag_handle_calc(x,y,z,&vct,&hang,&hx,&hy,&hz); if (draw_bone_model_wind_click_box(start_pt,hx,hy,hz)) drag_handle=drag_handle_z; } // click on any bones? if (drag_handle==drag_handle_none) { k=-1; draw_bone=draw_setup.bones; for (n=0;n!=model.nbone;n++) { x=draw_bone->fpnt.x+draw_setup.move.x; y=draw_bone->fpnt.y+draw_setup.move.y; z=draw_bone->fpnt.z+draw_setup.move.z; if (draw_bone_model_wind_click_box(start_pt,x,y,z)) { k=n; break; } draw_bone++; } if (k==-1) return(FALSE); // select as current bone cur_bone=k; reset_bone_list(); draw_model_wind_pose(&model,cur_mesh,cur_pose); return(TRUE); } // get drag angle switch (drag_handle) { case drag_handle_x: ang=&model.poses[cur_pose].bone_moves[cur_bone].rot.x; mov=&model.poses[cur_pose].bone_moves[cur_bone].mov.x; break; case drag_handle_y: ang=&model.poses[cur_pose].bone_moves[cur_bone].rot.y; mov=&model.poses[cur_pose].bone_moves[cur_bone].mov.y; break; case drag_handle_z: ang=&model.poses[cur_pose].bone_moves[cur_bone].rot.z; mov=&model.poses[cur_pose].bone_moves[cur_bone].mov.z; break; default: return(TRUE); } reset_bone_list(); // drag bone org_ang=*ang; org_mov=*mov; last_pt.h=last_pt.v=-1; undo_set_bone_move(cur_pose,cur_bone); SetCCursor(bone_drag_cursor); do { TrackMouseLocation(NULL,&pt,&track); model_wind_offset_click(&pt); if (memcmp(&last_pt,&pt,sizeof(Point))==0) continue; memmove(&last_pt,&pt,sizeof(Point)); x=pt.h-start_pt.h; if (x<-180) x=-180; if (x>180) x=180; if (drag_bone_mode==drag_bone_mode_rotate) { *ang=org_ang+(((float)x)/2.0f); } else { *mov=org_mov+(((float)x)/20.0f); } // draw the model model_bone_drag_on=TRUE; draw_model_wind_pose(&model,cur_mesh,cur_pose); model_bone_drag_on=FALSE; reset_bone_list(); redraw_bone_list(); } while (track!=kMouseTrackingMouseReleased); InitCursor(); // redraw model draw_model_wind_pose(&model,cur_mesh,cur_pose); return(TRUE); }
void select_model_wind(Point start_pt,unsigned long modifiers) { int lx,rx,ty,by,sz; double mod_matrix[16],proj_matrix[16],vport[4]; char org_vertex_sel[max_model_vertex]; bool chg_sel; float *pv; Point pt,last_pt; MouseTrackingResult track; model_wind_play(FALSE,FALSE); // get the draw vertexes // need to save off array as drawing will reuse // array and free it model_draw_setup_initialize(&model,&draw_setup,TRUE); draw_model_setup_pose(&model,&draw_setup,cur_pose); model_create_draw_bones(&model,&draw_setup); model_create_draw_vertexes(&model,cur_mesh,&draw_setup); sz=(model.meshes[cur_mesh].nvertex*3)*sizeof(float); pv=(float*)malloc(sz); if (pv==NULL) return; memmove(pv,draw_setup.mesh_arrays[cur_mesh].gl_vertex_array,sz); model_draw_setup_shutdown(&model,&draw_setup); // setup transforms draw_model_gl_setup(&model); glGetDoublev(GL_MODELVIEW_MATRIX,mod_matrix); glGetDoublev(GL_PROJECTION_MATRIX,proj_matrix); glGetIntegerv(GL_VIEWPORT,(GLint*)vport); // turn on or off? if ((modifiers&shiftKey)!=0) { select_model_wind_save_sel_state(org_vertex_sel); SetCCursor(add_cursor); chg_sel=TRUE; } else { if ((modifiers&controlKey)!=0) { select_model_wind_save_sel_state(org_vertex_sel); SetCCursor(sub_cursor); chg_sel=FALSE; } else { memset(org_vertex_sel,0x0,max_model_vertex); InitCursor(); chg_sel=TRUE; } } // drag the selection last_pt.h=last_pt.v=-1; drag_sel_on=TRUE; do { TrackMouseLocation(NULL,&pt,&track); model_wind_offset_click(&pt); if (memcmp(&last_pt,&pt,sizeof(Point))==0) continue; memmove(&last_pt,&pt,sizeof(Point)); if (start_pt.h<last_pt.h) { lx=start_pt.h; rx=last_pt.h; } else { rx=start_pt.h; lx=last_pt.h; } if (start_pt.v<last_pt.v) { ty=start_pt.v; by=last_pt.v; } else { by=start_pt.v; ty=last_pt.v; } select_model_wind_restore_sel_state(org_vertex_sel); model_sel_vertex(pv,lx,ty,rx,by,chg_sel,mod_matrix,proj_matrix,vport); SetRect(&drag_sel_box,lx,ty,rx,by); draw_model_wind_pose(&model,cur_mesh,cur_pose); } while (track!=kMouseTrackingMouseReleased); drag_sel_on=FALSE; free(pv); // redraw the model draw_model_wind_pose(&model,cur_mesh,cur_pose); // reset the data browser hilite_vertex_rows(); InitCursor(); }