It is currently September 8th, 2024, 4:41 am

Unexpected behavior with on-demand SetAnchor right vs left align switching. Any workarounds?

Get help with creating, editing & fixing problems with skins
Crest
Posts: 148
Joined: August 16th, 2013, 12:47 pm

Unexpected behavior with on-demand SetAnchor right vs left align switching. Any workarounds?

Post by Crest »

Have needed to dynamically switch the anchor position of a skin I'm in the process of making, via the `!SetAnchor` bang, and have noticed more apparently that changing the anchor alignment from the default left edge to the right edge (`R`) this way physically moves the skin by 100% of its width.

This is unexpected behavior for two reasons:
  • It doesn't behave this way when a skin has the Position>From Right option changed via the context menu settings for the skin (that is, the physical position of the skin doesn't move when toggled). Also, not sure if it's a bug, or I'm misunderstanding whether the two things are equivalent, but using `!SetAnchor` with a right (`R`) align value doesn't auto mark that context menu setting (it's independent of whatever state set by bangs).
  • In all image editors I've used, along with in CSS, setting a different alignment anchor/transform origin point doesn't move the original element but only adjusts where an element is scaled from. I'm not familiar with any different point of reference that behaves like Rainmeter's way of handling the switching on anchor via bangs.
GIF demo (click for animation):
Demo.gif
Test case INI:

Code: Select all

[Variables]

[Rainmeter]
Update=1000
DynamicWindowSize=1

[String]
Meter=String
W=300
H=300
FontFace=Segoe UI
FontSize=11
FontColor=255,255,255,255
Text=SetAnchor test
SolidColor=0,0,0,255
AntiAlias=1
ClipString=1
DynamicVariables=1

[Click]
Meter=Shape
X=([String:XW]-[Click:W])
Y=0
Shape=Rectangle 0,0,40,40,0 | Fill Color 0,200,0 | StrokeWidth 0
LeftMouseUpAction=[!SetAnchor "0R" "0"]
RightMouseUpAction=[!SetAnchor "0" "0"]
DynamicVariables=1
This has implications for the purposes of say, being able to resize the skin from either edge outward from the opposite edge the mouse is dragging (such resizing can work but since the entire skin position moves first---sometimes offscreen if the anchor changes while at an edge of the screen---it's hardly an expected or pleasant experience when someone has already positioned a skin where they like).

Have tried various workarounds including adding `!Move`/`!SetWindowPosition` bangs but this has unexpected behavior when used with inline formulas and `#CURRENTCONFIGX#`, so haven't found something that can work around this dynamically and wondering what may be possible that I've missed.

The only thing that "worked" in my tests was using `!SetWindowPosition` with a static (fixed) coordinate value that for a right-aligned anchor is offset the same width as the full skin more than the left-aligned static coordinate value (eg: one being `1300` and the other `1000` respectively, assuming a 300px width skin). This obviously isn't suitable for arbitrary skin positions and dynamic skin widths but shows the principle in theory would work if one could get something like `#CURRENTCONFIGX#` working with it properly.
You do not have the required permissions to view the files attached to this post.
Last edited by Crest on July 3rd, 2024, 11:59 am, edited 1 time in total.
User avatar
Yincognito
Rainmeter Sage
Posts: 8030
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Unexpected behavior with on-demand SetAnchor right vs left align switching. Any workarounds?

Post by Yincognito »

Crest wrote: July 3rd, 2024, 8:07 amThis is unexpected behavior
This actually is the expected behavior, since when doing [!SetAnchor "0R" "0"] you're telling the skin to set the anchor at the 0 horizontal position ... but based on the top left corner of the skin - hence the skin movement, given that then the skin will be drawn to the right of your current left side of the skin. What you want is [!SetAnchor "#CURRENTCONFIGWIDTH#R" "0"], which will anchor the skin at its right edge horizontally. The context menu and other tools probably already do that, which is why they work as you expect.

That being said, yeah, the context menu bullets don't reflect the new setting in this regard, not sure if it's a bug or an intentional omission given the supposedly "temporary" / "manual" nature of the change. On the other hand, the context menu bullets are the most precise ones when it comes to a skin's loaded state, even ahead of the Manage Rainmeter window (for example, you can have a loaded skin being incorrectly shown as unloaded in Manage Rainmeter, but correctly shown as loaded in the context menu bullets ... and at the same time!).
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
ikarus1969
Posts: 588
Joined: February 28th, 2011, 3:20 pm
Location: Vienna, Austria

Re: Unexpected behavior with on-demand SetAnchor right vs left align switching. Any workarounds?

Post by ikarus1969 »

Yincognito wrote: July 3rd, 2024, 8:42 am This actually is the expected behavior, since when doing [!SetAnchor "0R" "0"] you're telling the skin to set the anchor at the 0 horizontal position ... but based on the top left corner of the skin - hence the skin movement, given that then the skin will be drawn to the right of your current left side of the skin. What you want is [!SetAnchor "#CURRENTCONFIGWIDTH#R" "0"], which will anchor the skin at its right edge horizontally. The context menu and other tools probably already do that, which is why they work as you expect.
I think with [!SetAnchor "0R" "0"] you are telling rainmeter to draw the skin, starting at the WindowX and WindowY (given in the Rainmeter.ini for that skin) and from right to left (and top-down because of "0"), taking the width of the skin (300 in that case).
So: based on the top right corner.

[!SetAnchor "0" "0"] switches back: starting at the same WindowX and WindowY, but now drawing from left to right

The skin itself does not move - WindowX and WindowY remain the same; but the direction of drawing changes.
Crest
Posts: 148
Joined: August 16th, 2013, 12:47 pm

Re: Unexpected behavior with on-demand SetAnchor right vs left align switching. Any workarounds?

Post by Crest »

Yincognito wrote: July 3rd, 2024, 8:42 am This actually is the expected behavior, since when doing [!SetAnchor "0R" "0"] you're telling the skin to set the anchor at the 0 horizontal position ... but based on the top left corner of the skin - hence the skin movement, given that then the skin will be drawn to the right of your current left side of the skin. What you want is [!SetAnchor "#CURRENTCONFIGWIDTH#R" "0"], which will anchor the skin at its right edge horizontally. The context menu and other tools probably already do that, which is why they work as you expect.
Appreciate the clarification. One issue remaining is that changing the anchor (either to left or right) isn't always in sync with the latest skin position after the skin has been resized, variously jerking to random offsets when triggered, even with using the suggested variable for the anchor coordinate.

Any thoughts on what is causing this discrepancy?

GIF:
Demo-2.gif
Updated test case (here using mouse wheel for resizing for simplicity):

Code: Select all

[Variables]
U=[!UpdateMeter *][!Redraw]

[Rainmeter]
Update=1000
DynamicWindowSize=1

[String]
Meter=String
W=300
H=300
FontFace=Segoe UI
FontSize=11
FontColor=255,255,255,255
Text=SetAnchor test
SolidColor=0,0,0,255
AntiAlias=1
ClipString=1
MouseScrollUpAction=[!SetOption "String" "W" "([String:W] + 20)"]#U#
MouseScrollDownAction=[!SetOption "String" "W" "([String:W] - 20)"]#U#
DynamicVariables=1

[Click]
Meter=Shape
X=([String:XW]-[Click:W])
Y=0
Shape=Rectangle 0,0,40,40,0 | Fill Color 0,200,0 | StrokeWidth 0
LeftMouseUpAction=[!SetAnchor "#CURRENTCONFIGWIDTH#R" "0"]
RightMouseUpAction=[!SetAnchor "0" "0"]
DynamicVariables=1
You do not have the required permissions to view the files attached to this post.
Crest
Posts: 148
Joined: August 16th, 2013, 12:47 pm

Re: Unexpected behavior with on-demand SetAnchor right vs left align switching. Any workarounds?

Post by Crest »

I think I understand what is probably occurring in the post above. The variable coordinate obviously converts it to static value for the purpose of storing in Rainmeter.ini, so the right-aligned anchor becomes a fixed 'width' from that point onward until the button is clicked again.

However, in testing updating the anchor coordinate on resize it has the effect of resizing oddly, like it's being resized from the center presumably due to some timing conflicts or something.

My assumption going into this thread originally was `0R` would draw the skin outward '0 pixels from the right edge' (given a prior thread about this and my general experience up until testing switching the anchor point on the fly) but since Yingcognito's answer it seems the skin is re-drawn initially from a coordinate based on the left edge (hence why the skin appears to move if left at `0R`). Which means this static coordinate would require being updated in Rainmeter.ini so long as a right-aligned coordinate is used and resizing has occurred, when wanting to maintain seamless anchor switching.

Hmm. Still requires some thought as to how to update without the odd resizing side-effect.
User avatar
Yincognito
Rainmeter Sage
Posts: 8030
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Unexpected behavior with on-demand SetAnchor right vs left align switching. Any workarounds?

Post by Yincognito »

ikarus1969 wrote: July 3rd, 2024, 9:04 am I think with [!SetAnchor "0R" "0"] you are telling rainmeter to draw the skin, starting at the WindowX and WindowY (given in the Rainmeter.ini for that skin) and from right to left (and top-down because of "0"), taking the width of the skin (300 in that case).
So: based on the top right corner.

[!SetAnchor "0" "0"] switches back: starting at the same WindowX and WindowY, but now drawing from left to right

The skin itself does not move - WindowX and WindowY remain the same; but the direction of drawing changes.
Absolutely. :thumbup:
When I mentioned "moving", I referred more to the visual effect for the user - should have been clearer on that in my post indeed. ;-)
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
ikarus1969
Posts: 588
Joined: February 28th, 2011, 3:20 pm
Location: Vienna, Austria

