void childBoundsChanged (juce::Component* child) { setSize (child->getWidth(), child->getHeight()); child->setTopLeftPosition (0, 0); #if JUCE_WIN32 resizeHostWindow (hostWindow, titleW, titleH, this); owner->updateSize(); #else Rect r; GetWindowBounds ((WindowRef) hostWindow, kWindowContentRgn, &r); HIRect p; zerostruct (p); HIViewConvertRect (&p, parentView, 0); // find the X position of our view in case there's space to the left of it r.right = r.left + jmax (titleW, ((int) p.origin.x) + getWidth()); r.bottom = r.top + getHeight() + titleH; SetWindowBounds ((WindowRef) hostWindow, kWindowContentRgn, &r); owner->updateSize(); owner->Invalidate(); #endif }
static void HIOpenGLViewSetContextWindowAndBounds (HIOpenGLViewData* inData) { if (inData == nil) return; if (inData->mControl == nil) return; if (inData->mContext == nil) return; // Determine the AGL_BUFFER_RECT for the control. The coordinate // system for this rectangle is relative to the owning window, with // the origin at the bottom left corner and the y-axis inverted. HIRect ctrlBounds, winBounds; HIViewGetBounds(inData->mControl, &ctrlBounds); WindowRef window = GetControlOwner(inData->mControl); ControlRef root = nil; GetRootControl(window, &root); HIViewGetBounds(root, &winBounds); HIViewConvertRect(&ctrlBounds, inData->mControl, root); GLint bufferRect[4] = { (int)ctrlBounds.origin.x, (int)((winBounds.size.height) - (ctrlBounds.origin.y + ctrlBounds.size.height)), (int)ctrlBounds.size.width, (int)ctrlBounds.size.height }; // Associate the OpenGL context with the control's window, and establish the buffer rect. aglSetDrawable(inData->mContext, GetWindowPort(window)); aglSetInteger(inData->mContext, AGL_BUFFER_RECT, bufferRect); aglEnable(inData->mContext, AGL_BUFFER_RECT); // Establish the clipping region for the OpenGL context. To properly handle clipping // within the view hierarchy, I'm walking the hierarchy to determine the intersection // of this view's bounds with its parents. Is there an easier way to do this? CGRect clipBounds = ctrlBounds; HIViewRef parent = HIViewGetSuperview(inData->mControl); while (parent != root) { CGRect parentBounds; HIViewGetBounds(parent, &parentBounds); HIViewConvertRect(&parentBounds, parent, root); clipBounds = CGRectIntersection(clipBounds, parentBounds); parent = HIViewGetSuperview(parent); } Rect rgnBounds = { (int)clipBounds.origin.y, (int)clipBounds.origin.x, (int)(clipBounds.origin.y + clipBounds.size.height), (int)(clipBounds.origin.x + clipBounds.size.width) }; RgnHandle rgn = NewRgn(); RectRgn(rgn, &rgnBounds); aglSetInteger(inData->mContext, AGL_CLIP_REGION, (const GLint*)rgn); aglEnable(inData->mContext, AGL_CLIP_REGION); }
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; } }
//-------------------------------------------------------------------------------------------------// void OSXCarbonWindow::windowMovedOrResized() { // External windows will call this method. if(mView != NULL) { // Determine the AGL_BUFFER_RECT for the view. The coordinate // system for this rectangle is relative to the owning window, with // the origin at the bottom left corner and the y-axis inverted. // Also, when leaving fullscreen, the display properties are not guaranteed to be // the same as when we were windowed previously. So resize the window and views back // to their original dimensions. HIRect newFrame = CGRectMake(mLeft, mTop+22, mWidth, mHeight); HIRect viewBounds = CGRectZero, winBounds = CGRectZero; SizeWindow(mWindow, mWidth, mHeight, true); HIViewSetFrame(mView, &newFrame); HIViewGetBounds(mView, &viewBounds); HIViewRef root = HIViewGetRoot(HIViewGetWindow(mView)); HIViewGetBounds(root, &winBounds); HIViewConvertRect(&viewBounds, mView, root); // Set the AGL buffer rectangle (i.e. the bounds that we will use) GLint bufferRect[4]; bufferRect[0] = viewBounds.origin.x; // 0 = left edge bufferRect[1] = winBounds.size.height - (viewBounds.origin.y + viewBounds.size.height); // 0 = bottom edge bufferRect[2] = viewBounds.size.width; // width of buffer rect bufferRect[3] = viewBounds.size.height; // height of buffer rect aglSetInteger(mAGLContext, AGL_BUFFER_RECT, bufferRect); aglEnable(mAGLContext, AGL_BUFFER_RECT); aglUpdateContext(mAGLContext); mLeft = viewBounds.origin.x; mTop = bufferRect[1]; } for (ViewportList::iterator it = mViewportList.begin(); it != mViewportList.end(); ++it) { (*it).second->_updateDimensions(); } }
//-------------------------------------------------------------------------------------------------// void OSXCarbonWindow::windowResized() { // Ensure the context is current if(!mIsFullScreen) { // Determine the AGL_BUFFER_RECT for the view. The coordinate // system for this rectangle is relative to the owning window, with // the origin at the bottom left corner and the y-axis inverted. HIRect newFrame = CGRectMake(mLeft, mTop+22, mWidth, mHeight); HIRect viewBounds = CGRectZero, winBounds = CGRectZero; SizeWindow(mWindow, mWidth, mHeight, true); HIViewSetFrame(mView, &newFrame); HIViewGetBounds(mView, &viewBounds); HIViewRef root = HIViewGetRoot(HIViewGetWindow(mView)); HIViewGetBounds(root, &winBounds); HIViewConvertRect(&viewBounds, mView, root); // Set the AGL buffer rectangle (i.e. the bounds that we will use) GLint bufferRect[4]; bufferRect[0] = viewBounds.origin.x; // 0 = left edge bufferRect[1] = winBounds.size.height - (viewBounds.origin.y + viewBounds.size.height); // 0 = bottom edge bufferRect[2] = viewBounds.size.width; // width of buffer rect bufferRect[3] = viewBounds.size.height; // height of buffer rect aglSetInteger(mAGLContext, AGL_BUFFER_RECT, bufferRect); aglEnable(mAGLContext, AGL_BUFFER_RECT); aglUpdateContext(mAGLContext); mLeft = viewBounds.origin.x; mTop = bufferRect[1]; } else { swapCGLBuffers(); } for (ViewportList::iterator it = mViewportList.begin(); it != mViewportList.end(); ++it) { (*it).second->_updateDimensions(); } }
//-------------------------------------------------------------------------------------------------// void OSXCarbonWindow::resize(unsigned int width, unsigned int height) { if(!mWindow) return; // Check if the window size really changed if(mWidth == width && mHeight == height) return; mWidth = width; mHeight = height; if (mIsExternal) { HIRect viewBounds = CGRectZero, winBounds = CGRectZero; HIViewGetBounds(mView, &viewBounds); HIViewRef root = HIViewGetRoot(HIViewGetWindow(mView)); HIViewGetBounds(root, &winBounds); HIViewConvertRect(&viewBounds, mView, root); mLeft = viewBounds.origin.x; mTop = winBounds.size.height - (viewBounds.origin.y + viewBounds.size.height); // Set the AGL buffer rectangle (i.e. the bounds that we will use) GLint bufferRect[4]; bufferRect[0] = mLeft; // 0 = left edge bufferRect[1] = mTop; // 0 = bottom edge bufferRect[2] = mWidth; // width of buffer rect bufferRect[3] = mHeight; // height of buffer rect aglSetInteger(mAGLContext, AGL_BUFFER_RECT, bufferRect); for (ViewportList::iterator it = mViewportList.begin(); it != mViewportList.end(); ++it) { (*it).second->_updateDimensions(); } } else { SizeWindow(mWindow, width, height, true); } }
//-------------------------------------------------------------------------------------------------// void OSXCarbonWindow::windowMovedOrResized() { // External windows will call this method. if(mView != NULL) { // Determine the AGL_BUFFER_RECT for the view. The coordinate // system for this rectangle is relative to the owning window, with // the origin at the bottom left corner and the y-axis inverted. HIRect viewBounds, winBounds; HIViewGetBounds(mView, &viewBounds); HIViewRef root = HIViewGetRoot(HIViewGetWindow(mView)); HIViewGetBounds(root, &winBounds); HIViewConvertRect(&viewBounds, mView, root); // Set the AGL buffer rectangle (i.e. the bounds that we will use) GLint bufferRect[4]; bufferRect[0] = viewBounds.origin.x; // 0 = left edge bufferRect[1] = winBounds.size.height - (viewBounds.origin.y + viewBounds.size.height); // 0 = bottom edge bufferRect[2] = viewBounds.size.width; // width of buffer rect bufferRect[3] = viewBounds.size.height; // height of buffer rect aglSetInteger(mAGLContext, AGL_BUFFER_RECT, bufferRect); aglEnable (mAGLContext, AGL_BUFFER_RECT); mWidth = viewBounds.size.width; mHeight = viewBounds.size.height; mLeft = viewBounds.origin.x; mTop = bufferRect[1]; } for (ViewportList::iterator it = mViewportList.begin(); it != mViewportList.end(); ++it) { (*it).second->_updateDimensions(); } }
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; } }