Hello,
in the appearanceChanged event of app I have this code:
for i as Integer = 0 to WindowCount-1
if Window(i) isa versionsWin then
if IsDarkMode then
versionsWin.RoundRectangle1.FillColor = kClrDarkMode
else
versionsWin.RoundRectangle1.FillColor = kClrWhite
end if
exit
end if
next
Switching between light and dark mode works OK when the window is not a floating window.
But if I make the window a floating window, RoundRectangle1 does not react; it remains the same as in light mode.
So I put the code into the paint event of the floating window, and now RoundRectangle1 changes its color all right:
if IsDarkMode then
RoundRectangle1.FillColor = backClrDM
else
RoundRectangle1.FillColor = recBackClr
end if
Hence my question: is it safe to move into the paint event of all windows their own code that at present resides in appearanceChanged, even if a window would not necessarily need a paint event?
for i as Integer = 0 to WindowCount-1
if Window(i) isa versionsWin then
if IsDarkMode then
versionsWin( Windows(i) ).RoundRectangle1.FillColor = kClrDarkMode
else
versionsWin( Windows(i) ).RoundRectangle1.FillColor = kClrWhite
end if
exit
end if
next
g.ForeColor = aBrightColor
if IsDarkMode then g.ForeColor = aDarkColor
No:
if IsDarkMode then me.FillColor = someOtherColor
if IsDarkMode then me.BackDrop = anotherPicture
Please do not change Control properties in the .Paint-Event. This may lead to unexpected behavior (especially on TargetWindows), since that Property-assignment could trigger yet another .Invalidate of the Control (called by the Xojo Framework) which is leading to an endlessly repeating Invalidation-Paint-Loop).
If that’s your only option… then at the very least please do it like this (to avoid unnecessary Property assignments):
Dim useColor As Color = aLightColor
if IsDarkMode then useColor = aDarkColor
if (me.FillColor <> aLightColor) then me.FillColor = aLightColor
[quote=418710:@Jürg Otter]g.ForeColor = aBrightColor
if IsDarkMode then g.ForeColor = aDarkColor[/quote]
Just to clarify… you could use g.FillRoundRect and g.DrawRoundRect in the paint event of the window or a canvas with the appropriate color based on IsDarkMode rather than a RoundedRect control.
Actually yesterday I had replaced the roundRectangle with a canvas, but since in DarkMode I noticed that the angles did not show “clean”, I had reverted using a roundRectangle.
Well, this morning I tried again using a canvas with the same code of yesterday, and everything looks all right. All is well that ends well (google translation of the idiom: tutto bene quello che finisce bene). Thanks.
Hi,
as I said in one of my posts above, I moved various codes requiring different colors for certain objects in the paint event of the object’s window. For instance, if my textArea.backcolor is set to Yellow but in DarkMode should switch to Blue, the window’s paint event handles it:
(paint event handler)
dim mBackColor as color = color.yellow
if isDarkMode then mBackColor = color.blue
myTextArea.backcolor = mBackColor
Now, my textArea.text contains certain words in colors different in Light and DarkMode, handled by a “resetColors” method. So, in the paint event of the window I added:
if myTextArea.text <> “” then
resetColors
end if
Then I noticed that myTextArea kept redrawing when I changed the size of the window or edited the text etc. Therefore I realized what I should have been aware of, i.e. the paint event draws continually.
Of course, I moved the call to resetColors to the app.appearanceChanged event.
So I’m now wondering if the idea of keeping all code (the above snippet is just an instance, but I have more calls for controls that do not auto-change their colors when changing appearance) in the paint events of windows is really a good idea, and I’m tempted to go back and make use of the app.appearanceChanged event.
[quote=428640:@Carlo Rubini]So I’m now wondering if the idea of keeping all code (the above snippet is just an instance, but I have more calls for controls that do not auto-change their colors when changing appearance) in the paint events of windows is really a good idea, and I’m tempted to go back and make use of the app.appearanceChanged event.
Suggestions and advice welcome. Thank you.[/quote]
Indeed, recoloring, recommended by Apple, should be done in the paint event. Changing colors as you do can be done in the AppearanceChanged event, given you manually change them. You should be fine.
If you ever are going to use Apple-named colors like “textColor” then it is mandatory to call “textColor” in the paint event. The AppearanceChanged event should not be used to call “textColor” because the system is not ready yet to change “textColor” to dark or light mode. Using light-dark aware NSColors does not even require the AppearanceChanged event, it just signals an upcoming change and it is safe as well as mandatory to use the paint event…