Ejemplo n.º 1
0
IGraphicsCarbon::~IGraphicsCarbon()
{
  if (mTextEntryView)
  {
    RemoveEventHandler(mTextEntryHandler);
    mTextEntryHandler = 0;

    #if USE_MLTE
    TXNFocus(mTextEntryView, false);
    TXNClear(mTextEntryView);
    TXNDeleteObject(mTextEntryView);
    #else
    HIViewRemoveFromSuperview(mTextEntryView);
    #endif

    mTextEntryView = 0;
    mEdControl = 0;
    mEdParam = 0;
  }

  RemoveEventLoopTimer(mTimer);
  RemoveEventHandler(mControlHandler);
  RemoveEventHandler(mWindowHandler);
  mTimer = 0;
  mView = 0;
//  DisposeRgn(mRgn);
}
Ejemplo n.º 2
0
void IGraphicsCarbon::EndUserInput(bool commit)
{
  if (mTextEntryHandler)
  {
    RemoveEventHandler(mTextEntryHandler);
    mTextEntryHandler = 0;
  }
  else
  {
    return;
  }

  if (commit)
  {
    // Get the text
    CharsHandle textHandle;
    TXNGetDataEncoded(mTextEntryView, kTXNStartOffset, kTXNEndOffset, &textHandle, kTXNTextData);

    // Check that we have some worthwhile data
    if (textHandle != NULL && GetHandleSize(textHandle) > 0)
    {
      const long textLength = GetHandleSize(textHandle);
      char txt[257];
      strncpy(txt, *textHandle, (textLength > 255) ? 255 : textLength);
      txt[(textLength > 255) ? 255 : textLength] = '\0';

      if (mEdParam)
        mGraphicsMac->SetFromStringAfterPrompt(mEdControl, mEdParam, txt);
      else
        mEdControl->TextFromTextEntry(txt);
    }
  }

  if (mTextEntryView)
  {
    TXNFocus(mTextEntryView, false);
    TXNClear(mTextEntryView);
    TXNDeleteObject(mTextEntryView);
    mTextEntryView = 0;
  }

  if (mIsComposited)
  {
    HIViewSetNeedsDisplay(mView, true);
  }
  else
  {
    mEdControl->SetDirty(false);
    mEdControl->Redraw();
  }

  SetThemeCursor(kThemeArrowCursor);
  SetUserFocusWindow(kUserFocusAuto);

  mEdControl = 0;
  mEdParam = 0;
}
OSStatus
TextViewDelete( WindowRef window, OSType key )
{
    OSStatus status = eventNotHandledErr;
    MyMLTEData *pMyMLTEData = NULL;
    
    // recover our data from the window
    status = GetWindowProperty( window, kMyPropertyCreator, key,
                        sizeof(Ptr), NULL, &pMyMLTEData );
    require_action( status == noErr, CantGetObj, status = eventNotHandledErr );

    // clean up allocated memory
    TXNDeleteObject( pMyMLTEData->fTXNObj );
    DisposePtr( (char*)pMyMLTEData );
    
    status = RemoveWindowProperty( window, kMyPropertyCreator, key );
    CantGetObj:
    return status;
}
OSStatus YASTControlAttachToExistingControl(ControlRef theControl) {
	OSStatus err;
	YASTControlVars *varsp;
	UInt32 outCommandID;
	EventHandlerRef controlEvents, windowEvents;
	TXNObject theTXNObject;
	RgnHandle outlineRegion;
	
		/* set up our locals */
	controlEvents = windowEvents = NULL;
	theTXNObject = NULL;
	outlineRegion = NULL;
	varsp = NULL;
	err = noErr;
	
		/* allocate our private storage and set up initial settings*/
	varsp = (YASTControlVars *) malloc(sizeof(YASTControlVars));
	if (varsp == NULL) {
		err = memFullErr;
	} else {
		varsp->fInFocus = false;
		varsp->fIsActive = true;
		varsp->fTXNObjectActive = false;
		varsp->fControl = theControl;
		varsp->fTabMovesFocus = true;
		varsp->fDrawFocusBox = true;
		varsp->fFocusDrawState = false;
		varsp->fIsReadOnly = false;
		varsp->fRTextOutlineRegion = NULL;
		varsp->fWindow = GetControlOwner(theControl);
		varsp->fGrafPtr = GetWindowPort(varsp->fWindow);
	}
	
		/* set our control's command id.  we don't actually use it, but it must
		be non-zero for our control to be sent command events.  only set it
		if it has not already been set.  */
	err = GetControlCommandID(theControl, &outCommandID);
	if (err == noErr) {
		if (outCommandID == 0) {
			err = SetControlCommandID(theControl, 1);
		}
	}
		/* calculate the rectangles used by the control */
	if (err == noErr) {
		outlineRegion = NewRgn();
		if (outlineRegion == NULL) {
			err = memFullErr;
		} else {
			Rect bounds;
			varsp->fRTextOutlineRegion = outlineRegion;
			GetControlBounds(theControl, &bounds);
			YASTControlCalculateBounds(varsp, &bounds);
		}
	}

		/* create the new edit field */
	if (err == noErr) {
		err = TXNNewObject(NULL, varsp->fWindow, &varsp->fRTextArea,
			kTXNWantVScrollBarMask | kTXNAlwaysWrapAtViewEdgeMask,
			kTXNTextEditStyleFrameType, kTXNTextensionFile, kTXNSystemDefaultEncoding, 
			&theTXNObject, &varsp->fTXNFrameID, (TXNObjectRefcon) varsp);
		if (err == noErr) {
			varsp->fTXNObject = theTXNObject;
		}
	}
	
		/* set the field's background */
	if (err == noErr) {
		RGBColor rgbWhite = {0xFFFF, 0xFFFF, 0xFFFF};
		TXNBackground tback;
		tback.bgType = kTXNBackgroundTypeRGB;
		tback.bg.color = rgbWhite;
		TXNSetBackground( varsp->fTXNObject, &tback);
	}
	
		/* set the margins for easier selection and display */
	if (err == noErr) {
		TXNControlData txnCControlData;
		TXNControlTag txnControlTag = kTXNMarginsTag;
		TXNMargins txnMargins = { 2, 3, 2, 1 };	/* t,l,b,r */
		txnCControlData.marginsPtr	= &txnMargins; 
		(void) TXNSetTXNObjectControls( varsp->fTXNObject, false, 1, &txnControlTag, &txnCControlData );
	}
	
		/* install our carbon event handlers */
	if (err == noErr) {
		static EventHandlerUPP gTPEventHandlerUPP = NULL;
		if (gTPEventHandlerUPP == NULL)
			gTPEventHandlerUPP = NewEventHandlerUPP(YASTControlCarbonEventHandler);
	
			/* carbon event handlers for the control */
		err = InstallEventHandler( GetControlEventTarget( theControl ),
			gTPEventHandlerUPP,
			(sizeof(gYASTControlEvents)/sizeof(EventTypeSpec)),
			gYASTControlEvents,
			varsp, &controlEvents);
		if (err == noErr) { 
			varsp->fControlEvents = windowEvents;
			
				/* carbon event handlers for the control's window */
			err = InstallEventHandler( GetWindowEventTarget( varsp->fWindow ),
				gTPEventHandlerUPP, (sizeof(gYASTControlWindowEvents)/sizeof(EventTypeSpec)),
				gYASTControlWindowEvents, varsp, &windowEvents);
			if (err == noErr) {
				varsp->fWindowEvents = windowEvents;
			}
		}
	}
	
		/* perform final activations and setup for our text field.  Here,
		we assume that the window is going to be the 'active' window. */
	if (err == noErr) {
		SetTextActivation(varsp, (varsp->fIsActive && varsp->fInFocus));
	}
	
		/* clean up on error */
	if (err != noErr) {
		if (controlEvents != NULL) RemoveEventHandler(controlEvents);
		if (windowEvents != NULL) RemoveEventHandler(windowEvents);
		if (theTXNObject != NULL) TXNDeleteObject(theTXNObject);
		if (outlineRegion != NULL) DisposeRgn(outlineRegion);
		if (varsp != NULL) free((void*) varsp);
	}
	
		/* all done */
	return err;
}
	/* YASTControlCarbonEventHandler defines the main entry point for all
	of the carbon event handlers installed for the YASTControl. */
