예제 #1
0
OSStatus MakeWindowTransparent(WindowRef aWindowRef)
{
    OSStatus status = paramErr;
    require(aWindowRef != NULL, paramErr);

    // is the window compositing or not?
    WindowAttributes attributes;
    status = GetWindowAttributes(aWindowRef, &attributes);
    require_noerr(status, GetWindowAttributes);

    /*	if (attributes & kWindowCompositingAttribute)
    	{
    		// it is compositing so we intercept the kEventWindowGetRegion event to be able to specify an empty opaque region
    		EventTypeSpec wCompositingEvents = { kEventClassWindow, kEventWindowGetRegion };
    		status = InstallWindowEventHandler(aWindowRef, TransparentWindowHandler, 1, &wCompositingEvents, aWindowRef, NULL);
    		require_noerr(status, InstallWindowEventHandler);

    		HIViewRef contentView;
    		status = HIViewFindByID(HIViewGetRoot(aWindowRef), kHIViewWindowContentID, &contentView);
    		require_noerr(status, HIViewFindByID);

    		// and we intercept the kEventControlDraw event of our content view so that we can make it transparent
    		EventTypeSpec cCompositingEvents = { kEventClassControl, kEventControlDraw };
    		status = InstallControlEventHandler(contentView, TransparentWindowHandler, 1, &cCompositingEvents, contentView, NULL);
    		require_noerr(status, InstallControlEventHandler);
    	}
    	else*/
    {
        // it is non-compositing so we intercept the kEventWindowGetRegion event to be able to specify an empty opaque region
        // and we intercept the kEventWindowDrawContent event of our window so that we can make it transparent
        EventTypeSpec wNonCompositingEvents[] =
        {
            { kEventClassWindow, kEventWindowGetRegion },
            { kEventClassWindow, kEventWindowDrawContent }
        };
        status = InstallWindowEventHandler(aWindowRef, TransparentWindowHandler, GetEventTypeCount(wNonCompositingEvents), wNonCompositingEvents, aWindowRef, NULL);
        require_noerr(status, InstallWindowEventHandler);
    }

    // telling the HIToolbox that our window is not opaque so that we will be asked for the opaque region
    UInt32 features;
    status = GetWindowFeatures(aWindowRef, &features);
    require_noerr(status, GetWindowFeatures);
    if ( ( features & kWindowIsOpaque ) != 0 )
    {
        status = HIWindowChangeFeatures(aWindowRef, 0, kWindowIsOpaque);
        require_noerr(status, HIWindowChangeFeatures);
    }

    // force opaque shape to be recalculated
    status = ReshapeCustomWindow(aWindowRef);
    require_noerr(status, ReshapeCustomWindow);

    // ensure that HIToolbox doesn't use standard shadow style, which defeats custom opaque shape
    status = SetWindowAlpha(aWindowRef, 0.999);
    require_noerr(status, SetWindowAlpha);

SetWindowAlpha:
ReshapeCustomWindow:
HIWindowChangeFeatures:
GetWindowFeatures:
InstallControlEventHandler:
HIViewFindByID:
InstallWindowEventHandler:
GetWindowAttributes:
paramErr:

    return status;
}
예제 #2
0
/*
	Handle events of kEventClassControl that get sent to the Frame
*/
OSStatus HandleStarFrameControlEvents(
	EventHandlerCallRef inCallRef,
	EventRef inEvent,
	StarFrameData* frameData)
{
	OSStatus retVal = eventNotHandledErr;

	switch(GetEventKind(inEvent)) {
		case kEventControlInitialize :
			retVal = HandleStarFrameInitialize(inCallRef, inEvent, frameData);
		break;

		case kEventControlOwningWindowChanged : {
			// We only want the star-shaped opaque area of our frame view to
			// draw.  Everything else should be transparent.  To accomplish that
			// we change the features of the owning window so that only the
			// content we draw shows up on screen
			WindowRef newWindow = GetControlOwner(frameData->hiSelf);
			HIWindowChangeFeatures(newWindow, 0, kWindowIsOpaque);
		} break;

		case kEventControlBoundsChanged : {
			retVal = HandleStarFrameBoundsChanged(inCallRef, inEvent, frameData);
		} break;

        case kEventControlDraw : {
			HIRect			bounds;
			CGContextRef	cgContext;

			HIViewGetBounds(frameData->hiSelf, &bounds);
			float radius = fmin(CGRectGetWidth(bounds) / 2.0, CGRectGetHeight(bounds) / 2.0);

			GetEventParameter(inEvent, kEventParamCGContextRef, typeCGContextRef, NULL, sizeof(cgContext), NULL, &cgContext );
			if(NULL != cgContext) {
				HIThemeMenuDrawInfo drawInfo;
				CGPathRef starPath = CreatePathForStarFrame(frameData, radius);

				drawInfo.version = 0;
				drawInfo.menuType = frameData->menuType;

				// HIThemeDrawMenuBackground is designed to draw the pin striped background
				// of standard menus.  Our menu is a star and so HIThemeDrawMenuBackground may not be
				// appropriate in this case.  Nevertheless, we'll draw the standard menu background for
				// this menu and clip it to a star.
				CGContextClearRect(cgContext, bounds);
				CGContextSaveGState(cgContext);
				CGContextTranslateCTM(cgContext, radius, radius);
				CGContextAddPath(cgContext, starPath);
				CGContextClip(cgContext);
				CGContextTranslateCTM(cgContext, -radius, -radius);
				HIThemeDrawMenuBackground(&bounds, &drawInfo, cgContext, kHIThemeOrientationNormal);
				CGContextRestoreGState(cgContext);

				// The pin striping looks a bit odd sort of floating out by itself.  We'll also add
				// a lovely gray line to help emphasize the boundary
				CGContextTranslateCTM(cgContext, radius, radius);
				CGContextAddPath(cgContext, starPath);
				CGContextSetRGBStrokeColor(cgContext, 0.8, 0.8, 0.8, 1.0);
				CGContextSetLineWidth(cgContext, 1.0);
				CGContextStrokePath(cgContext);
				
				CGPathRelease(starPath);
				starPath = NULL;
			}

			retVal = noErr;
		} break;

		// Mac OS X v10.4 introduced a Window Manager bug.
		// The workaround is to implement the kEventControlGetFrameMetrics handler.
		// Even after the bug is fixed, the workaround will not be harmful.
		case kEventControlGetFrameMetrics: {
			HIViewRef contentView = NULL;

			// If we can find our content view, ask it for our metrics
			verify_noerr(HIViewFindByID(frameData->hiSelf, kHIViewWindowContentID, &contentView));
			if(NULL != contentView) {
				retVal = SendEventToEventTargetWithOptions( inEvent, GetControlEventTarget( contentView ), kEventTargetDontPropagate );
			}
		} break;

		default:
		break;
	}

	return retVal;
}
예제 #3
0
void MCStack::realize()
{ //create window
	if (!MCnoui && MCModeMakeLocalWindows())
	{
		if ( getextendedstate(ECS_FULLSCREEN) )
		{
		//TS-2008-08-01 : [[Bug 5703 - fullscreen stack prop interacts badly with HideMenuBar]]
			if (!((MCScreenDC*)MCscreen)->getmenubarhidden())
				SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar);

			const MCDisplay *t_display;
			t_display = MCscreen -> getnearestdisplay(rect);
			MCRectangle t_workarea, t_viewport;
			t_workarea = t_display -> workarea;
			t_viewport = t_display -> viewport ;
			setrect(t_viewport);
		}
		else
		{
			if (!((MCScreenDC*)MCscreen)->getmenubarhidden())
				SetSystemUIMode(kUIModeNormal, NULL);
		}

		Rect wrect;
		MCScreenDC *psdc = (MCScreenDC *)MCscreen;
		psdc->MCRect2MacRect(rect, wrect);
		window = new _Drawable;
		window->type = DC_WINDOW;
		window->handle.window = 0;
		char *tmpname = NULL;
		const unsigned char *namePascal;
		if (!isunnamed())
		{ //set window title to name of stack temporarily.
			tmpname = strclone(getname_cstring()); //it will be changed by setname() later.
			namePascal = c2pstr(tmpname);
		}
		else
			namePascal = (unsigned char*)"\p";

		loadwindowshape();


		window->handle.window = NULL;
		uint32_t wclass;
		uint32_t wattributes;
		getWinstyle(wattributes,wclass);
		
		wattributes |= kWindowCompositingAttribute;

		long testdecorations = WD_TITLE | WD_MENU | WD_CLOSE | WD_MINIMIZE | WD_MAXIMIZE;

		if (m_window_shape != NULL)
		{
			static WindowDefUPP s_window_mask_proc = NULL;
			if (s_window_mask_proc == NULL)
				s_window_mask_proc = NewWindowDefUPP(WindowMaskProc);
			
			WindowDefSpec t_spec;
			t_spec . defType = kWindowDefProcPtr;
			t_spec . u . defProc = s_window_mask_proc;
			
			CreateCustomWindow(&t_spec, wclass, wattributes, &wrect, (WindowPtr *)&window -> handle . window);
			HIWindowChangeFeatures((WindowPtr)window -> handle . window, 0, kWindowIsOpaque);
		}
		else if (((flags & F_DECORATIONS && !(decorations & testdecorations))
		          || wclass == kPlainWindowClass))
		{
			static WindowDefUPP s_borderless_proc = NULL;
			if (s_borderless_proc == NULL)
				s_borderless_proc = NewWindowDefUPP(BorderlessWindowProc);
				
			WindowDefSpec t_spec;
			t_spec . defType = kWindowDefProcPtr;
			t_spec . u . defProc = s_borderless_proc;

			if (wclass == kPlainWindowClass)
				wclass = kUtilityWindowClass;

			CreateCustomWindow(&t_spec, wclass, wattributes, &wrect, (WindowPtr *)&window->handle.window);
		}
		else
			CreateNewWindow(wclass, wattributes,&wrect, (WindowPtr *)&window->handle.window);

		if (wclass == kFloatingWindowClass)
			ChangeWindowAttributes((WindowPtr)window -> handle . window, kWindowNoAttributes, kWindowHideOnSuspendAttribute);
		
		// MW-2009-10-31: Make sure we can collapse any rev window
		HIWindowChangeFeatures((WindowPtr)window -> handle . window, kWindowCanCollapse, 0);
		
		if (window->handle.window == NULL)
			SetWTitle((WindowPtr)window->handle.window, namePascal);
		SetWTitle((WindowPtr)window->handle.window, namePascal);
		setopacity(blendlevel * 255 / 100);
		SetWRefCon((WindowPtr)window->handle.window, mode);
		
		ControlRef t_control;
		MCRevolutionStackViewCreate(this, &t_control);
		ControlRef t_root_control;
		GetRootControl((WindowPtr)window -> handle . window, &t_root_control);
		HIViewAddSubview(t_root_control, t_control);
		ShowControl(t_control);
		
		if (wclass == kDrawerWindowClass)
		{
			Window pwindow = NULL;
			if (parentwindow != DNULL)
				pwindow = parentwindow;
			else
				if (MCdefaultstackptr && MCdefaultstackptr->getw() != DNULL )
					pwindow = MCdefaultstackptr->getw();
			if (pwindow && GetWRefCon((WindowPtr)pwindow->handle.window) != WM_DRAWER)
			{
				SetDrawerParent((WindowPtr)window->handle.window, (WindowPtr)pwindow->handle.window);
				WindowAttributes watt;
				GetWindowAttributes((WindowPtr)pwindow->handle.window,&watt);
				if (wattributes & kWindowResizableAttribute)
					ChangeWindowAttributes((WindowPtr)pwindow->handle.window, kWindowLiveResizeAttribute, 0);
				OptionBits draweredge;
				switch (wposition)
				{
				case WP_PARENTTOP:
					draweredge = kWindowEdgeTop;
					break;
				case WP_PARENTRIGHT:
					draweredge = kWindowEdgeRight;
					break;
				case WP_PARENTBOTTOM:
					draweredge = kWindowEdgeBottom;
					break;
				case WP_PARENTLEFT:
					draweredge = kWindowEdgeLeft;
					break;
				default:
					draweredge =  kWindowEdgeDefault;
					break;
				}
				SetDrawerPreferredEdge((WindowPtr)window->handle.window, draweredge);
				if (walignment)
				{
					MCRectangle parentwindowrect;
					MCscreen->getwindowgeometry(pwindow, parentwindowrect);
					int2 wspace = 0;
					RgnHandle r = NewRgn();
					GetWindowRegion((WindowPtr)window->handle.window, kWindowStructureRgn, r);
					Rect tRect;
					GetRegionBounds(r, &tRect);
					DisposeRgn(r);
					MCRectangle drawerwindowrect;
					psdc->MacRect2MCRect(tRect, drawerwindowrect);
					if (wposition == WP_PARENTTOP || wposition == WP_PARENTBOTTOM)
					{
						wspace = parentwindowrect.width - drawerwindowrect.width;
						if (watt & kWindowMetalAttribute)
							if (wspace)
								wspace += 10; //for metal
					}
					else
					{
						wspace = parentwindowrect.height - drawerwindowrect.height;
						if (watt & kWindowMetalAttribute)
							if (wspace)
								wspace += 5; //for metal
					}
					if (wspace > 0)
						switch (walignment)
						{
						case OP_CENTER:
							SetDrawerOffsets ((WindowPtr)window->handle.window,ceil(wspace/2) -1,floor(wspace/2) + 1);
							break;
						case OP_RIGHT:
						case OP_BOTTOM:
							SetDrawerOffsets ((WindowPtr)window->handle.window,wspace,0);
							break;
						case OP_TOP:
						case OP_LEFT:
							SetDrawerOffsets ((WindowPtr)window->handle.window,0,wspace);
							break;
						}
				}
			}
		}
		delete tmpname;


		// MW-2005-11-06: We also need to catch window constraining events so we can flush
		//   the screen geometry cache.
		EventTypeSpec list[] =
		{
		
			{kEventClassWindow, kEventWindowCollapsed},
			{kEventClassWindow, kEventWindowExpanded},
			{kEventClassMouse, kEventMouseWheelMoved},
			{kEventClassWindow, kEventWindowBoundsChanging},
			{kEventClassWindow, kEventWindowBoundsChanged},
			{kEventClassWindow, kEventWindowConstrain},
			{kEventClassWindow, kEventWindowFocusAcquired},
			{kEventClassWindow, kEventWindowFocusRelinquish},
			{kEventClassWindow, kEventWindowActivated},
			{kEventClassWindow, kEventWindowDeactivated},
			{kEventClassWindow, kEventWindowClose},
		};

		EventHandlerRef ref;
		
		// MW-2005-09-07: Pass the window handle as user data, otherwise 'takewindow' causes problems
		InstallWindowEventHandler((WindowPtr)window->handle.window, MCS_weh, sizeof(list) / sizeof(EventTypeSpec), list, (WindowPtr)window -> handle . window, &ref);
		
		ChangeWindowAttributes((WindowPtr)window->handle.window, 0, kWindowHideOnFullScreenAttribute);
		
		updatemodifiedmark();
	}
	start_externals();
}