/* YASTControlSetData is dispatched from our control event handler. It is where we handle all calls to SetControlData directed to our control. */ static OSStatus YASTControlSetData( YASTControlVarsPtr varsp, ResType inTagName, void * inBuffer, Size inBufferSize) { OSStatus err, returnedResult; /* default result */ returnedResult = eventNotHandledErr; /* dispatch according to the tag */ switch (inTagName) { case kYASTControlAllTextTag: /* char* */ case kYASTControlSelectedTextTag: /* char* */ { TXNOffset oStartOffset, oEndOffset; /* pick the range of chars we want to replace */ if (inTagName == kYASTControlSelectedTextTag) TXNGetSelection( varsp->fTXNObject, &oStartOffset, &oEndOffset); else { oStartOffset = kTXNStartOffset; oEndOffset = kTXNEndOffset; } /* get the new text */ err = TXNSetData( varsp->fTXNObject, kTXNTextData, inBuffer, inBufferSize, oStartOffset, oEndOffset ); } returnedResult = err; break; case kYASTControlAllUnicodeTextTag: /* CFStringRef */ case kYASTControlSelectedUnicodeTextTag: /* CFStringRef */ if (inBufferSize != sizeof(CFStringRef)) { err = paramErr; } else { CFStringRef theString; CFIndex length; UniChar *buffer; TXNOffset oStartOffset, oEndOffset; /* pick the range of chars we want to replace */ if (inTagName == kYASTControlSelectedUnicodeTextTag) TXNGetSelection( varsp->fTXNObject, &oStartOffset, &oEndOffset); else { oStartOffset = kTXNStartOffset; oEndOffset = kTXNEndOffset; } theString = * (CFStringRef*) inBuffer; /* get the new text */ length = CFStringGetLength(theString); buffer = (UniChar *) malloc(length*sizeof(UniChar)); if (buffer != NULL) { CFRange range; range.location = 0; range.length = length; CFStringGetCharacters(theString, range, buffer); /* add the new text */ err = TXNSetData( varsp->fTXNObject, kTXNUnicodeTextData, buffer, length*2, oStartOffset, oEndOffset); free(buffer); } else { err = memFullErr; } } returnedResult = err; break; case kYASTControlSelectionRangeTag: /* YASTControlEditTextSelectionRec */ if (inBufferSize != sizeof(CFRange)) { err = paramErr; } else { YASTControlEditTextSelectionPtr range; range = (YASTControlEditTextSelectionPtr) inBuffer; err = TXNSetSelection( varsp->fTXNObject, range->selStart, range->selEnd); if (err == noErr) { TXNShowSelection( varsp->fTXNObject, false); } } returnedResult = err; break; case kYASTControlTabsAdvanceFocusTag: /* Boolean (default true) */ if (inBufferSize != sizeof(Boolean)) { err = paramErr; } else { varsp->fTabMovesFocus = * (Boolean*) inBuffer; err = noErr; } returnedResult = err; break; case kYASTControlDoDrawFocusTag: /* Boolean (default true) */ if (inBufferSize != sizeof(Boolean)) { err = paramErr; } else { varsp->fDrawFocusBox = * (Boolean*) inBuffer; RedrawFocusOutline(varsp); err = noErr; } returnedResult = err; break; case kYASTControlReadOnlyTag: if (inBufferSize != sizeof(Boolean)) { err = paramErr; } else { TXNControlData txnCControlData; TXNControlTag txnControlTag; txnControlTag = kTXNIOPrivilegesTag; if ( * (Boolean*) inBuffer ) txnCControlData.uValue = kTXNReadOnly; else txnCControlData.uValue = kTXNReadWrite; err = TXNSetTXNObjectControls( varsp->fTXNObject, false, 1, &txnControlTag, &txnCControlData ); if (err == noErr) { varsp->fIsReadOnly = * (Boolean*) inBuffer; } } returnedResult = err; break; case kYASTControlTabSizeTag: if (inBufferSize != sizeof(SInt16)) { err = paramErr; } else { TXNTab txnTabData; TXNControlTag txnControlTag; txnControlTag = kTXNTabSettingsTag; txnTabData.value = * (SInt16*) inBuffer; txnTabData.tabType = kTXNRightTab; txnTabData.filler = 0; err = TXNSetTXNObjectControls( varsp->fTXNObject, false, 1, &txnControlTag, &txnTabData ); } returnedResult = err; break; } return returnedResult; }
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; } }
OSStatus DisplayReleaseNotes(void) { OSStatus err; IBNibRef nib = NULL; WindowRef window = NULL; err = CreateNibReference(CFSTR("SecondLife"), &nib); if(err == noErr) { CreateWindowFromNib(nib, CFSTR("Release Notes"), &window); } if(err == noErr) { // Get the text view control HIViewRef textView; ControlID id; id.signature = 'text'; id.id = 0; LLString releaseNotesText; _read_file_into_string(releaseNotesText, "releasenotes.txt"); // Flawfinder: ignore err = HIViewFindByID(HIViewGetRoot(window), id, &textView); if(err == noErr) { // Convert from the encoding used in the release notes. CFStringRef str = CFStringCreateWithBytes( NULL, (const UInt8*)releaseNotesText.c_str(), releaseNotesText.size(), kCFStringEncodingWindowsLatin1, // This matches the way the Windows version displays the release notes. FALSE); if(str != NULL) { int size = CFStringGetLength(str); if(size > 0) { UniChar *chars = new UniChar[size + 1]; CFStringGetCharacters(str, CFRangeMake(0, size), chars); err = TXNSetData(HITextViewGetTXNObject(textView), kTXNUnicodeTextData, chars, size * sizeof(UniChar), kTXNStartOffset, kTXNStartOffset); delete[] chars; } CFRelease(str); } else { // Creating the string failed. Probably an encoding problem. Display SOMETHING... err = TXNSetData(HITextViewGetTXNObject(textView), kTXNTextData, releaseNotesText.c_str(), releaseNotesText.size(), kTXNStartOffset, kTXNStartOffset); } } // Set the selection to the beginning of the text and scroll it into view. if(err == noErr) { err = TXNSetSelection(HITextViewGetTXNObject(textView), kTXNStartOffset, kTXNStartOffset); } if(err == noErr) { // This function returns void. TXNShowSelection(HITextViewGetTXNObject(textView), false); } } if(err == noErr) { ShowWindow(window); } if(err == noErr) { // Set up an event handler for the window. EventHandlerRef handler = NULL; EventTypeSpec handlerEvents[] = { { kEventClassCommand, kEventCommandProcess } }; InstallWindowEventHandler( window, NewEventHandlerUPP(simpleDialogHandler), GetEventTypeCount (handlerEvents), handlerEvents, (void*)window, &handler); } if(err == noErr) { RunAppModalLoopForWindow(window); } if(window != NULL) { DisposeWindow(window); } if(nib != NULL) { DisposeNibReference(nib); } return(err); }