I use a canvas overlay over the top of other controls to pick up drag and drop events and perform some graphics effects.
With most of the Xojo controls (textArea, checkbox etc) any mouse click on the canvas will fall-through to the underlying controls without problem - which is what I want.
However, if I change a textArea to one extended by MacOSLib or use an nsTextFieldControlMBS from MonkeyBread then the mouse click no longer falls through to the underlying control.
Does anyone know why that happens and what I might to to correct it?
Is the Canvas placed as a child of the control or is it just placed last over controls?
If the Canvas is a child I think what’s happening is MacOSLib and MBS are adding a new subview to the TextArea that covers you’re Canvas that was added by Xojo previously. So at some time after MacOSLib/MBS does it’s thing you need to move the Canvas to the top of the TextAreas subviews, not sure the best way to do that. Maybe something as simple as…
Canvas1.Parent = nil //remove from subviews
Canvas1.Parent = mySoupedUpTextArea //add back at top
Thanks for that. I had not played with the parent property before.
In a simple test file I find that setting:
mySoupedUpTextArea.parent = canvas1
in the window open event does work - canvas mouse events drop through to the textArea, though interestingly mySoupedUpTextArea now gets cropped by the boundaries of canvas1.
But, applying this to the containerControl where the real mySoupedUpTextArea resides, overlaying the TextArea with Canvas1 and applying mySoupedUpTextArea.parent = canvas1 in the containerControl’s open event results in an app crash.
The report from OSX shows:
0 com.apple.AppKit 0x9361e624 NSViewGetVisibleRect + 12
1 com.apple.AppKit 0x9361e6b9 NSViewGetVisibleRect + 161
2 com.apple.AppKit 0x9361e6b9 NSViewGetVisibleRect + 161
3 com.apple.AppKit 0x9361e6b9 NSViewGetVisibleRect + 161
on and on for 512 loops.
Obviously close to a solution, but not quite there yet.
Any more ideas?
This should be the other way round, that’s making the TextArea a child of the Canvas which is why its getting cropped.
I’m not sure what interactions are happening here. Is Canvas1 part of the ContainerControl or part of the Window? Is Canvas1 only for overlaying a single TextArea or is it supposed to encompass several controls?
And what are the changes you’re making to the TextArea? I looked in MacOSLib and don’t see any TextAreaExtensions that add a subview so maybe something else is stealing clicks.
The crash log shows a cyclic path was made somehow in the view hierarchy. I get the same thing by adding 2 Canvases to a window and setting their Parents to each other. …ah I see, if you placed the Canvas as a child of the TextArea in the Xojo IDE then doing “myTextArea.Parent = Canvas1” also makes the TextArea a child of the Canvas, so GetVisibleRect is spinning between those two.
Anyways, I’m not so sure it’s subview placement that’s the problem. Let me know what MacOSLib feature is making this happen and I’ll test it out.
I tried it around the other way, but it would not work. It works better (in some cases) where mySoupedUpTextarea.parent = canvas1 because canvas 1 is over the top of the text area. Canvas1 also covers other objects.
I may be getting my parents/children relationships muddled but I would have thought the canvas Overlay would have been the parent, and the textArea the child as the canvas may cover more than just one object. The other way around would mean that the canvas would need multiple parents - obviously not - even in this day and age.
The overall structure I have is one of several layers of canvases and containerControls of the following form - sorry about the psychodelics but this was the best I could come up with to illustrate the problem as there are multiple layers of container controls and canvases above the textAreas.
The only extension I am using at the moment is RTFValue for setting the content - I will be using others but have to get over this hurdle first.
Using an unextended textArea works fine - the mouse clicks fall through to the textAreas as indicated. But adding the MacOSLib extensions seems to break that.
Any other guidance you can give would be helpful.
O_o (’< (>’.’)> :S no, very helpful
In the view hierarchy children are on top of the parent, so in your graphic the children of ccProject are cnvFade and ccPageView. When I’ve done Canvas overlays it was for one control and I’d put it on-top/as-child of the control. I thought you might be doing it that way and MacOSLib/MBS was adding another view on top, but you’re not doing it that way.
You’re doing a Canvas outside the controls but overlapping and I don’t see how MacOSLib/MBS could do anything to change that, plus RTFValue doesn’t add a subview anyways. So I’m thinking it must be something else. Are you sure RTFValue is the only difference between working and not working? I can’t reproduce the problem, do you have a minimal example you can show?
I have been playing around with this a bit more. I removed all the MBS/MacOSLib stuff from Xojo and find that this is not specific to those enhancements but is related to Xojo’s vanilla textarea.
Place 2 text areas on a window. Put a canvas over the top of both, run it and you will see that you cannot reliably click between the two text areas. It might work once, but not multiple times.
Now, using your reparenting method, in the window’s Open event, reparent:
textArea1.parent = canvas1
textArea2.parent = canvas2
Now, on running, you can reliably click between the two textAreas.
The challenge now comes when embedding these within containerControls to multiple levels, each with its own set of overlay canvases. You can demo this by doing the simple structure above in a containerControl rather than a window (change the class), then put the container control into a new Window and overlay another canvas. Again you can only click through the canvas if you reparent the containerControl to the overlay canvas.
So I guess its a Xojo bug. I see now that it has been reported in 29669 and 32772 which I will update.
The work around seems to be one of having to reparent all containerControls all the way down the view hierarchy.
I still seem to have some problems related to containerControls which are embedded on-the-fly - and will report back in due course.
With regard the embedded-on-the-fly container controls. The problem here is that a newly constructed and embedded containerControl goes to the front of the containerControl/Window into which it is embedded. Any overlaid Canvas therefore gets pushed back from the overlay position. I tried reparenting the new containerControls to the canvas but this seems to cause greater confusion. My solution in the end was to remove any overlay Canvasses from the containerControl where stuff was being created on the fly, and instead move those canvases to a containerControl at a lower level in the hierarchy.
But, as seems to be the way all to often, having fixed the problem of click-through to the textAreas, the canvasses that form their new parents no longer display their graphics events correctly. The paint events run, but nothing is shown on screen.
Does Xojo have a Samaritans dept. that stops people jumping from windows?
Ah I see, the problem is that for some reason the Focus isn’t being changed by Xojo, otherwise all the normal click activity seems to happen. So you just need to manually set focus and all works well as Thomas White mentions in <https://xojo.com/issue/32772>.
[code]Function MouseDown(X As Integer, Y As Integer) As Boolean
//any previous code
me.SetFocus //manually set missing focus
Or wrap it in a subclass and just change your TextArea supers
[code]Class OverlayableTextArea Inherits TextArea
Event MouseDown(X As Integer, Y As Integer) As Boolean
Function MouseDown(X As Integer, Y As Integer) As Boolean
dim b As Boolean = RaiseEvent MouseDown(X, Y)
Also, the idea of changing control parents is for a different situation and won’t help here, only munge things up
Ah, brilliant, in the end its so simple.
Thank you Will.