Here we have rotated the string "Hello World" -45 degrees: The Angle option is pretty simple in principle. You simply add the option to the String meter, defining the number (negative or positive) of radians you want to rotate the string by. It is simpler to understand if you think about this in degrees instead of radians, with the original horizontal orientation being 0 degrees. Then just use the Rad(degrees) mathematical function to convert the degrees to radians for the meter.
Angle=(Rad(-45))
The text will be rotated the defined number of radians inside the meter, using the X and Y of the meter (the top-left corner in the case of the default StringAlign=Left) as the anchor point of the rotation.
However, there are some very important rules to understand in order to successfully use the Angle option.
What we will do is lay out these rules, and demonstrate how you can work within them to get the results you want.
First, let me acknowledge right up front that the Angle option is just poorly designed in Rainmeter. Mostly this is due to the fact that the rotation does not change the resulting size of the meter, (like ImageRotate can...) and this makes it a tad horrible to use. Issues with backwards compatibility make that difficult to fix, and eventually there may have to be something like a brand new MeterRotate option for this kind of thing that works on any meter type. (more like a really simple TransformationMatrix) In the meantime however, it does work and can be used to create some nice string effects.
Rule One : The String meter is not rotated. The text inside is the meter is.
It is important to understand this as the first and primary thing. When you create a String meter, the meter that is created is a rectangle. It has a horizontal orientation, and will be sized either automatically to fit the string using the defined font, or manually by setting W and H on the meter.
Code: Select all
[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1
[MeterHoriz]
Meter=String
X=0
Y=0
FontSize=30
FontColor=47,47,47,255
SolidColor=150,150,150,255
AntiAlias=1
Text=Hello World
Rule Two : The size and orientation of the meter is not changed by the Angle option.
Again, it is important to remember the the "text" is rotated inside the "meter". The meter itself is not rotated, its size is not changed, and in every sense, the meter itself has no idea that any angle was even applied.
Rule Three : The rotation of the text inside the meter will almost certainly make it so the text no longer fits inside the meter.
To demonstrate, let's just add a second meter at the same spot, with the same text as our first one. Then we will rotate it -45 degrees:
Code: Select all
[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1
[MeterHoriz]
Meter=String
X=0
Y=0
FontSize=30
FontColor=47,47,47,255
SolidColor=150,150,150,255
AntiAlias=1
Text=Hello World
[MeterAngle]
Meter=String
X=0
Y=0
FontSize=30
FontColor=255,255,255,255
AntiAlias=1
Angle=(Rad(-45))
Text=Hello World
Rule Four : The size of the actual skin will also not change to reflect the new angle of the text.
Remember that the size of the String meter is never changed by the Angle option. That means the size of the skin, which is automatically defined by the overall size and position of all meters in the skin, is also not changed. Unless the String meter is part of a larger skin that has a background or other meters that cause the overall size of the skin to be large enough, our rotated text is almost certain to not only "rotate out" of the meter, (which is sorta OK, the text will still be drawn outside the meter as long as it is still inside the skin) but actually "rotate out" of the entire skin and be truncated. (which is really not OK) That should be clear from our image above.
DynamicWindowSize in the [Rainmeter] section is no help with this. Remember, nothing has changed "size" when we use the Angle option on a String meter.
Rule Five : The X and Y of the String meter play a role in making the skin fit the rotated text.
What this means is that while creating a background meter so that our skin is big enough to hold the rotated text is the right thing to do, it should be remembered that you may also need to "move" the String meter so when it is rotated it is entirely contained by the background meter. The changes you need to make to X and Y will vary wildly, depending on the angle of rotation, and whether it is positive (swinging down around the anchor) or negative (swinging up around the anchor).
Let me demonstrate:
Code: Select all
[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1
[MeterBack]
Meter=Image
W=172
H=187
SolidColor=47,47,47,255
[MeterHoriz]
Meter=String
X=0
Y=0
FontSize=30
FontColor=47,47,47,255
SolidColor=150,150,150,255
AntiAlias=1
Text=Hello World
[MeterAngle]
Meter=String
X=0
Y=0
FontSize=30
FontColor=255,255,255,255
AntiAlias=1
Angle=(Rad(-45))
Text=Hello World
What we need to do is use X and Y to "move" the String meter to a position where, when the text is rotated, it is entirely contained by the background meter.
Code: Select all
[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1
[MeterBack]
Meter=Image
W=172
H=187
SolidColor=47,47,47,255
[MeterHoriz]
Meter=String
X=0
Y=141
FontSize=30
FontColor=47,47,47,255
SolidColor=150,150,150,255
AntiAlias=1
Text=Hello World
[MeterAngle]
Meter=String
X=0
Y=141
FontSize=30
FontColor=255,255,255,255
AntiAlias=1
Angle=(Rad(-45))
Text=Hello World
Rule Six : The anchor / center of rotation is based on the "font", not the "string".
By that I mean that most fonts have some "slack space" around the actual character glyphs in the font file. When the string is rotated, that slack space is rotated with it. This will be much more pronounced if you don't set AccurateText=1 in the [Rainmeter] section of the skin, but even if you do it will play a small role in the final effect.
So to have my rotated string properly rotate exactly around the top left corner of the "visible text", to match with the first non-rotated String meter, I would make a couple of tweaks to the X and Y of the rotated meter.
Code: Select all
[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1
[MeterBack]
Meter=Image
W=172
H=187
SolidColor=47,47,47,255
[MeterHoriz]
Meter=String
X=0
Y=141
FontSize=30
FontColor=47,47,47,255
SolidColor=150,150,150,255
AntiAlias=1
Text=Hello World
[MeterAngle]
Meter=String
X=-4
Y=144
FontSize=30
FontColor=255,255,255,255
AntiAlias=1
Angle=(Rad(-45))
Text=Hello World
Rule Seven : Most of this sizing and positioning is going to be trial-and-error. Sorry...
There really is just no way that you are going to be able to automate or even calculate what the size of any background meter, and the X and Y of the String meter will need to be to make this work right for you.
Mostly this is due to the fact that in spite of whatever clever formulas you might come up with, the variable width of characters in most fonts, the varying metrics of different fonts, and the fact that there is no reliable formula for "number of characters X point size = number of pixels" is just going to make it something you have to tweak.
What I recommend is that you create your meter non-rotated first, get a sense of how big it is, and then create a visible background Image meter that will be more than large enough to hold it when rotated. Change the X and Y To move the meter where it will fit best in the background meter, and then rotate it with the Angle option. Then you can play with the W and H of the background Image meter, and the X and Y of the String meter, until you get things positioned correctly, with the "text" fitting as efficiently as possible in the background.
Hint: You can find the size of a meter by simply adding something like:
MouseOverAction=[!Log "#CURRENTSECTION# is [#CURRENTSECTION#:W] X [#CURRENTSECTION#:H]"]
to the meter. Then just mouse over it to see the size in the About / Log dialog. Remove this when you are done testing.
Then you can simply set the background image meter to SolidColor=0,0,0,0 (invisible), and you should end up with just your rotated string working perfectly. Do not remove the background meter in my example. It isn't there just to help you position things, but will be required to ensure the overall skin is big enough, even if it is "invisible".
Code: Select all
[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1
[MeterBack]
Meter=Image
W=172
H=187
SolidColor=0,0,0,0
[MeterAngle]
Meter=String
X=-4
Y=144
FontSize=30
FontColor=255,255,255,255
AntiAlias=1
Angle=(Rad(-45))
Text=Hello World
Remember, our actual String meter has not changed size or shape.
Any mouse actions you put on that string meter will react, and only react, to the rectangle defined by the original, non-rotated meter. In our example above, a LeftMouseUpAction on the String meter will be completely ignored by about 90% of the "visible" string. There is no perfect solution, but one thing you can do is to put any mouse actions on that background Image meter instead, and set SolidColor=0,0,0,1. At least then the full "visible" string reacts to the mouse. That is one reason why it is worth the effort to make the "text" fit the "background" as exactly as possible. The background image will still be a rectangle, so you may have a lot of empty space that reacts to the mouse, but that is probably better in the long haul than having most of the text not react.
You can improve on this situation quite a bit by creating really any image in PhotoShop or Gimp the same size as the original String meter. (205 X 44 in our example). Then you can use ImageAlpha=1 and ImageRotate=-45 on an Image meter using that image, to have it match the rotation of the string. Putting the mouse actions on this Image meter will help, since the mouse will ignore any "completely invisible" portions of the meter, and you will get a result that is a lot more satisfying.
Relative positioning with "r" and "R" is just not going to work right. The relative position of the next meter you define with X=5R or any other relative position option is going to be based on the size and shape of the original non-rotated previous meter, and you are just not going to get any useful behavior.
The StringAlign option can certainly be used, but it should be remembered that StringAlign is also based on the X and Y and W and H of the meter. Since StringAlign=Center means that the string will be centered on X and then equally divided to the left and right of X, this can cause its own issues with the size of the meter and / or the size of the skin. Adding an Angle to the mix can be managed, but with a center of rotation that isn't top left anymore, it might take some additional tweaking of the W/H/X/Y values to get things right.