static pascal OSStatus YASTControlCarbonEventHandler(
									EventHandlerCallRef myHandler,
									EventRef event,
									void* userData) {
	#pragma unused ( myHandler )
    OSStatus err, returnedResult;
	YASTControlVarsPtr varsp;
	UInt32 eclass, ekind;
		/* set up locals */
	eclass = GetEventClass(event);
	ekind = GetEventKind(event);
	varsp = (YASTControlVarsPtr) userData;
	returnedResult = eventNotHandledErr;
		/* dispatch the event by class*/
	switch (eclass) {
	
		case kEventClassWindow:
			if ( ekind == kEventWindowCursorChange ) {
				Point where;
				UInt32 modifiers;
				Boolean cursorWasSet;
					/* get the mouse position */
				err = GetEventParameter( event, kEventParamMouseLocation, 
						typeQDPoint,  NULL, sizeof(where), NULL, &where);
				if (err == noErr) {
					err = GetEventParameter( event, kEventParamKeyModifiers, 
							typeUInt32,  NULL, sizeof(modifiers), NULL, &modifiers);
					if (err == noErr) {
						SetPort(varsp->fGrafPtr);
						GlobalToLocal(&where);
						if (PtInRect(where, &varsp->fRBounds)) {
							err = HandleControlSetCursor( varsp->fControl, where, modifiers, &cursorWasSet);
							if (err != noErr) cursorWasSet = false;
							if ( ! cursorWasSet ) InitCursor();
							returnedResult = noErr;
						}
					}
				}
			}
			break;
	
		case kEventClassMouse:
				/* handle mouse downs in the control, but only if the
				control is in focus. */
			if ( ekind == kEventMouseDown ) {
				EventRecord outEvent;
				if ( varsp->fInFocus ) {
					if (ConvertEventRefToEventRecord( event, &outEvent)) {
						TXNClick( varsp->fTXNObject,  &outEvent);
					}
					returnedResult = noErr;
				}
			}
			break;

		case kEventClassTextInput:
			if ( ekind == kEventUnicodeForKeyEvent
			&& varsp->fTabMovesFocus) {
				UniChar mUnicodeText[8];
				UInt32 bytecount, nchars;
					/* get the character */
				err = GetEventParameter(event, kEventParamTextInputSendText, 
							typeUnicodeText, NULL, sizeof(mUnicodeText),
							&bytecount, (char*) mUnicodeText);
				if ((err == noErr)
				&& (bytecount >= sizeof(UniChar))) {
					nchars = ( bytecount / sizeof(UniChar) );
						/* if it's not the tab key, forget it... */
					if ( mUnicodeText[0] == '\t' ) {
						EventRef rawKeyEvent;
						Boolean shiftDown;
							/* is the shift key held down? */
						shiftDown = false;
						err = GetEventParameter(event, kEventParamTextInputSendKeyboardEvent, 
									typeEventRef, NULL, sizeof(rawKeyEvent), NULL, &rawKeyEvent);
						if (err == noErr) {
							UInt32 modifiers;
							err = GetEventParameter(rawKeyEvent, kEventParamKeyModifiers, 
									typeUInt32, NULL, sizeof(modifiers), NULL, &modifiers);
							if (err == noErr) {
								shiftDown = ( (modifiers & shiftKey) != 0 );
							}
						}
							/* advance the keyboard focus, backwards if shift is down */
						if (shiftDown)
							ReverseKeyboardFocus( varsp->fWindow );
						else AdvanceKeyboardFocus( varsp->fWindow );
							/* noErr lets the CEM know we handled the event */
						returnedResult = noErr;
					}
				}
			}
			break;

		case kEventClassControl:
			switch (ekind) {

				case kEventControlSetFocusPart:
					{	ControlPartCode thePart;
						err = GetEventParameter(event, kEventParamControlPart, 
							typeControlPartCode, NULL, sizeof(thePart), NULL, &thePart);
						if (err == noErr) {
							switch (thePart) {
								default:
								case kControlFocusNoPart: /* turn off focus */
									if ( varsp->fInFocus ) {
										TXNFocus( varsp->fTXNObject, false);
										varsp->fInFocus = false;
									}
									thePart = kControlFocusNoPart;
									break;
								case kYASTControlOnlyPart: /* turn on focus */
									if ( !  varsp->fInFocus ) {
										TXNFocus( varsp->fTXNObject, true);
										varsp->fInFocus = true;
									}
									thePart = kYASTControlOnlyPart;
									break;
								case kControlFocusPrevPart: /* toggle focus on/off */
								case kControlFocusNextPart:
									varsp->fInFocus = ! varsp->fInFocus;
									TXNFocus( varsp->fTXNObject, varsp->fInFocus);
									thePart = (varsp->fInFocus ? kYASTControlOnlyPart : kControlFocusNoPart);
									break;
							}
							SetPort(varsp->fGrafPtr);
								/* calculate the next highlight state */
							SetTextActivation(varsp, varsp->fIsActive && varsp->fInFocus);
								/* redraw the text fram and focus rectangle to indicate the
								new focus state */
							DrawThemeEditTextFrame(&varsp->fRTextOutline,
								varsp->fIsActive ? kThemeStateActive: kThemeStateInactive);
							RedrawFocusOutline(varsp);
						}
							/* pass back the foocus part code */
						err = SetEventParameter( event, kEventParamControlPart,
								typeControlPartCode, sizeof(thePart), &thePart);
						returnedResult = err;
					}
					break;

				case kEventControlHitTest:
						/* this event does not necessairly mean that a mouse click
						has occured.  Here we are simply testing to see if a particular
						point is located inside of the control.  More complicated controls
						would return different part codes for different parts of
						themselves;  but, since YASTControls only advertise one part, the
						hit test here is more or less a boolean test. */
					{	ControlPartCode thePart;
						Point where;
						err = GetEventParameter(event, kEventParamMouseLocation, 
							typeQDPoint, NULL, sizeof(where), NULL, &where);
						if (err == noErr) {
							if (PtInRect(where, &varsp->fRTextArea)) {
								thePart = kYASTControlOnlyPart;
							} else thePart = 0;
							err = SetEventParameter( event, kEventParamControlPart,
										typeControlPartCode, sizeof(thePart), &thePart);
						}
						returnedResult = err;
					}
					break;

				case kEventControlClick:
						/* here we handle focus switching on the control.  Actual tracking
						of mouse down events in the control is performed in the kEventClassMouse
						mouse down handler above. */
					if ( ! varsp->fInFocus ) {
						SetKeyboardFocus(varsp->fWindow, varsp->fControl, kYASTControlOnlyPart);
						returnedResult = noErr;
					}
					break;
					
				case kEventControlBoundsChanged:
						/* we moved, or switched size - recalculate our rectangles */
					{	Rect bounds;
						err = GetEventParameter(event, kEventParamCurrentBounds, 
							typeQDRectangle, NULL, sizeof(bounds), NULL, &bounds);
						if (err == noErr) {
							YASTControlCalculateBounds(varsp, &bounds);
							TXNSetFrameBounds( varsp->fTXNObject,
								varsp->fRTextArea.top, varsp->fRTextArea.left,
								varsp->fRTextArea.bottom, varsp->fRTextArea.right,
								varsp->fTXNFrameID);
						}
					}
					break;
						
				case kEventControlActivate:
				case kEventControlDeactivate:
					{	SetPort(varsp->fGrafPtr);
						varsp->fIsActive = (ekind == kEventControlActivate);
						SetTextActivation(varsp, varsp->fIsActive && varsp->fInFocus);
							/* redraw the frame */
						DrawThemeEditTextFrame(&varsp->fRTextOutline,
							varsp->fIsActive ? kThemeStateActive: kThemeStateInactive);
						RedrawFocusOutline(varsp);
						returnedResult = noErr;
					}
					break;
					
				case kEventControlDraw:
						/* redraw the control */
					SetPort(varsp->fGrafPtr);
						/* update the text region */
					TXNDraw(varsp->fTXNObject, NULL);
						/* restore the drawing environment */
						/* draw the text frame and focus frame (if necessary) */
					DrawThemeEditTextFrame(&varsp->fRTextOutline,
						varsp->fIsActive ? kThemeStateActive: kThemeStateInactive);
					RedrawFocusOutline(varsp);
					returnedResult = noErr;
					break;
					
				case kEventControlSetCursor:
						/* cursor adjustment */
					{	SetPortWindowPort(varsp->fWindow);
						TXNAdjustCursor( varsp->fTXNObject, varsp->fRTextOutlineRegion);
						returnedResult = noErr;
					}
					break;
					
				case kEventControlDispose:
						/* RemoveEventHandler(varsp->fControlEvents); -- this call has been
						left out on purpose because it will be called automatically when the
						control is disposed. */
					RemoveEventHandler(varsp->fWindowEvents);
					TXNDeleteObject(varsp->fTXNObject);
					DisposeRgn(varsp->fRTextOutlineRegion);
					free(varsp);
						/* returnedResult = noErr; -- this has been left out on purpose
						because we want the dispatching to continue and dispose of the control */
					break;
					
				case kEventControlSetData:
					{	ResType inTagName;
						Size inBufferSize;
						void * inBuffer;
						err = GetEventParameter( event, kEventParamControlDataTag, typeEnumeration, 
							NULL, sizeof(inTagName), NULL, &inTagName);
						if (err == noErr) {
							err = GetEventParameter( event, kEventParamControlDataBuffer, typePtr, 
								NULL, sizeof(inBuffer), NULL, &inBuffer);
							if (err == noErr) {
								err = GetEventParameter( event, kEventParamControlDataBufferSize, typeLongInteger, 
									NULL, sizeof(inBufferSize), NULL, &inBufferSize);
								if (err == noErr) {
									err = YASTControlSetData(varsp, inTagName, inBuffer, inBufferSize);
								}
							}
						}
						returnedResult = err;
					}
					break;
					
				case kEventControlGetData:
					{	ResType inTagName;
						Size inBufferSize, outBufferSize;
						void * inBuffer;
						err = GetEventParameter( event, kEventParamControlDataTag, typeEnumeration, 
							NULL, sizeof(inTagName), NULL, &inTagName);
						if (err == noErr) {
							err = GetEventParameter( event, kEventParamControlDataBuffer, typePtr, 
								NULL, sizeof(inBuffer), NULL, &inBuffer);
							if (err == noErr) {
								err = GetEventParameter( event, kEventParamControlDataBufferSize, typeLongInteger, 
									NULL, sizeof(inBufferSize), NULL, &inBufferSize);
								if (err == noErr) {
									err = YASTControlGetData(varsp, inTagName, inBuffer, inBufferSize, &outBufferSize);
									if (err == noErr) {
										err = SetEventParameter( event, kEventParamControlDataBufferSize,
													typeLongInteger, sizeof(outBufferSize), &outBufferSize);
									}
								}
							}
						}
						returnedResult = err;
					}
					break;
					
			}
			break;
		case kEventClassCommand:
			if ( ekind == kEventProcessCommand ) {
				HICommand command;
				err = GetEventParameter( event, kEventParamDirectObject,
										typeHICommand, NULL, sizeof(command), NULL, &command);
				if (err == noErr) {
					switch (command.commandID) {
						case kHICommandUndo:
							TXNUndo(varsp->fTXNObject);
							returnedResult = noErr;
							break;
						case kHICommandRedo:
							TXNRedo(varsp->fTXNObject);
							returnedResult = noErr;
							break;
						case kHICommandCut:
							ClearCurrentScrap();
							err = TXNCut(varsp->fTXNObject); 
							if (err == noErr)
								err = TXNConvertToPublicScrap();
							returnedResult = err;
							break;
						case kHICommandCopy:
							ClearCurrentScrap();
							err = TXNCopy(varsp->fTXNObject);
							if (err == noErr)
								err = TXNConvertToPublicScrap();
							returnedResult = err;
							break;
						case kHICommandPaste:
							err = TXNConvertFromPublicScrap();
							if (err == noErr)
								err = TXNPaste(varsp->fTXNObject);
							returnedResult = err;
							break;
						case kHICommandClear:
							err = TXNClear(varsp->fTXNObject);
							returnedResult = err;
							break;
						case kHICommandSelectAll:
							err = TXNSetSelection(varsp->fTXNObject, kTXNStartOffset, kTXNEndOffset);
							returnedResult = err;
							break;
					}
				}
			} else if ( ekind == kEventCommandUpdateStatus ) {
				HICommand command;
				TXNOffset oStartOffset, oEndOffset;
				TXNActionKey oActionKey;

				err = GetEventParameter( event, kEventParamDirectObject, typeHICommand, 
										NULL, sizeof(command), NULL, &command);
				
				if ((err == noErr)
				&& ((command.attributes & kHICommandFromMenu) != 0)) {
					switch (command.commandID) {
						case kHICommandUndo:
							if (TXNCanUndo(varsp->fTXNObject, &oActionKey)) {
								EnableMenuItem(command.menu.menuRef, 0); /* required pre OS 10.2 */
								EnableMenuItem(command.menu.menuRef, command.menu.menuItemIndex);
							} else DisableMenuItem(command.menu.menuRef, command.menu.menuItemIndex);
							returnedResult = noErr;
							break;
						case kHICommandRedo:
							if (TXNCanRedo(varsp->fTXNObject, &oActionKey)) {
								EnableMenuItem(command.menu.menuRef, 0); /* required pre OS 10.2 */
								EnableMenuItem(command.menu.menuRef, command.menu.menuItemIndex);
							} else DisableMenuItem(command.menu.menuRef, command.menu.menuItemIndex);
							returnedResult = noErr;
							break;
						case kHICommandCut:
						case kHICommandCopy:
						case kHICommandClear:
							TXNGetSelection(varsp->fTXNObject, &oStartOffset, &oEndOffset);
							if (oStartOffset != oEndOffset) {
								EnableMenuItem(command.menu.menuRef, 0); /* required pre OS 10.2 */
								EnableMenuItem(command.menu.menuRef, command.menu.menuItemIndex);
							} else DisableMenuItem(command.menu.menuRef, command.menu.menuItemIndex);
							returnedResult = noErr;
							break;
						case kHICommandPaste:
							if (TXNIsScrapPastable()) {
								EnableMenuItem(command.menu.menuRef, 0); /* required pre OS 10.2 */
								EnableMenuItem(command.menu.menuRef, command.menu.menuItemIndex);
							} else DisableMenuItem(command.menu.menuRef, command.menu.menuItemIndex);
							returnedResult = noErr;
							break;
						case kHICommandSelectAll:
							if(TXNDataSize(varsp->fTXNObject) > 0) {
								EnableMenuItem(command.menu.menuRef, 0); /* required pre OS 10.2 */
								EnableMenuItem(command.menu.menuRef, command.menu.menuItemIndex);
							} else DisableMenuItem(command.menu.menuRef, command.menu.menuItemIndex);
							returnedResult = noErr;
							break;
					}
				}
			}
			break;
	}
    return returnedResult;
}