Re: Unexpected behavior with on-demand SetAnchor right vs left align switching. Any workarounds?

Post by ikarus1969 »

I always think it that way:
  1. the skin is positioned to WindowX, WindowY coordinates (they are screen related)
  2. the skin is moved so, that the anchor-point (skin/config related) is on that WindowX, WindowY-point
So let's say the skins WindowX and WindowY position is 100, 150 and the skins width is 50 and the skins height is 80

Code: Select all

If AnchorX is set to  0   and AnchorY to  0 : the skin is drawn from 100, 150
If AnchorX is set to 10   and AnchorY to 10 : the skin is drawn from  90, 140
If AnchorX is set to 10R  and AnchorY to 30 : the skin is drawn from  60, 120
If AnchorX is set to 10%  and AnchorY to  0 : the skin is drawn from  95, 150 (10% of 50 = 5; 100 - 5 = 95)
If AnchorX is set to 10%R and AnchorY to 20%: the skin is drawn from  55, 134 (X: 10% of 50 = 5, 100 - (50 - 5) = 55, Y:20% of 80 = 16; 150 - 16 = 134)
negative values for AnchorX/AnchorY will be set to 0 before used.
User avatar
Yincognito
Rainmeter Sage
Posts: 8030
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Unexpected behavior with on-demand SetAnchor right vs left align switching. Any workarounds?

Post by Yincognito »

Crest wrote: July 3rd, 2024, 9:10 amAny thoughts on what is causing this discrepancy?
Yes, see the 1st ikarus1969 reply. I'll give an example, and you can test it yourself by having both C:\Users\[User]\AppData\Roaming\Rainmeter\Rainmeter.ini (positioned at your skin's section for conveniency) and your skin's .ini opened in Notepad++, because Notepad++ has a nice feature that will alert you when a viewed file has changed and ask you if you want to update the tab to display its changes.

Let's say that your skin has WindowX=H and WindowY=V in Rainmeter.ini (H=561 and V=356 for me, but it doesn't matter):
- right click to set the anchor at "0" "0" and see the changes in Rainmeter.ini (if any)
- scroll down 3 notches to narrow the skin horizontally by 60px from the right side, you'll have no change in Rainmeter.ini
- left click to set AnchorX at 240R and check
- scroll down another 3 nothes to horizontally narrow the skin again by 60px, but this time from its left side (notice how WindowX and WindowY stayed the same!)
- right click again to set the anchor at "0" "0": skin will jump to the left due to narrowing it from the left side in the previous step (WindowX and WindowY are still H and V!)

So basically, you have to take into account that when doing the scrolling. I didn't use !SetAnchor much myself so there surely are solutions for the approach, I usually go with !SetWindowPosition, and, in this case, setting the WindowX accordingly from the right too (I left the previous approach commented out for comparison purposes) would do:

Code: Select all

;LeftMouseUpAction=[!SetAnchor "#CURRENTCONFIGWIDTH#R" "0"]
LeftMouseUpAction=[!SetWindowPosition "(#SCREENAREAX#+#SCREENAREAWIDTH#-#CURRENTCONFIGX#)R" "(#CURRENTCONFIGY#)" "(#CURRENTCONFIGWIDTH#)R" "0"]
;RightMouseUpAction=[!SetAnchor "0" "0"]
RightMouseUpAction=[!SetWindowPosition "(#CURRENTCONFIGX#)" "(#CURRENTCONFIGY#)" "0" "0"]
Now, performing the above steps should produce the result you wanted. ;-)
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
Crest
Posts: 148
Joined: August 16th, 2013, 12:47 pm

Re: Unexpected behavior with on-demand SetAnchor right vs left align switching. Any workarounds?

Post by Crest »

Crest wrote: July 3rd, 2024, 9:46 amHowever, in testing updating the anchor coordinate on resize it has the effect of resizing oddly, like it's being resized from the center presumably due to some timing conflicts or something.

...

Hmm. Still requires some thought as to how to update without the odd resizing side-effect.
For the curious found this can be solved by keeping in sync the full `!SetWindowPosition` at each resize change, with the WindowX and WindowY set as `#CURRENTCONFIGX#` and `#CURRENTCONFIGY#`, respectively (since apparently the WindowX/Y actually does need to be moved simultaneously to behave as desired). Note: for the test case skin this would require some additional changes but for my actual skin purposes it works well.
User avatar
Yincognito
Rainmeter Sage
Posts: 8030
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Unexpected behavior with on-demand SetAnchor right vs left align switching. Any workarounds?

Post by Yincognito »

Crest wrote: July 3rd, 2024, 11:30 am Heh, same minute posts :p
Yeah, well, mine was longer, explanations, tests, and all that, lol. Took a while to write properly, with care at every detail. :D
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth