It is currently April 23rd, 2024, 1:33 pm

Rounding or ... Trunc-ing error :)

Report bugs with the Rainmeter application and suggest features.
User avatar
Yincognito
Rainmeter Sage
Posts: 7149
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Rounding or ... Trunc-ing error :)

Post by Yincognito »

I'm not sure if this is a bug or not (I would lean towards not), and hopefully any solution (if necessary, that is) won't affect too much backward compatibility, but here we go...

Introduction: As you can see from loading the skin below, Rainmeter yields the integer part (i.e. the equivalent of the TRUNC() function) of a fractional/decimal number when the :X, :Y, :XW and :YH section variable parameters are used on a meter. The 99.99 below is automatically transformed into the integer 99.

Issue: when the meter's X, Y, W and H are modified using a formula (like in this little skin that zooms in and out the red image on hover, leave, click and release), Rainmeter not only doesn't automatically convert to integers so that the zooming works properly (ok, this is to be expected, no big deal), BUT needs ROUND()-ing the results instead of TRUNC()-ing them, despite clearly needing the opposite as shown above. The skin below illustrates this, and as you can see, any hover style except the GlobalRound and Round one fail and move / shrink the red image:

Code: Select all

[Variables]
HoverScale=1.15

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1
BackgroundMode=2
SolidColor=47,47,47,255
SkinWidth=300
SkinHeight=300

---Styles---

[PlainHoverStyle]
MouseOverAction=[!SetOption #CURRENTSECTION# X ([#CURRENTSECTION#:X]-([#CURRENTSECTION#:W]*#HoverScale#-[#CURRENTSECTION#:W])/2)][!SetOption #CURRENTSECTION# Y ([#CURRENTSECTION#:Y]-([#CURRENTSECTION#:H]*#HoverScale#-[#CURRENTSECTION#:H])/2)][!SetOption #CURRENTSECTION# W ([#CURRENTSECTION#:W]*#HoverScale#)][!SetOption #CURRENTSECTION# H ([#CURRENTSECTION#:H]*#HoverScale#)][!UpdateMeter *][!Redraw]
MouseLeaveAction=[!SetOption #CURRENTSECTION# X ([#CURRENTSECTION#:X]+([#CURRENTSECTION#:W]-[#CURRENTSECTION#:W]/#HoverScale#)/2)][!SetOption #CURRENTSECTION# Y ([#CURRENTSECTION#:Y]+([#CURRENTSECTION#:H]-[#CURRENTSECTION#:H]/#HoverScale#)/2)][!SetOption #CURRENTSECTION# W ([#CURRENTSECTION#:W]/#HoverScale#)][!SetOption #CURRENTSECTION# H ([#CURRENTSECTION#:H]/#HoverScale#)][!UpdateMeter *][!Redraw]
LeftMouseDownAction=[!SetOption #CURRENTSECTION# X ([#CURRENTSECTION#:X]+([#CURRENTSECTION#:W]-[#CURRENTSECTION#:W]/#HoverScale#)/2)][!SetOption #CURRENTSECTION# Y ([#CURRENTSECTION#:Y]+([#CURRENTSECTION#:H]-[#CURRENTSECTION#:H]/#HoverScale#)/2)][!SetOption #CURRENTSECTION# W ([#CURRENTSECTION#:W]/#HoverScale#)][!SetOption #CURRENTSECTION# H ([#CURRENTSECTION#:H]/#HoverScale#)][!UpdateMeter *][!Redraw]
LeftMouseUpAction=[!SetOption #CURRENTSECTION# X ([#CURRENTSECTION#:X]-([#CURRENTSECTION#:W]*#HoverScale#-[#CURRENTSECTION#:W])/2)][!SetOption #CURRENTSECTION# Y ([#CURRENTSECTION#:Y]-([#CURRENTSECTION#:H]*#HoverScale#-[#CURRENTSECTION#:H])/2)][!SetOption #CURRENTSECTION# W ([#CURRENTSECTION#:W]*#HoverScale#)][!SetOption #CURRENTSECTION# H ([#CURRENTSECTION#:H]*#HoverScale#)][!UpdateMeter *][!Redraw]

[GlobalTruncHoverStyle]
MouseOverAction=[!SetOption #CURRENTSECTION# X (Trunc([#CURRENTSECTION#:X]-([#CURRENTSECTION#:W]*#HoverScale#-[#CURRENTSECTION#:W])/2))][!SetOption #CURRENTSECTION# Y (Trunc([#CURRENTSECTION#:Y]-([#CURRENTSECTION#:H]*#HoverScale#-[#CURRENTSECTION#:H])/2))][!SetOption #CURRENTSECTION# W (Trunc([#CURRENTSECTION#:W]*#HoverScale#))][!SetOption #CURRENTSECTION# H (Trunc([#CURRENTSECTION#:H]*#HoverScale#))][!UpdateMeter *][!Redraw]
MouseLeaveAction=[!SetOption #CURRENTSECTION# X (Trunc([#CURRENTSECTION#:X]+([#CURRENTSECTION#:W]-[#CURRENTSECTION#:W]/#HoverScale#)/2))][!SetOption #CURRENTSECTION# Y (Trunc([#CURRENTSECTION#:Y]+([#CURRENTSECTION#:H]-[#CURRENTSECTION#:H]/#HoverScale#)/2))][!SetOption #CURRENTSECTION# W (Trunc([#CURRENTSECTION#:W]/#HoverScale#))][!SetOption #CURRENTSECTION# H (Trunc([#CURRENTSECTION#:H]/#HoverScale#))][!UpdateMeter *][!Redraw]
LeftMouseDownAction=[!SetOption #CURRENTSECTION# X (Trunc([#CURRENTSECTION#:X]+([#CURRENTSECTION#:W]-[#CURRENTSECTION#:W]/#HoverScale#)/2))][!SetOption #CURRENTSECTION# Y (Trunc([#CURRENTSECTION#:Y]+([#CURRENTSECTION#:H]-[#CURRENTSECTION#:H]/#HoverScale#)/2))][!SetOption #CURRENTSECTION# W (Trunc([#CURRENTSECTION#:W]/#HoverScale#))][!SetOption #CURRENTSECTION# H (Trunc([#CURRENTSECTION#:H]/#HoverScale#))][!UpdateMeter *][!Redraw]
LeftMouseUpAction=[!SetOption #CURRENTSECTION# X (Trunc([#CURRENTSECTION#:X]-([#CURRENTSECTION#:W]*#HoverScale#-[#CURRENTSECTION#:W])/2))][!SetOption #CURRENTSECTION# Y (Trunc([#CURRENTSECTION#:Y]-([#CURRENTSECTION#:H]*#HoverScale#-[#CURRENTSECTION#:H])/2))][!SetOption #CURRENTSECTION# W (Trunc([#CURRENTSECTION#:W]*#HoverScale#))][!SetOption #CURRENTSECTION# H (Trunc([#CURRENTSECTION#:H]*#HoverScale#))][!UpdateMeter *][!Redraw]

[GlobalRoundHoverStyle]
MouseOverAction=[!SetOption #CURRENTSECTION# X (Round([#CURRENTSECTION#:X]-([#CURRENTSECTION#:W]*#HoverScale#-[#CURRENTSECTION#:W])/2))][!SetOption #CURRENTSECTION# Y (Round([#CURRENTSECTION#:Y]-([#CURRENTSECTION#:H]*#HoverScale#-[#CURRENTSECTION#:H])/2))][!SetOption #CURRENTSECTION# W (Round([#CURRENTSECTION#:W]*#HoverScale#))][!SetOption #CURRENTSECTION# H (Round([#CURRENTSECTION#:H]*#HoverScale#))][!UpdateMeter *][!Redraw]
MouseLeaveAction=[!SetOption #CURRENTSECTION# X (Round([#CURRENTSECTION#:X]+([#CURRENTSECTION#:W]-[#CURRENTSECTION#:W]/#HoverScale#)/2))][!SetOption #CURRENTSECTION# Y (Round([#CURRENTSECTION#:Y]+([#CURRENTSECTION#:H]-[#CURRENTSECTION#:H]/#HoverScale#)/2))][!SetOption #CURRENTSECTION# W (Round([#CURRENTSECTION#:W]/#HoverScale#))][!SetOption #CURRENTSECTION# H (Round([#CURRENTSECTION#:H]/#HoverScale#))][!UpdateMeter *][!Redraw]
LeftMouseDownAction=[!SetOption #CURRENTSECTION# X (Round([#CURRENTSECTION#:X]+([#CURRENTSECTION#:W]-[#CURRENTSECTION#:W]/#HoverScale#)/2))][!SetOption #CURRENTSECTION# Y (Round([#CURRENTSECTION#:Y]+([#CURRENTSECTION#:H]-[#CURRENTSECTION#:H]/#HoverScale#)/2))][!SetOption #CURRENTSECTION# W (Round([#CURRENTSECTION#:W]/#HoverScale#))][!SetOption #CURRENTSECTION# H (Round([#CURRENTSECTION#:H]/#HoverScale#))][!UpdateMeter *][!Redraw]
LeftMouseUpAction=[!SetOption #CURRENTSECTION# X (Round([#CURRENTSECTION#:X]-([#CURRENTSECTION#:W]*#HoverScale#-[#CURRENTSECTION#:W])/2))][!SetOption #CURRENTSECTION# Y (Round([#CURRENTSECTION#:Y]-([#CURRENTSECTION#:H]*#HoverScale#-[#CURRENTSECTION#:H])/2))][!SetOption #CURRENTSECTION# W (Round([#CURRENTSECTION#:W]*#HoverScale#))][!SetOption #CURRENTSECTION# H (Round([#CURRENTSECTION#:H]*#HoverScale#))][!UpdateMeter *][!Redraw]

[TruncHoverStyle]
MouseOverAction=[!SetOption #CURRENTSECTION# X ([#CURRENTSECTION#:X]-Trunc((Trunc([#CURRENTSECTION#:W]*#HoverScale#)-[#CURRENTSECTION#:W])/2))][!SetOption #CURRENTSECTION# Y ([#CURRENTSECTION#:Y]-Trunc((Trunc([#CURRENTSECTION#:H]*#HoverScale#)-[#CURRENTSECTION#:H])/2))][!SetOption #CURRENTSECTION# W (Trunc([#CURRENTSECTION#:W]*#HoverScale#))][!SetOption #CURRENTSECTION# H (Trunc([#CURRENTSECTION#:H]*#HoverScale#))][!UpdateMeter *][!Redraw]
MouseLeaveAction=[!SetOption #CURRENTSECTION# X ([#CURRENTSECTION#:X]+Trunc(([#CURRENTSECTION#:W]-Trunc([#CURRENTSECTION#:W]/#HoverScale#))/2))][!SetOption #CURRENTSECTION# Y ([#CURRENTSECTION#:Y]+Trunc(([#CURRENTSECTION#:H]-Trunc([#CURRENTSECTION#:H]/#HoverScale#))/2))][!SetOption #CURRENTSECTION# W (Trunc([#CURRENTSECTION#:W]/#HoverScale#))][!SetOption #CURRENTSECTION# H (Trunc([#CURRENTSECTION#:H]/#HoverScale#))][!UpdateMeter *][!Redraw]
LeftMouseDownAction=[!SetOption #CURRENTSECTION# X ([#CURRENTSECTION#:X]+Trunc(([#CURRENTSECTION#:W]-Trunc([#CURRENTSECTION#:W]/#HoverScale#))/2))][!SetOption #CURRENTSECTION# Y ([#CURRENTSECTION#:Y]+Trunc(([#CURRENTSECTION#:H]-Trunc([#CURRENTSECTION#:H]/#HoverScale#))/2))][!SetOption #CURRENTSECTION# W (Trunc([#CURRENTSECTION#:W]/#HoverScale#))][!SetOption #CURRENTSECTION# H (Trunc([#CURRENTSECTION#:H]/#HoverScale#))][!UpdateMeter *][!Redraw]
LeftMouseUpAction=[!SetOption #CURRENTSECTION# X ([#CURRENTSECTION#:X]-Trunc((Trunc([#CURRENTSECTION#:W]*#HoverScale#)-[#CURRENTSECTION#:W])/2))][!SetOption #CURRENTSECTION# Y ([#CURRENTSECTION#:Y]-Trunc((Trunc([#CURRENTSECTION#:H]*#HoverScale#)-[#CURRENTSECTION#:H])/2))][!SetOption #CURRENTSECTION# W (Trunc([#CURRENTSECTION#:W]*#HoverScale#))][!SetOption #CURRENTSECTION# H (Trunc([#CURRENTSECTION#:H]*#HoverScale#))][!UpdateMeter *][!Redraw]

[RoundHoverStyle]
MouseOverAction=[!SetOption #CURRENTSECTION# X ([#CURRENTSECTION#:X]-Round((Round([#CURRENTSECTION#:W]*#HoverScale#)-[#CURRENTSECTION#:W])/2))][!SetOption #CURRENTSECTION# Y ([#CURRENTSECTION#:Y]-Round((Round([#CURRENTSECTION#:H]*#HoverScale#)-[#CURRENTSECTION#:H])/2))][!SetOption #CURRENTSECTION# W (Round([#CURRENTSECTION#:W]*#HoverScale#))][!SetOption #CURRENTSECTION# H (Round([#CURRENTSECTION#:H]*#HoverScale#))][!UpdateMeter *][!Redraw]
MouseLeaveAction=[!SetOption #CURRENTSECTION# X ([#CURRENTSECTION#:X]+Round(([#CURRENTSECTION#:W]-Round([#CURRENTSECTION#:W]/#HoverScale#))/2))][!SetOption #CURRENTSECTION# Y ([#CURRENTSECTION#:Y]+Round(([#CURRENTSECTION#:H]-Round([#CURRENTSECTION#:H]/#HoverScale#))/2))][!SetOption #CURRENTSECTION# W (Round([#CURRENTSECTION#:W]/#HoverScale#))][!SetOption #CURRENTSECTION# H (Round([#CURRENTSECTION#:H]/#HoverScale#))][!UpdateMeter *][!Redraw]
LeftMouseDownAction=[!SetOption #CURRENTSECTION# X ([#CURRENTSECTION#:X]+Round(([#CURRENTSECTION#:W]-Round([#CURRENTSECTION#:W]/#HoverScale#))/2))][!SetOption #CURRENTSECTION# Y ([#CURRENTSECTION#:Y]+Round(([#CURRENTSECTION#:H]-Round([#CURRENTSECTION#:H]/#HoverScale#))/2))][!SetOption #CURRENTSECTION# W (Round([#CURRENTSECTION#:W]/#HoverScale#))][!SetOption #CURRENTSECTION# H (Round([#CURRENTSECTION#:H]/#HoverScale#))][!UpdateMeter *][!Redraw]
LeftMouseUpAction=[!SetOption #CURRENTSECTION# X ([#CURRENTSECTION#:X]-Round((Round([#CURRENTSECTION#:W]*#HoverScale#)-[#CURRENTSECTION#:W])/2))][!SetOption #CURRENTSECTION# Y ([#CURRENTSECTION#:Y]-Round((Round([#CURRENTSECTION#:H]*#HoverScale#)-[#CURRENTSECTION#:H])/2))][!SetOption #CURRENTSECTION# W (Round([#CURRENTSECTION#:W]*#HoverScale#))][!SetOption #CURRENTSECTION# H (Round([#CURRENTSECTION#:H]*#HoverScale#))][!UpdateMeter *][!Redraw]

---Meters---

[Image]
Meter=Image
MeterStyle=PlainHoverStyle
X=99.99
Y=99.99
W=99.99
H=99.99
SolidColor=247,47,47,255
DynamicVariables=1

[Text]
Meter=String
X=150
Y=150
SolidColor=0,0,0,0
FontFace=Consolas
FontColor=255,255,255,255
FontSize=16
StringAlign=CenterCenter
AntiAlias=1
Text="X = [Image:X]#CRLF#Y = [Image:Y]#CRLF#W = [Image:W]#CRLF#H = [Image:H]"
DynamicVariables=1
Question: Is this normal? If it isn't, what can be done about it, to preferably keep some consistency between numerical transformations needed for positional handling? If it's normal, care to explain why the above behavior and if there's an "easy" solution available as a workaround, without always beeing careful to pick the right transformation when working with meter coordinates?

Bonus question: why the GlobalRound hover style above worked in the first place? If rounding is the way to go with this, shouldn't EVERY part of a formula that gets translated into an (integer) coordinate be rounded first? In other words, shouldn't the Round hover style work and GlobalRound fail?
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
jsmorley
Developer
Posts: 22629
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Rounding or ... Trunc-ing error :)

Post by jsmorley »

Pixel-based skin measurements like W and H and such are always integers, and as far as I know, they are truncated everywhere in Rainmeter. If you have a formula-based value for those, you will need to Round() them yourself in the formula.
User avatar
Yincognito
Rainmeter Sage
Posts: 7149
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Rounding or ... Trunc-ing error :)

Post by Yincognito »

jsmorley wrote: April 14th, 2021, 3:40 pm Pixel-based skin measurements like W and H and such are always integers, and as far as I know, they are truncated everywhere in Rainmeter.
Yeah, no problem with that. My question was why I need to round them instead of truncating them in a formula...
It's like saying that I need milk and asking you for coffee, if you understand what I'm saying. :confused:

EDIT: Hmm...I think I understand. I need to round them in a formula so that when Rainmeter truncates the result afterwards, no pixels are lost. I guess it's all clear now, thanks. :thumbup:
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
jsmorley
Developer
Posts: 22629
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Rounding or ... Trunc-ing error :)

Post by jsmorley »

Both Round() and Trunc() work as expected for me...

Code: Select all

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1

[Variables]

[MeterOne]
Meter=String
X=(Trunc(2.9))
FontSize=11
FontWeight=400
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
AntiAlias=1
Text=[MeterOne:X]
DynamicVariables=1

[MeterTwo]
Meter=String
X=(Round(2.9))
Y=2R
FontSize=11
FontWeight=400
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
AntiAlias=1
Text=[MeterTWo:X]
DynamicVariables=1

1.png

If you just use X=2.9, that will be truncated to 2.
You do not have the required permissions to view the files attached to this post.
User avatar
Yincognito
Rainmeter Sage
Posts: 7149
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Rounding or ... Trunc-ing error :)

Post by Yincognito »

jsmorley wrote: April 14th, 2021, 3:54 pmBoth Round() and Trunc() work as expected for me...
Yes, they do. I was simply under the impression that given the final truncated result when it comes to positioning, I needed to Trunc() the formula itself, but failed to realize that Round() simply protects the fractional part from being lost when Rainmeter automatically truncates the result in the X, Y, W and H options. E.g. I do (1.44 * 2) = 2.88; if I truncate the formula myself using Trunc(), Rainmeter would place the meter at 2, and that 0.88 part (which visually would amount to almost a whole pixel) would be lost; if I Round() the formula though, I would get 3, and the "incomplete" (but still almost a whole) pixel "survives".
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth