Focus rings & container controls

anyone have a snippet to draw a proper focus ring around a container control ?

#If TargetWindows
  Dim rc As New MemoryBlock (16)
  rc.Int32Value (0) = 0
  rc.Int32Value (4) = 0
  rc.Int32Value (8) = 100
  rc.Int32Value (12) = 100
  Soft Declare Function DrawFocusRect Lib "user32" (ByVal hdc As Integer, lpRect As Ptr) As Integer
  Call DrawFocusRect (g.Handle (Graphics.HandleTypeHDC), rc) 

rc is a RECT with left, top, right, bottom

I have written the code to supply a mask for the focus ring on the Mac. I use it in Iconographer Mini to have rounded corners on it’s focus ring.

However it’s not really a snippet as you have to hack the XOJCanvas class to capture and override the event.

Edit: Oh wait, you said container control, not canvas. You’re still required to capture and overwrite the event, but I don’t know what NSClass the Xojo Container Controls use.

It’s also hard to fake on the Mac as focus rings are drawn outside of the control, drop rings are drawn inside. You can enabled outside drawing with a declare, but more hacking and you lose auto clamping control drawing.

I suppose I could put a canvas in the container and have it be the same size then use that
not sure if that would give me clipping issues
I’m already managing “when” to draw the focus ring

If you inset the contents of your container by 4px (IIRC), then make your container larger than it needs to be (so the content is the correct size), it will look close.

Hopefully close enough. This is one of those things that is trivial if you use Apple’s tools and languages. I’m certain it can be done through Xojo, but as I’ve not tried to do it via a Container control, I don’t know what else has to be discovered to get it to work.

yeah not sure I will have 4 px as I’m using a container to make a custom “combobox” - more or less
so size wise the container has to be about right
I’ll poke about some more
maybe I can find something usable

Trying to fake focus rings was the reason I looked into properly handling it.

You could put a canvas into the container control, but the editfield would get the focus. So really you’d have to hack the edit field, and then provide a mask for the canvas.

Seems like trouble to me. Especially as when you hack a Xojo class, you then receive events for all instances of the Xojo class, not just your subclasses.

yeah :frowning:
I have it correctly drawing a faked focus ring around the entire control just for debugging purposes
but would love to be ablke to draw a correct one
I just dont see a nice way to do that on macOS ( the primary target )

but, it may not be needed (which would be even nicer, as then I can get rid of what I do for debugging entirely :slight_smile:

Maybe the old carbon functions for drawing the focus ring still work, I haven’t looked.

It’s only complicated for us, because of the choice of development tool. If we’d used Xcode, it is a non-issue. Subclass, capture event, provide mask, job done.

what NS control type is the container control?
an NSView?

Very likely the handle refers to a NSview
Never looked at that in the Xcode view hierarchy explorer & now it seems to not be able to do that any more :frowning:

<XOJCanvasView: 0x7f9987a35e30> (Controller: 0x600003e5ba20; Owner: 0x600002245770; RunControl: EmbeddedWindowControl) superClass: XOJView

To capture the Focus Ring event.

call class_replaceMethod( canvasClass, NSSelectorFromString( "drawFocusRingMask" ), addressOf handleDrawFocusRingMask, "v@:" )

Then use NS drawing functions, like NSRectFill.