It is currently April 27th, 2024, 10:31 am

Creating Scalable Skins

Tips and Tricks from the Rainmeter Community
User avatar
eclectic-tech
Rainmeter Sage
Posts: 5407
Joined: April 12th, 2012, 9:40 pm
Location: Cedar Point, Ohio, USA

Creating Scalable Skins

Post by eclectic-tech »

CREATE OR MODIFY SKINS TO SCALE FOR HIGH RESOLUTION SCREENS
Most older skins and many new skins were designed with hard-coded size variable and worked well with the available resolution displays back then. However, most modern displays use resolutions that make older skins appear tiny at the default 100% DPI or they become distorted if DPI scaling above 100%.
See more information on Rainmeter and DPI here: https://forum.rainmeter.net/viewtopic.php?t=22272#p118040.
Adding pixel scaling to these skins will keep them useful on today's high-resolution screens.
Pixel scaling is possible in 3 steps:
1.) adding a SCALE=1 variable to the [Variables] section of the skin
2.) adding formulas to meters dimensions
3.) adding a points-to-pixels adjustment to scale fonts properly.

STEPS TO ADD SCALING TO OLDER SKINS

Adding Formulas (Step 2)
I would recommend starting in the [Rainmeter] section and add a pixel scaling multiplication formula to any hard-coded pixel values.
Examples:
SkinHeight=200 changes to SkinHeight=(200*#Scale#)
BackgroundMargins=5,5,5,5 changes to BackgroundMargins=(5 * #Scale#),(5 * #Scale#),(5 * #Scale#),(5 * #Scale#)

Next look at the [Variables] section and add pixel scaling formulas to all pixel values of defined variables.
Example:
ClocWidth=100 changes to ClockWidth=(100*#Scale#)

Then look at ALL meters in the skin and modifying any hard-coded pixel values of ALL X, Y, W, and H with a pixel scaling formula to multiply the original value. Disregard any #variablenames# since they were already scaled in the [Variables] section.
Examples:
X=6 is changed to X=(6 * #Scale#)
ScaleMargins=5,5,5,5 changes to ScaleMargins=(5 * #Scale#),(5 * #Scale#),(5 * #Scale#),(5 * #Scale#)
X=(6 + #ClockWidth#) is changed to X=((6 * #Scale#) + #ClockWidth#)
X=#ClockWidth# is NOT changed; variables were already scaled in the [Variables] section.
X=(#ClockWidth# * 2) is changed to X=(#ClockWidth# * (2 * #Scale#))

* Shape Meter Option *
Shape meter X, Y, W, and H parameter values can be modified by #Scale# multiplication, or you can add | Scale #Scale#,#Scale# to the shape parameters.


Font Points Relative to Pixels Scaling (Step 3)
Rainmeter fonts are based on points (not pixels) so the font size needs to be adjusted before pixel scaling can be used in order to keep the point size relative to the pixel scale used.
Note: FontSize originally had to be integers but now Rainmeter can accept fractional values as font sizes.

One way is to reduced the original hard-coded point size by ~25% (0.75) so 12 becomes 9. The pixel scale multiplier is multiplied by a points-to-pixel relational value of 1.33 and that result is used to scale the font.
Example:
A hard-coded FontSize=12 should be changed to FontSize=(ceil(9*(#Scale#*1.33))) ... 9 x 1.33 = 11.97 and the ceil() function result is 12, which match the original FontSize value.
The 'ceil()' function is optional since Rainmeter can use fractional font sizes: FontSize=(9*(#Scale#*1.33)) and will be just as accurate.


Manual or User-Friendly Scale Adjusting
You can have the end user manually modify Scale=1 in the [Variables] section of the code or add mouse actions to simplify scaling.

I usually use mouse scroll actions to let the end user easily change the scale.

Note: If the action bangs are added to the [Rainmeter] section, because it is NOT dynamic, a [!Refresh] bang is required.
But, if you have a background meter in the skin, you can add those action bangs to that meter.
You will need to also add DynamicVariables=1 and [!UpdateMeter *][!Redraw].
This avoids having to [!Refresh] the entire skin.

Mouse scroll scaling added to [Rainmeter] section code (Scales: 1x ~ 3x):

Code: Select all

MouseScrollUpAction=[!WriteKeyValue Variables Scale (Clamp(#Scale#+0.01,1,3))][!Refresh]

MouseScrollDownAction=[!WriteKeyValue Variables Scale (Clamp(#Scale#-0.01,1,3))][!Refresh]

MiddleMouseUpAction=[!WriteKeyValue Variables Scale 1][!Refresh]
Mouse scroll scaling added to a [Background] meter section code (Scale: 1x ~ 3x):

Code: Select all

MouseScrollUpAction=[!WriteKeyValue Variables Scale (Clamp(#Scale#+0.01,1,3))][!SetVariable Scale (Clamp(#Scale#+0.01,1,3))][!UpdateMeter *][!Redraw]

MouseScrollDownAction=[!WriteKeyValue Variables Scale (Clamp(#Scale#-0.01,1,3))][!SetVariable Scale (Clamp(#Scale#+0.01,1,3))][!UpdateMeter *][!Redraw]

MiddleMouseUpAction=[!WriteKeyValue Variables Scale 1][!SetVariable Scale 1][!UpdateMeter *][!Redraw]

DynamicVariables=1

SUMMARY
Be sure to look for any @include= files that may contain hard-coded pixel or FontSize values that need to be modified.

Generally, this should give you the ability to adjust the scale of the modified skin to match almost any screen resolution.

Hopefully this information can be useful in adding scaling to older skin or in your new skin creations and keep them useable well into the future. :D

Keep coding! :rosegift:
buckb
Posts: 65
Joined: February 12th, 2018, 12:47 am

Re: Creating Scalable Skins

Post by buckb »

Helpful guide, eclectic-tech. Thanks for posting.

This knucklehead could have used it about a week ago! ;-)
User avatar
Yincognito
Rainmeter Sage
Posts: 7175
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Creating Scalable Skins

Post by Yincognito »

Even though the [Rainmeter] section is not dynamic, one might workaround some cases by using the nested syntax either here (questionable), or in sections related to it (like [Variables] or other meters being updated). Just saying.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
eclectic-tech
Rainmeter Sage
Posts: 5407
Joined: April 12th, 2012, 9:40 pm
Location: Cedar Point, Ohio, USA

Re: Creating Scalable Skins

Post by eclectic-tech »

buckb wrote: Helpful guide, eclectic-tech. Thanks for posting.

This knucklehead could have used it about a week ago! ;-)
Thanks!| ;-)
Yincognito wrote: January 12th, 2024, 11:53 am Even though the [Rainmeter] section is not dynamic, one might workaround some cases by using the nested syntax either here (questionable), or in sections related to it (like [Variables] or other meters being updated). Just saying.
@Yincognito ... Agreed, this is intended to give authors a starting point for scaling. There are other methods that could be useful and should be explored. Everyone has ways of coding they feel comfortable using, so I leave it up to the individual to experiment.
User avatar
Yincognito
Rainmeter Sage
Posts: 7175
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Creating Scalable Skins

Post by Yincognito »

eclectic-tech wrote: January 12th, 2024, 1:56 pm@Yincognito ... Agreed, this is intended to give authors a starting point for scaling. There are other methods that could be useful and should be explored. Everyone has ways of coding they feel comfortable using, so I leave it up to the individual to experiment.
Sure thing! :thumbup:
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth