NSWindow shadow with transparency, how to clip certain area - macos

In our OS X application, we have enabled window shadow by view.window?.hasShadow = true. This will create a fine shadow over NSWindow. We have created a hole in the application by a custom view to see the background through it, via its mask layer.
Our problem is that the shadow is visible in the hole region too. Can we make the shadow not appear in the transparent region. We have searched, but didn't get anything to clip window shadow at certain area.
This shadow is creating some problem in the application
We have given a button to collapse/expand the view which have the hole. So the hole will enlarge and shrink according to that. At this time window will not recalculate the shadow. We have tried the view.window?.invalidateShadow(). But it doesn't has any effect.
We are drawing some texts over the transparent region. When the expand collapse happens we can see the traces of the text drawn. It will always be there.
Every thing comes fine if we resize the application, which will recalculate the shadow. How we can overcome these issue. What will be the work around.

Related

Resizing Layered Windows

I'm hoping I can get away with communicating the issue I'm having clearly without posting a ton of source code. The source is all ASM and while most would understand it, it's still not their primary "thing."
I have a layered window which is working perfectly - up to the point of resizing it. The window is all per-pixel alpha. There are no transparent pixels. The borders and caption are opaque (255 alpha); the client area is something like 128 alpha or whatever I put it at. So no transparent pixels.
I have a function that handles redraws - it's actually geared toward rebuilding the frame for a new window size. GetWindowDC is called on the layered window. CreateCompatibleDC creates off of that DC. The bitmap is a DIB section. The bitmap is properly sent to UpdateLayeredWindow. Again, everything works perfectly as long as the window is not in active resize (border drag).
I have tried using DefWindowProc to handle border drags, as well as completely handling all aspects of that functionality myself. The results are the same: massive flicker but ONLY beyond the window boundaries that existed before border drag began, and then the window size does not ultimately change - sort of. The original window area remains displayed without issue. No flicker there. However if (for example) I'm dragging the right border to the right, everything right of the original window right edge flickers rapidly then vanishes. When I release the left mouse button, the display remains at the original size (the size the window was before dragging the border). I've verified the bitmap is correctly rebuilt to the new size. It seems like the DC for the layered window doesn't want to resize because the entire area of original window size is completely stable, but any new area appearing post-resize flickers then hides.
I've even tried removing the ws_ex_layered style before resizing the window in my manual handling (I've tried both MoveWindow and SetWindowPos) then resetting the ex style after SetWindowPos / MoveWindow but before dragging.
When I let DefWindowProc handle the updates, I got the exact same result. So indications are that something is wrong with my repainting. But I even whittled that process down (commenting out oodles of code for test) and just filled the bitmap with 0xFF0000FF (arbitrary test value, blue, full opacity) then jumped straight to UpdateLayeredWindow. Same result.
The bitmap used for UpdateLayeredWindow is deleted before calling the "rebuild" function and within the function that bitmap is recreated to the new size. I have verified the new size extensively - I can see the new bitmap as it high-speed flickers and it's all good. The DC is GetWindowDC from the layered window. The compatible DC creates off that DC. The bitmap is selected into the compatible DC, and that compatible DC is passed to UpdateLayeredWindow. If any of these things were off, I would never see the new bitmap displayed. It's there - it just flickers at high speed ONLY beyond the window bounds that existed before resize began. DefWindowProc yields the same results. Within that original area, my caption buttons slide off to the right as I drag the right border to the right, further verifying everything is good.
I'm at a loss. Any input would be welcome.

Unable to Move the Canvas or Change Any of the Transform Values

I am using Unity 5 and I started to make a menu scene. When I made the canvas, all of values under the Rect Transform component are locked and it says "some values driven by Canvas." The only thing I can change is the z position when using the gizmo in the editor. I can't reset the position or anything. Why is this happening?
This means that the canvas's canvas component has it's render mode set to Screen space - overlay. This forces it to be the size of the screen. Change it to World Space and it will allow you to resize it and move it around.
Changing the Render mode is not an ideal solution; neither is Overlay mode the reason why this is happening at all. World Space is just a render mode that changes the way your whole UI behaves and would mean a whole different set up and a whole lot more work just to get a child UI object to move independently.
Here is the description of what World Space is for from the Unity site:
In this render mode, the Canvas will behave as any other object in the
scene. The size of the Canvas can be set manually using its Rect
Transform, and UI elements will render in front of or behind other
objects in the scene based on 3D placement. This is useful for UIs
that are meant to be a part of the world. This is also known as a
“diegetic interface”.
The Rect Transform usually gets locked because it is a child of another Canvas Object which controls its Transforms. The way to fix this is to overwrite it by adding a “Layout Element” component to it. From there you can configure it to work the way you like and it can have transforms independent of the Parent UI Object.
For full details, see this Unity support page: https://support.unity3d.com/hc/en-us/articles/115000179163-How-to-overwrite-Width-and-Height-values-that-are-driven-by-a-Layout-Group-in-runtime-
Canvas is depend on game tab in your window panel.
Adjust panel by use of close tab or resize panel or doc game panel.
It will help you make default 800 X 600 canvas.

JavaFX animations are flickering

I have a window displaying a video stream with a twitter feed as an overlay.
When a new tweet is displayed, the current tweet animates out using a rotate animation and the next tweet is rotated into view. The animations are performed using a RotateTransition.
The app also switches between different cameras to display different streams. To give an indication of when the app switches to the next camera, I have a progressbar that fills using a Timeline object.
This works well, until I resize the window. The rotate animations start to flicker, along with the progressbars as they gradually fill.
As a test, I disabled the video stream, to see what's happening. The 'artifact' doesn't occur then and I can resize as much as I want. If I play the stream and don't resize, everything works well.
The video player is based on VLCJ, but the actual pixels are drawn on a WritableImage in an Imageview.
See the following images that illustrate the problem.
At the bottom right you can see 2 different progress bars (a ProgresBar and a ProgressIndicator).
A part of the flickering result is still visible below the second image. It somehow stays visible, probably because the area doesn't get redrawn.
Any idea what makes the flickering happen? Is there anything I can do to fix or avoid this?
I tried some VM options in IntelliJ: -Dsun.java2d.d3d=true -Dprism.forceGPU=true to somehow enable hardware acceleration, but that doesn't seem to help.
Disabling the progressbar fill animation doesn't help either.
I had a similar problem with some arcs and shapes that would flicker when its attributes / sizes were changed.
The solution to my problem was to make sure that the methods used to change the shapes were called from inside the JavaFX thread.
Platform.runLater(() -> {
arc.setStartAngle(30);
arc.setLength(45);
}

NSWindow Content Border messing with CALayer's geometry

I have an NSWindow with a 32px bottom content border. Inside the window's view, I have two custom subviews. Each of them are layer backed, and I'm tracking the mouse with an NSTrackingArea. Part of what I'm doing is some mouseOver effects with CoreAnimation. This is not a problem in general, but I noticed something kind of strange and wondered if anyone knows why this is happening.
When setting up the trackingArea and mouseOver method, I hitTest the root layer and log the layer's name so I can see if the geometry of the various sublayers hold water when I resize the window. Internally, they seem (and look) fine. Visually, they are in the right place, but when I move the mouse, I notice that the though the mouse is physically over a layer, hitTest is returning whatever layer is 32 px above it. However, if I remove the content border, it works as you would expect and the correct layer is returned.
I obviously need the content border, so I have a very simple workaround which involves offsetting the hitTest point by 32px. This works fine, but it just seems weird that the presence of a content border seems to skewing the co-ordinate system of these subviews. Does anyone know why this could be happening?
NSEvent returns mouse locations relative to the window's coordinate system, not the targeted view's. You probably need to call convertRect:fromView: to get the correct coordinates.

Glow around Button

How can I draw a slight white 'glow' around a button or label in 10.5 and later? I have seen some apps do it, but I am still confused how I should do this.
See NSShadow. You'd create and set a shadow (saving your graphics context beforehand), then draw the basic shape of your button, unset it (by restoring your graphics context), then continue drawing as usual.
In the case of a ready-made control like NSButton, you will need to subclass and override its cell drawing (and possibly make the host NSButton control itself a bit larger to accommodate the larger area needed to encompass the "glow" of the cell).
You might be able to avoid this with a label by setting its font shadow, but I don't think IB lets you do this, so you'd programmatically give the label an attributed string (via its -setAttributedString: method). The attributes would include the NSShadow (configured as desired) as the NSShadowAttributeName.

Resources