IPopupMenu* IGraphicsCarbon::CreateIPopupMenu(IPopupMenu* pMenu, IRECT* pAreaRect)
{
  // Get the plugin gui frame rect within the host's window
  HIRect rct;
  HIViewGetFrame(this->mView, &rct);

  // Get the host's window rect within the screen
  Rect wrct;
  GetWindowBounds(this->mWindow, kWindowContentRgn, &wrct);

  #ifdef RTAS_API
  int xpos = wrct.left + this->GetLeftOffset() + pAreaRect->L;
  int ypos = wrct.top + this->GetTopOffset() + pAreaRect->B + 5;
  #else
  HIViewRef contentView;
  HIViewFindByID(HIViewGetRoot(this->mWindow), kHIViewWindowContentID, &contentView);
  HIViewConvertRect(&rct, HIViewGetSuperview((HIViewRef)this->mView), contentView);

  int xpos = wrct.left + rct.origin.x + pAreaRect->L;
  int ypos = wrct.top + rct.origin.y + pAreaRect->B + 5;
  #endif

  MenuRef menuRef = CreateMenu(pMenu);

  if (menuRef)
  {
    int32_t popUpItem = 1;
    int32_t PopUpMenuItem = PopUpMenuSelect(menuRef, ypos, xpos, popUpItem);

    short result = LoWord(PopUpMenuItem) - 1;
    short menuIDResult = HiWord(PopUpMenuItem);
    IPopupMenu* resultMenu = 0;

    if (menuIDResult != 0)
    {
      MenuRef usedMenuRef = GetMenuHandle(menuIDResult);

      if (usedMenuRef)
      {
        if (GetMenuItemRefCon(usedMenuRef, 0, (URefCon*)&resultMenu) == noErr)
        {
          resultMenu->SetChosenItemIdx(result);
        }
      }
    }

    CFRelease(menuRef);

    return resultMenu;
  }
  else
  {
    return 0;
  }
}
Beispiel #2
0
void MusicBoxDialog(void)
{
	OSStatus	err;
	IBNibRef	nibRef;

	if (!cartOpen)
		return;

	err = CreateNibReference(kMacS9XCFString, &nibRef);
	if (err == noErr)
	{
		CFURLRef	iconURL;
		FSRef		iconFSRef;
		IconRef		actIcon;
		WindowRef	tWindowRef;

		actIcon = nil;

		if (musicboxmode == kMBXSoundEmulation)
			iconURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("musicbox_ledoff"), CFSTR("icns"), nil);
		else
			iconURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("musicbox_ledon" ), CFSTR("icns"), nil);

		if (iconURL)
		{
			if (CFURLGetFSRef(iconURL, &iconFSRef))
				err = RegisterIconRefFromFSRef('~9X~', 'micn', &iconFSRef, &actIcon);

			CFRelease(iconURL);
		}

		err = CreateWindowFromNib(nibRef, CFSTR("MusicBox"), &tWindowRef);
		if (err == noErr)
		{
			EventHandlerRef		mboxRef, paneRef;
			EventHandlerUPP		mboxUPP, paneUPP;
			EventLoopTimerRef	timeRef;
			EventLoopTimerUPP	timeUPP;
			EventTypeSpec		mboxEvents[] = { { kEventClassCommand, kEventCommandProcess      },
												 { kEventClassCommand, kEventCommandUpdateStatus } },
								paneEvents[] = { { kEventClassControl, kEventControlDraw         } };
			CFStringRef			sref;
			CGDataProviderRef	prov;
			CGImageRef			ipng;
			CFURLRef			iurl;
			HIViewRef			ctl, root, paneView, imageView, contentView;
			HIViewID			cid;
			HIRect				bounds;
			Rect				windowRect, barRect;
			char				drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT];

			mboxPause = false;
			mbxFinished = false;
			showIndicator = false;
			so.stereo_switch = ~0;

			for (int i = 0; i < MAC_MAX_PLAYERS; i++)
				controlPad[i] = 0;

			switch (drawingMethod)
			{
				case kDrawingOpenGL:
					Settings.OpenGLEnable = true;
					break;

				case kDrawingDirect:
				case kDrawingBlitGL:
					Settings.OpenGLEnable = false;
			}

			// 107's enhanced SPC player

			root = HIViewGetRoot(tWindowRef);
			cid.id = 0;

			if (musicboxmode == kMBXSoundEmulation)
			{
				cid.signature = 'HEAD';
				HIViewFindByID(root, cid, &ctl);
				EnableControl(ctl);

				StoredAPU          = new SAPU;
				StoredAPURegisters = new SAPURegisters;
				StoredSoundData    = new SSoundData;
				StoredIAPURAM      = new uint8 [0x10000];

				SPCPlayFreeze();
			}
			else
				MusicBoxForceFreeze();

			cid.signature = 'Kart';
			HIViewFindByID(root, cid, &ctl);
			SetStaticTextTrunc(ctl, truncEnd, false);
			_splitpath(Memory.ROMFilename, drive, dir, fname, ext);
			sref = CFStringCreateWithCString(kCFAllocatorDefault, fname, MAC_PATH_ENCODING);
			if (sref)
			{
				SetStaticTextCFString(ctl, sref, false);
				CFRelease(sref);
			}

			ipng = nil;

			iurl = CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("musicbox_indicator"), CFSTR("png"), nil);
			if (iurl)
			{
				prov = CGDataProviderCreateWithURL(iurl);
				if (prov)
				{
					ipng = CGImageCreateWithPNGDataProvider(prov, nil, false, kCGRenderingIntentDefault);
					CGDataProviderRelease(prov);
				}

				CFRelease(iurl);
			}

			imageView = nil;

			if (ipng)
			{
				HIViewFindByID(root, kHIViewWindowContentID, &contentView);

				err = HIImageViewCreate(ipng, &imageView);
				if (err == noErr)
				{
					bounds = CGRectMake(30, 64, CGImageGetWidth(ipng), CGImageGetHeight(ipng));
					HIViewSetFrame(imageView, &bounds);
					HIImageViewSetOpaque(imageView, false);
					HIViewSetVisible(imageView, true);
					HIViewAddSubview(contentView, imageView);
					cid.signature = 'iMaG';
					SetControlID(imageView, &cid);
				}

				CGImageRelease(ipng);
			}

			cid.signature = 'Pane';
			HIViewFindByID(root, cid, &paneView);
			HIViewGetBounds(paneView, &bounds);
			mbxViewWidth  = bounds.size.width;
			mbxViewHeight = bounds.size.height;
			mbxMarginY = (mbxViewHeight - mbxBarHeight) / 2.0;
			mbxMarginX = (mbxViewWidth - ((mbxBarWidth * 8.0 + mbxBarSpace * 7.0) * 2.0 + mbxLRSpace)) / 2.0;

			if (imageView)
			{
				HIViewSetZOrder(imageView, kHIViewZOrderBelow, paneView);
				HIViewAddSubview(imageView, paneView);
			}

			cid.signature = 'Tr_i';
			HIViewFindByID(root, cid, &ctl);
			HIViewGetFrame(ctl, &bounds);
			GetWindowBounds(tWindowRef, kWindowTitleBarRgn, &barRect);
			mbxClosedHeight = (short) (bounds.origin.y + bounds.size.height + 7.0) + (barRect.bottom - barRect.top);

			GetWindowBounds(tWindowRef, kWindowStructureRgn, &windowRect);
			mbxOpenedHeight = windowRect.bottom - windowRect.top;

			windowRect.bottom = windowRect.top + mbxClosedHeight;
			SetWindowBounds(tWindowRef, kWindowStructureRgn, &windowRect);

			paneUPP = NewEventHandlerUPP(IndicatorEventHandler);
			err = InstallControlEventHandler(paneView, paneUPP, GetEventTypeCount(paneEvents), paneEvents, (void *) paneView, &paneRef);

			mboxUPP = NewEventHandlerUPP(MusicBoxEventHandler);
			err = InstallWindowEventHandler(tWindowRef, mboxUPP, GetEventTypeCount(mboxEvents), mboxEvents, (void *) tWindowRef, &mboxRef);

			timeUPP = NewEventLoopTimerUPP(MusicBoxTimerHandler);
			err = InstallEventLoopTimer(GetCurrentEventLoop(), kEventDurationNoWait, kEventDurationSecond * 2.0 / (double) Memory.ROMFramesPerSecond, timeUPP, (void *) paneView, &timeRef);

			MusicBoxInitIndicator();

			stopNow = false;
			MacStartSound();
			pthread_create(&mbxThread, nil, SoundTask, nil);

			MoveWindowPosition(tWindowRef, kWindowMusicBox, true);
			GetWindowBounds(tWindowRef, kWindowStructureRgn, &windowRect);
			if (windowRect.bottom - windowRect.top > mbxClosedHeight)
			{
				showIndicator = true;
				SetControl32BitValue(ctl, 1);	// Tr_i
			}

			ShowWindow(tWindowRef);
			err = RunAppModalLoopForWindow(tWindowRef);
			HideWindow(tWindowRef);

			SaveWindowPosition(tWindowRef, kWindowMusicBox);

			stopNow = true;
			pthread_join(mbxThread, nil);
			MacStopSound();

			err = RemoveEventLoopTimer(timeRef);
			DisposeEventLoopTimerUPP(timeUPP);

			err = RemoveEventHandler(mboxRef);
			DisposeEventHandlerUPP(mboxUPP);

			err = RemoveEventHandler(paneRef);
			DisposeEventHandlerUPP(paneUPP);

			ReleaseWindow(tWindowRef);

			so.stereo_switch = ~0;

			mbxFinished = true;

			if (musicboxmode == kMBXSoundEmulation)
			{
 				SPCPlayDefrost();

				delete    StoredAPU;
				delete    StoredAPURegisters;
				delete    StoredSoundData;
				delete [] StoredIAPURAM;
			}
			else
				MusicBoxForceDefrost();

			Settings.OpenGLEnable = false;
		}

		if (actIcon)
			err = UnregisterIconRef('~9X~', 'micn');

		DisposeNibReference(nibRef);
	}
}
Beispiel #3
0
// Each time a new window is first opened, call this one time function to set up
// the text view
OSStatus
SetUpTheTextView( WindowRef window )
{
	OSStatus status = noErr;
	HIViewRef textView = NULL;
	HIViewRef scrollView = NULL;
	HIViewRef scrollParentView = NULL;
	
	CMLTEViewData* mlteData = NULL;
	
	// Get the HITextView from the window
	status = GetTextViewFromWindow( window, textView );
	
	require_action( textView != NULL, EXIT, status = paramErr );
	
	// make a new custom C++ object to hold MLTE related data
	mlteData = new CMLTEViewData();
	
	// DON'T FORGET TO DISPOSE THIS WHEN HITextView destructs!!!
	
	// put the custom object in the HITextView for this window
	// as a control property so that we can retrieve it later when we need it.
	status = TextViewStoreMLTEInstanceData( textView, mlteData );
	require_action( textView != NULL, EXIT, status = paramErr );
	
	// Now set the text view as we like it
	status = TextViewDefaultSettings( textView );
	check_noerr( status );
	status = TextViewAddActionNameMapper( textView );
	check_noerr( status );
	status = TextViewSetMargins( textView, 0 /*top*/, 0 /*left*/, 0 /*right*/ );
	check_noerr( status );
	
	// get fancy - try to add a picture behind the textView
	scrollView = HIViewGetSuperview( textView );
	scrollParentView = HIViewGetSuperview( scrollView );
	
	if( scrollParentView != NULL )
	{
		HIViewRef imageViewRef = AddImage( scrollParentView );
		if( imageViewRef != NULL )
		{
			HIRect scrollFrame;
			
			HIViewGetFrame( scrollView, &scrollFrame );
			HIViewSetFrame( imageViewRef, &scrollFrame );
			
			status = HIViewSetZOrder( scrollView, kHIViewZOrderAbove, imageViewRef );
			check_noerr( status );
			HIViewSetVisible(imageViewRef, true);
			
			status = TextViewSetBGAlpha( textView, 0.75 );
			check_noerr( status );
  
		}
	}
	
	// register for menu handing
	status = TextViewInstallMenuHandlers( textView );
  
	EXIT:
	return status;
}
void IGraphicsCarbon::CreateTextEntry(IControl* pControl, IText* pText, IRECT* pTextRect, const char* pString, IParam* pParam)
{
  if (!pControl || mTextEntryView || !mIsComposited) return; // Only composited carbon supports text entry

  WindowRef window = mWindow;
  TXNFrameOptions txnFrameOptions = kTXNMonostyledTextMask | kTXNDisableDragAndDropMask | kTXNSingleLineOnlyMask;
  TXNObject txnObject = 0;
  TXNFrameID frameID = 0;
  TXNObjectRefcon txnObjectRefCon = 0;

  HIRect rct;
  HIViewGetFrame(this->mView, &rct);

  HIViewRef contentView;
  HIViewFindByID (HIViewGetRoot(this->mWindow), kHIViewWindowContentID, &contentView);
  HIViewConvertRect(&rct, HIViewGetSuperview((HIViewRef)this->mView), contentView);

  Rect rect = { rct.origin.y + pTextRect->T,
                rct.origin.x + pTextRect->L,
                rct.origin.y + pTextRect->B + 1,
                rct.origin.x + pTextRect->R + 1
              };

  if (TXNNewObject(NULL,
                   window,
                   &rect,
                   txnFrameOptions,
                   kTXNTextEditStyleFrameType,
                   kTXNSingleStylePerTextDocumentResType,
                   kTXNMacOSEncoding,
                   &txnObject,
                   &frameID,
                   txnObjectRefCon) == noErr)
  {
    TXNSetFrameBounds(txnObject, rect.top, rect.left, rect.bottom, rect.right, frameID);
    mTextEntryView = txnObject;

    // Set the text to display by defualt
    TXNSetData(mTextEntryView, kTXNTextData, pString, strlen(pString)/*+1*/, kTXNStartOffset, kTXNEndOffset); // center aligned text has problems with uneven string lengths

    RGBColor tc;
    tc.red = pText->mTextEntryFGColor.R * 257;
    tc.green = pText->mTextEntryFGColor.G * 257;
    tc.blue = pText->mTextEntryFGColor.B * 257;

    TXNBackground bg;
    bg.bgType         = kTXNBackgroundTypeRGB;
    bg.bg.color.red   = pText->mTextEntryBGColor.R * 257;
    bg.bg.color.green = pText->mTextEntryBGColor.G * 257;
    bg.bg.color.blue  = pText->mTextEntryBGColor.B * 257;

    TXNSetBackground(mTextEntryView, &bg);

    // Set justification
    SInt16 justification;
    Fract flushness;

    switch ( pText->mAlign )
    {
      case IText::kAlignCenter:
        justification = kTXNCenter;  // seems to be buggy wrt dragging and alignement with uneven string lengths
        flushness = kATSUCenterAlignment;
        break;
      case IText::kAlignFar:
        justification = kTXNFlushRight;
        flushness = kATSUEndAlignment;
        break;
      case IText::kAlignNear:
      default:
        justification = kTXNFlushLeft;
        flushness = kATSUStartAlignment;
        break;
    }

    TXNControlTag controlTag[1];
    TXNControlData controlData[1];
    controlTag[0] = kTXNJustificationTag;
    controlData[0].sValue = justification;
    TXNSetTXNObjectControls(mTextEntryView, false, 1, controlTag, controlData);

    ATSUFontID fontid = kATSUInvalidFontID;

    if (pText->mFont && pText->mFont[0])
    {
      ATSUFindFontFromName(pText->mFont, strlen(pText->mFont),
                           kFontFullName /* kFontFamilyName? */ ,
                           (FontPlatformCode)kFontNoPlatform,
                           kFontNoScriptCode,
                           kFontNoLanguageCode,
                           &fontid);
    }

    // font (NOT working)
    TXNTypeAttributes attributes[3];
    attributes[0].tag = kATSUFontTag;
    attributes[0].size = sizeof(ATSUFontID);
    attributes[0].data.dataPtr = &fontid;
    // size
    attributes[1].tag = kTXNQDFontSizeAttribute;
    attributes[1].size = kTXNFontSizeAttributeSize;
    attributes[1].data.dataValue = pText->mSize << 16;
    // color
    attributes[2].tag = kTXNQDFontColorAttribute;
    attributes[2].size = kTXNQDFontColorAttributeSize;
    attributes[2].data.dataPtr = &tc;

    // Finally set the attributes
    TXNSetTypeAttributes(mTextEntryView, 3, attributes, kTXNStartOffset, kTXNEndOffset);

    // Ensure focus remains consistent
    SetUserFocusWindow(window);
    AdvanceKeyboardFocus(window);

    // Set the focus to the edit window
    TXNFocus(txnObject, true);
    TXNSelectAll(mTextEntryView);
    TXNShowSelection(mTextEntryView, true);

    // The event types
    const static EventTypeSpec eventTypes[] =
    {
      { kEventClassMouse,    kEventMouseMoved },
      { kEventClassMouse,    kEventMouseDown },
      { kEventClassMouse,    kEventMouseUp },
      { kEventClassMouse,    kEventMouseWheelMoved },
      { kEventClassWindow,   kEventWindowClosed },
      { kEventClassWindow,   kEventWindowDeactivated },
      { kEventClassWindow,   kEventWindowFocusRelinquish },
      { kEventClassKeyboard, kEventRawKeyDown },
      { kEventClassKeyboard, kEventRawKeyRepeat }
    };

    // Install the event handler
    InstallWindowEventHandler(window, TextEntryHandler, GetEventTypeCount(eventTypes), eventTypes, this, &mTextEntryHandler);

    mEdControl = pControl;
    mEdParam = pParam;
    mTextEntryRect = *pTextRect;
  }
}
/*
	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;
}
/*****************************************************
*
* Handle_WindowCommandProcess(inHandlerCallRef, inEvent, inUserData) 
*
* Purpose:  called to handle of the events generated by the various controls of the HICustomView_Tester window
*
* Inputs:   inHandlerCallRef    - reference to the current handler call chain
*           inEvent             - the event
*           inUserData          - app-specified data you passed in the call to InstallEventHandler
*
* Returns:  OSStatus            - noErr indicates the event was handled
*                                 eventNotHandledErr indicates the event was not handled and the Toolbox should take over
*/
static pascal OSStatus Handle_WindowCommandProcess(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)
	{
	OSStatus status;
	HIViewRef customView = (HIViewRef)inUserData;
	
	// getting the command
	HICommandExtended aCommand;
	status = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(aCommand), NULL, &aCommand);
	require_noerr(status, ExitCommandProcess);
	status = eventNotHandledErr;

	// cheking that the command came from a control
	if ( ! (aCommand.attributes & kHICommandFromControl) ) goto ExitCommandProcess;

	switch (aCommand.commandID)
		{
		//
		// Asking for a refresh of the custom view
		//
		case 'SNDt':
			HIViewSetNeedsDisplay(customView, true);
			status = noErr;
			break;

		//
		// Setting the control value of the custom view
		//
		case 'SV00':
			SetControl32BitValue(customView, 0);
			status = noErr;
			break;
		case 'SV01':
			SetControl32BitValue(customView, 1);
			status = noErr;
			break;
		case 'SV17':
			SetControl32BitValue(customView, 17);
			status = noErr;
			break;
		case 'SVTH':
			SetControl32BitValue(customView, 1000);
			status = noErr;
			break;
		case 'SVet':
			{
			HIViewRef editText;
			HIViewFindByID(HIViewGetRoot(GetControlOwner(customView)), kSetValueEditID, &editText);
			char buffer[11];
			Size actualSize;
			GetControlData(editText, kControlEntireControl, kControlEditTextTextTag, 10, buffer, &actualSize);
			if (actualSize > 10) actualSize = 10;
			buffer[actualSize] = 0;
			SetControl32BitValue(customView, atoi(buffer));
			}
			status = noErr;
			break;

		//
		// Setting the state of the custom view
		//
		case 'CHlt':
			// setting the hilite to non-0 also stomps the previous hilite state if any
			// and we don't want that in our testing
			if (GetControl32BitValue(aCommand.source.control) == 1)
				HiliteControl(customView, 1);
			else
				HiliteControl(customView, 0);
			status = noErr;
			break;
		case 'CEnb':
			{
			HIViewRef hiliteControl;
			HIViewFindByID(HIViewGetRoot(GetControlOwner(customView)), kCheckHiliteID, &hiliteControl);
			if (GetControl32BitValue(aCommand.source.control) == 1)
				EnableControl(customView);
			else
				DisableControl(customView);
			UInt16 prevHilite = GetControlHilite(customView);
			if ((prevHilite == kControlInactivePart) || (prevHilite == kControlDisabledPart))
				DisableControl(hiliteControl);
			else
				EnableControl(hiliteControl);
			HIViewSetNeedsDisplay(customView, true);
			}
			status = noErr;
			break;
		case 'CAct':
			{
			HIViewRef hiliteControl;
			HIViewFindByID(HIViewGetRoot(GetControlOwner(customView)), kCheckHiliteID, &hiliteControl);
			if (GetControl32BitValue(aCommand.source.control) == 1)
				ActivateControl(customView);
			else
				DeactivateControl(customView);
			UInt16 prevHilite = GetControlHilite(customView);
			if ((prevHilite == kControlInactivePart) || (prevHilite == kControlDisabledPart))
				DisableControl(hiliteControl);
			else
				EnableControl(hiliteControl);
			HIViewSetNeedsDisplay(customView, true);
			}
			status = noErr;
			break;

		//
		// Testing the custom view in or as a scroller in a HIScrollView
		//
		case 'CTiS':
		case 'CTaS':
			if (GetControl32BitValue(aCommand.source.control) == 1)
				{
				// create a HIScrollView and install it where and as the custom view was
				HIViewRef scrollView;
				status = HIScrollViewCreate(kHIScrollViewValidOptions, &scrollView);
				require_noerr(status, ExitCommandProcess);
				
				HIRect frame;
				status = HIViewGetFrame(customView, &frame);
				require_noerr(status, ExitCommandProcess);
				status = HIViewSetFrame(scrollView, &frame);
				require_noerr(status, ExitCommandProcess);

				HIViewSetLayoutInfo(scrollView, &kBindToParentLayout);
				HIViewSetLayoutInfo(customView, &kNoBindLayout);
				
				status = HIViewAddSubview(HIViewGetSuperview(customView), scrollView);
				require_noerr(status, ExitCommandProcess);
				
				if (aCommand.commandID == 'CTiS')
					{
					// if we are testing the custom view in a scroller, we embed it in a scrolling User Pane
					// that we embed in the HIScrollView
					Rect boundsRect = {0, 0, 1000, 1000};
					HIViewRef userPane;
					status = CreateUserPaneControl(NULL, &boundsRect, kControlSupportsEmbedding, &userPane);
					require_noerr(status, ExitCommandProcess);
					
					EventTypeSpec userPaneEvents[] =
						{
							{kEventClassScrollable, kEventScrollableGetInfo},
							{kEventClassScrollable, kEventScrollableScrollTo}
						};
					InstallControlEventHandler(userPane, UserPaneHandler, 2, userPaneEvents, userPane, NULL);

					status = HIViewAddSubview(scrollView, userPane);
					require_noerr(status, ExitCommandProcess);
					status = HIViewAddSubview(userPane, customView);
					require_noerr(status, ExitCommandProcess);

					HIViewSetVisible(userPane, true);
					}
				else
					{
					// else we just embed the custom view directly in the HIScrollView
					status = HIViewAddSubview(scrollView, customView);
					require_noerr(status, ExitCommandProcess);
					}
				
				HIViewSetVisible(scrollView, true);
				
				// the 2 modes are not compatible so we disable the other check box
				HIViewRef otherCheckToDisable;
				if (aCommand.commandID == 'CTiS')
					HIViewFindByID(HIViewGetRoot(GetControlOwner(customView)), kCheckTestAsScrollID, &otherCheckToDisable);
				else
					HIViewFindByID(HIViewGetRoot(GetControlOwner(customView)), kCheckTestInScrollID, &otherCheckToDisable);
				require_noerr(status, ExitCommandProcess);
				DisableControl(otherCheckToDisable);
				// if we reach here, status is already set to noErr so we don't set it again
				}
			else
				{
				// we remove the HIScrollView and set the custom view back to where and as it was
				HIViewRef scrollView;
				if (aCommand.commandID == 'CTiS')
					scrollView = HIViewGetSuperview(HIViewGetSuperview(customView));
				else
					scrollView = HIViewGetSuperview(customView);

				status = HIViewAddSubview(HIViewGetSuperview(scrollView), customView);
				require_noerr(status, ExitCommandProcess);

				HIRect frame;
				status = HIViewGetFrame(scrollView, &frame);
				require_noerr(status, ExitCommandProcess);
				status = HIViewSetFrame(customView, &frame);
				require_noerr(status, ExitCommandProcess);

				HIViewSetLayoutInfo(customView, &kBindToParentLayout);

				// by releasing the HIScrollView, we also release the scrolling User Pane if any
				// which was embedded inside
				CFRelease(scrollView);
				
				// we renable the other check box
				HIViewRef otherCheckToEnable;
				if (aCommand.commandID == 'CTiS')
					HIViewFindByID(HIViewGetRoot(GetControlOwner(customView)), kCheckTestAsScrollID, &otherCheckToEnable);
				else
					HIViewFindByID(HIViewGetRoot(GetControlOwner(customView)), kCheckTestInScrollID, &otherCheckToEnable);
				require_noerr(status, ExitCommandProcess);
				EnableControl(otherCheckToEnable);
				// if we reach here, status is already set to noErr so we don't set it again
				}
			break;
		}

ExitCommandProcess:

	return status;
	}   // Handle_WindowCommandProcess
Beispiel #7
0

// ---------------------------------------------------------------------------
// To make a TextView auto-size along with its parent view, use the following
// code:

HIViewRef textView;
HILayoutInfo layoutInfo;
HIRect parentFrame;

//...

// Bind the view to its parent on all sides (affects resize)
layoutInfo.binding.left.kind = kHILayoutBindLeft;
layoutInfo.binding.left.toView = NULL;
layoutInfo.binding.left.offset = 0.0;
layoutInfo.binding.top.kind = kHILayoutBindTop;
layoutInfo.binding.top.toView = NULL;
layoutInfo.binding.top.offset = 0.0;
layoutInfo.binding.right.kind = kHILayoutBindRight;
layoutInfo.binding.right.toView = NULL;
layoutInfo.binding.right.offset = 0.0;
layoutInfo.binding.bottom.kind = kHILayoutBindBottom;
layoutInfo.binding.bottom.toView = NULL;
layoutInfo.binding.bottom.offset = 0.0;
status = HIViewSetLayoutInfo(textView, &layoutInfo);

// Set the initial size to be the same as the parent
status = HIViewGetFrame(HIViewGetSuperview(textView), &parentFrame);
status = HIViewSetFrame(textView, &parentFrame);