void doRotatedEllipses(CGContextRef context)
{
	int i, totreps = 144;
	float  tint = 1.0, tintIncrement = 1.0/totreps;
	// Create a new transform consisting of a 45 degrees rotation.
	CGAffineTransform theTransform = CGAffineTransformMakeRotation(M_PI/4);
	// Apply a scale to the transform just created.
	theTransform = CGAffineTransformScale(theTransform, 1, 2);
	// Place the first ellipse at a good location.
	CGContextTranslateCTM(context, 100., 100.);
	
	for(i=0 ; i < totreps ; i++){
		// Make a snapshot the coordinate system.
		CGContextSaveGState(context);
			// Set up the coordinate system for the rotated ellipse.
			CGContextConcatCTM(context, theTransform);
			CGContextBeginPath(context);
			CGContextAddArc(context, 0., 0., 45., 0., 2*M_PI, 0); 
			// Set the fill color for this instance of the ellipse.
			CGContextSetRGBFillColor(context, tint, 0., 0., 1.0);
			CGContextDrawPath(context, kCGPathFill);
		// Restore the coordinate system to that of the snapshot.
		CGContextRestoreGState(context);
		// Compute the next tint color.
		tint -= tintIncrement;
		// Move over by 1 unit in x for the next ellipse.
		CGContextTranslateCTM(context, 1.0, 0.0);
	}
}
Exemple #2
0
CGPoint CGPointRotateAround(CGPoint point, CGPoint pivot, CGFloat angle)
{
    CGPoint result = CGPointApplyAffineTransform(CGPointSubtract(point, pivot),
                                                 CGAffineTransformMakeRotation(angle));
    result = CGPointAdd(result, pivot);
    
    return result;
}
CGPoint CGPointRotatedAroundPoint(CGPoint point, CGPoint pivot, CGFloat degrees)
{
    CGAffineTransform translation, rotation;
	translation	= CGAffineTransformMakeTranslation(-pivot.x, -pivot.y);
	point		= CGPointApplyAffineTransform(point, translation);
	rotation	= CGAffineTransformMakeRotation(degrees * M_PI/180.0);
	point		= CGPointApplyAffineTransform(point, rotation);
	translation	= CGAffineTransformMakeTranslation(pivot.x, pivot.y);
	point		= CGPointApplyAffineTransform(point, translation);
	return point;
}
void doRotatedEllipsesWithCGPath(CGContextRef context)
{
	int i, totreps = 144.;
	CGMutablePathRef path = NULL;
	float  tint = 1., tintIncrement = 1./totreps;
	// Create a new transform consisting of a 45 degree rotation.
	CGAffineTransform theTransform = CGAffineTransformMakeRotation(M_PI/4);
	// Apply a scaling transformation to the transform just created.
	theTransform = CGAffineTransformScale(theTransform, 1, 2);
	// Create a mutable CGPath object.
	path = CGPathCreateMutable();
	if(!path){
		fprintf(stderr, "Couldn't create path!\n");
		return;
	}
	// Add a circular arc to the CGPath object, transformed
	// by an affine transform.
	CGPathAddArc(path, &theTransform, 0., 0., 45., 0., 2*M_PI, false); 
	// Close the CGPath object.
	CGPathCloseSubpath(path);
	
	// Place the first ellipse at a good location.	
	CGContextTranslateCTM(context, 100., 100.);
	for (i = 0 ; i < totreps ; i++){
		CGContextBeginPath(context);
		// Add the CGPath object to the current path in the context.
		CGContextAddPath(context, path);
		
		// Set the fill color for this instance of the ellipse.
		CGContextSetRGBFillColor(context, tint, 0., 0., 1.);
		// Filling the path implicitly closes it.
		CGContextFillPath(context);
		// Compute the next tint color.
		tint -= tintIncrement;
		// Move over for the next ellipse.
		CGContextTranslateCTM(context, 1, 0.);
	}
	// Release the path when done with it.
	CGPathRelease(path);
}
CGAffineTransform CGAffineTransformRotate(CGAffineTransform T,CGFloat angle) {
    return CGAffineTransformConcat(T,CGAffineTransformMakeRotation(angle));
}
/*
	Event handler for the content view that gets attached to the menu frame.

	The content view will (eventually) contain the menu view.
*/
OSStatus ContentViewEventHandler(
	EventHandlerCallRef inCallRef,
	EventRef inEvent,
	void *refcon)
{
	OSStatus retVal = eventNotHandledErr;
	if(GetEventClass(inEvent) == kEventClassMenu) {
		return noErr;
	} else
	if(GetEventClass(inEvent) == kEventClassControl) {
		HIViewRef hiSelf = NULL;
		verify_noerr(GetEventParameter(inEvent, kEventParamDirectObject, typeControlRef, NULL, sizeof(hiSelf), NULL, &hiSelf));

		if(hiSelf) {
			HIRect frame;
			HIViewGetFrame(hiSelf, &frame);

			switch(GetEventKind(inEvent)) {
				case kEventControlAddedSubControl : {
					HIViewRef subControl;
					ControlID subControlID;

					GetEventParameter(inEvent, kEventParamControlSubControl, typeControlRef, NULL, sizeof(subControl), NULL, &subControl );
					GetControlID(subControl, &subControlID);

					// This should be comparing against kHIViewMenuContentID as shown inside the
					// #if 0. At the time of this writing, however, using that constant causes a
					// linker error (and a crash if you use ZeroLink).  I extracted the signature
					// and id by determining the value at run-time the value I compare against.
#if 0
					if( kHIViewMenuContentID.signature == subControlID.signature && kHIViewMenuContentID.id == subControlID.id ) {
#else
					if( 'menu' == subControlID.signature && 0 == subControlID.id ) {
#endif
						// If we have the menu content view then set up some view bindings for it.
						HIRect bounds;
						HIViewGetBounds(hiSelf, &bounds);
						HIViewSetFrame(subControl, &bounds);

						HILayoutInfo contentLayout = {
							kHILayoutInfoVersionZero,
							{
								{ NULL, kHILayoutBindTop },
								{ NULL, kHILayoutBindLeft },
								{ NULL, kHILayoutBindBottom },
								{ NULL, kHILayoutBindRight }
							},
							{
								{ NULL, kHILayoutScaleAbsolute, 0 },
								{ NULL, kHILayoutScaleAbsolute, 0 }
							},
							{
								{ NULL, kHILayoutPositionTop, 0 },
								{ NULL, kHILayoutPositionLeft, 0 }
							}
						};

						verify_noerr(HIViewSetLayoutInfo(subControl, &contentLayout));
					}

					retVal = noErr;
				} break;

				case kEventControlGetFrameMetrics :
					HIViewFrameMetrics metrics;

					// The offset from the frame view to the content view is 
					// given by the kFrameOffset constant
					metrics.top = kFrameOffset;
					metrics.left = kFrameOffset;
					metrics.right = kFrameOffset;
					metrics.bottom = kFrameOffset;

					verify_noerr(SetEventParameter(inEvent, kEventParamControlFrameMetrics, typeControlFrameMetrics, sizeof(metrics), &metrics));

					retVal = noErr;
				break;

				case kEventControlBoundsChanged :
				case kEventControlOwningWindowChanged : {
					// Maintain the QuickDraw port by changing its position to
					// match that of the content view.
					CGrafPtr windowPort = NULL;
					WindowRef window = GetControlOwner(hiSelf);

					if(window && (windowPort = GetWindowPort(window))) {
						CGrafPtr savePort;
						bool swapped = QDSwapPort(windowPort, &savePort);

						MovePortTo((short) frame.origin.x, (short) frame.origin.y);
						PortSize((short) frame.size.width, (short) frame.size.height);

						if(swapped) {
							QDSwapPort(savePort, NULL);
						}
					}

					retVal = noErr;
				} break;
			} // switch
		} // if (hiSelf)
	}

	return retVal;
}


/* ------------------------------------------ CreatePathForEntireStarMenu */
/*
	Create a path shape for the star frame.
	
	This looks an awful lot like CreatePathForEntireStarMenu in
	StarMenu.cpp but takes the radius to use as a parameter and
	then takes into account the kFrameOffest when creating the path.

	In true Core Foundation style, this is a CreateXXX routine and the
	caller is responsible for freeing the path that is returned.
*/
CGPathRef CreatePathForStarFrame(StarFrameData *menuData, float radius)
{
   CGMutablePathRef retVal = CGPathCreateMutable();
   MenuItemIndex numItems = CountMenuItems(menuData->menu);

   if(numItems > 0) {
	  const CGPoint fullRadiusPoint = { radius, 0 };
	  const CGPoint halfRadiusPoint = { ((radius - kFrameOffset) / 2.0) + kFrameOffset , 0 };

	  float   anglePerItem = 2 * pi / (float)numItems;   // in radians naturally
	  float   halfAngle = anglePerItem / 2.0;

	  CGPoint startPoint = halfRadiusPoint;
	  CGAffineTransform midRotate = CGAffineTransformMakeRotation(halfAngle);
	  CGPoint midPoint = CGPointApplyAffineTransform(fullRadiusPoint, midRotate);

	  CGAffineTransform rotateToNext = CGAffineTransformMakeRotation(anglePerItem);

	  CGPathMoveToPoint(retVal, NULL, startPoint.x, startPoint.y);
	  CGPathAddLineToPoint(retVal, NULL, midPoint.x, midPoint.y);

	  for(short ctr = 0; ctr < numItems; ctr++) {
		 startPoint = CGPointApplyAffineTransform(startPoint, rotateToNext);
		 midPoint = CGPointApplyAffineTransform(midPoint, rotateToNext);

		 CGPathAddLineToPoint(retVal, NULL, startPoint.x, startPoint.y);
		 CGPathAddLineToPoint(retVal, NULL, midPoint.x, midPoint.y);
	  }

	  CGPathCloseSubpath(retVal);
   }

   return retVal;
}