Darkmode

didn’t I read somewhere there was now an EVENT to detect if a transition from light to dark or vice-versa had occured?

Yes, https://documentation.xojo.com/api/deprecated/application.html#application-appearancechanged

thanks… just found it:)

Its not searchable in the LR

Guess I’m having a brain freeze here. Since that occurs in the APP “object” and there may or may not be any number of Windows open, and those windows may or may not contain custom controls that need to “know” that this change happened, how best to propogate that event through out the objects that need to know?

I don’t need to worry about dark mode so I had not thought about it… but that should have been an event on the window and containerControl Classed…

What i would do is subclass window container control to add such an event…

When it is raised in app i would use the Window function to iterate through all open windows and raise that event on each one that is that subclass.

That in turn that window subclass could itterate through it’s controls and send that message to all of it’s controls that have been subclassed to implement an appearance changed interface (using IsA)…

Or alternatively have all such controls register with that window subclass instance in their open event (and deregister in close)

  • Karen

too bad you can’t subclass a Window… (this was just discussed on another thread)

And this is a existing (rather complex) app with dozens of windows, and I figured a Darkmode retro fit would be “easy”

I managed to get most the controls to recognize Darkmode, except for the hundreds of bevelbuttons (working on a replacement already).

So the app works fine in what ever mode is active, when it begins, but if you switch while its running, only some things (the window itself for example) will change modes. Something needs to trigger an invalidate/refresh for each control

[quote=418137:@Dave S]too bad you can’t subclass a Window… (this was just discussed on another thread)
[/quote]

Yes you can… Just have to to do it before you add any controls. I have done it many times over the years.

Try it.

Add a class (myWindowSubclass) and set it’s super to Window…

How to use it… Create a window normally and add controls… THEN set that Windows Super To myWindowSubclass.

  • karen

Changing the appearance to dark mode should be causing all Paint events again so that one can draw the difference properly. If it’s not, file a feedback case (I know you won’t, but standard phrase).

The App.AppearcanceChanged event, and the two new constants in R4 are specifically for people who are drawing wrong.

That makes sense… though then why does the appearanceChanged Event exist at all? It just confuses things.

BTW I wish people would stop thinking Window can’t be subclassed… It’s not often needed but it can be done to good effect when it is…

  • karen

Karen… even if what you say is true (and I’m going by what Jason said just the other day)… That would require that I recreate basically my entire application…

Tim… so far the controls I am NOT seeing this happen on are custom controls not based on a canvas… those that don’t have a specific “paint” event. I have not yet observed it happening (or not) on a canvas based control… but I will soon as I am working on a “darkmode” compatible “Icon Button”. I could have sworn that I had read that ALL Xojo controls were native (at least for macOS) with the sole exception of the Listbox… .but in fact it turns out the BevelButton also in NOT native, so this is what my replacement is for, as I need Icons and Captions together

At least one user argued for it during the beta phase. There was discussion where almost everyone agreed there was no need for it. In fact, your point about confusing things came up too.

The BevelButton that Xojo is using is so outdated Apple didn’t update it for Dark Mode. I’d wager it’s from 1998.

per the LR

[quote]
BevelButton is not a native Cocoa control and does not automatically change its appearance in dark mode.
[/code]

FYI… The closest equivalent of BevelButton in macOS (ie. Swift) is in fact 100% Darkmode compatible

[quote=418141:@Dave S]Karen… even if what you say is true (and I’m going by what Jason said just the other day)… That would require that I recreate basically my entire application…
[/quote]

As the paint events fire there is no need (and I should have thought of that)… But I wanted to make sure that the idea that Window can’t be subclassed is not propagated because it’s not true and sometime is useful

it’s a technique I have used a few times over the years, and (when designing a new app) knowing you can do it can be useful.

  • Karen

I set some colours for custom controls in the open event. After the AppearanceChange event I send a notification to all windows

Open event:

NotificationManager.AddReceiver self, "AppearanceChanged" setColors

Notify method:

Public Sub Notify(Message As String, UserData As Variant) setColors End Sub

Have no fear! I was thinking that, too - I am using a lot of ContainerControls (> 100) that contain (sometimes a lot of) special TextEdit SubClasses that I created years ago (giving me dates or numbers or special formed “product codes” instead of simple strings).

I was so used to them that I had totally forgotten they use custom colors to make them look a bit less harsh in what we all got used to over the years (“Not Dark Mode” - is that called “Light Mode” in english?)

Anyway - I tinkered about a day with the container controls and found that in fact they can be subclassed (as windows, see above) - so I hooked into the “Paint” Event of the subclassed ContainerControl, iterate through all the controls that are in there - set the colors accordingly. After the day of tinkering around (adding a “AppearanceChanged” function to my ContainerControl and TextEdit classes to set the colors accordingly) - I found that I only have to go through all open windows and all controls they contain and call “AppearanceChanged”. That’s it.

I was very brave just a few minutes ago and did a project-wide search & replace for ContainerControl → workContainerControl. That’s it - the app is dark mode ready (at least 99% of it). Looks very “native” - except for the Bevel Buttons, that’s true… They are much to bright in dark mode. But that’s … next.

Appearance changed is not solely for notification about switching to dark mode. It is called when a user switches between Light and Dark mode or when the accent color changes.

[quote=418176:@Jan Redepenning]
Have no fear! I was thinking that, too - I am using a lot of ContainerControls (> 100) t[/quote]
I am talking about WINDOWS with are fundamentaly different than container controls.

I use ContainerControls only as a base container for custom controls… but thanks

[quote=418298:@Dave S]I am talking about WINDOWS with are fundamentaly different than container controls.

I use ContainerControls only as a base container for custom controls… but thanks[/quote]

Actually for this purpose they are not that different … Both can be subclassed the same way and Jan’s methodology would work with them as well.

  • karen

My point is… I cannot afford to rebuild 27 windows , since as you yourself said… to subclass a window must be done before controls are placed on it… meaning I would have to create a window subclass, and replace basically the entire code base, something I don’t have the resources to do, nor do I believe the ROI would be even close to break even…

I will either find another way (Paint Event seems to be working for the most part)… or scrap the idea of a darkmode retro fit.

Dave I think you are bit hazy on the concept.
I meant you can’t create a subclass FROM a window with controls on it… You can however create the subclass the Window Class independently then assign that as the super to windows that have controls on it… And you can even do that with search and replace.

That is what Jan was saying

  • karen