2 Attachment(s)
DPI and icon sizes in sets
Hi DAW
I have been looking into icon sizes and DPI and have found the following I need help understanding.
The following 2 screen shots show a toolbar icon showing it's size, a view showing images on buttons and a view showing images on tab buttons. The first image is 100% DPI and the second is 125% with no code changes.
The icon I'm using is the DAW test icon - all.ico
100%
[ATTACH=CONFIG]10906[/ATTACH]
125%
[ATTACH=CONFIG]10907[/ATTACH]
Note the toolbar icon in 100% uses the 16x16 size and in 125% it uses the 24x24 size, which is expected.
Questions:
1, the tab button icons just seem to be sized 16x16 but uses 32 (100%) and 48 (125%) - why does the image change? and why doesn't it use 16? The tab dialog image list image height and width is 16.
2, same with the button why does the image change from 32 to 48, and how does it choose those images? Also the piImageSize seems to have no baring either, on selecting a size within the icon set.
Re: DPI and icon sizes in sets
I tried a similar test in 19.0, I'm guessing what you are seeing might have something to do with the LOGPIXELSY value obtained via GetDeviceCaps.
While running at 150% on my 4K display:
If I uncheck "Add 'DPI Aware' to Manifest" in Project Properties, Windows reports 96 to the application for LOGPIXELSY. The 16/32 icons are used per your first example.
If I check the "Add 'DPI Aware' to Manifest" in Project Properties, Windows reports 144 to the application for LOGPIXELSY. The 24/48 icons are used per your second example.
Setting piImageSize in a button only seems to affect the size of the bitmaps in pixels as it is displayed on the button. For a high DPI display it means the piImageSize needs to be increased to display a bitmap at the size that looks good. 24x24 seems to be correct instead of 16x16 when running at 150%. (I posted a message about this issue on Monday.)
I tried setting up an imagelist32 for the button. The piImageWidth/piImageHeight properties in the image list also seem to have no effect on which icon is used in an .ico file with multiple sizes present. It uses the 48x48 size and scales that icon to whatever you have piImageWidth/piImageHeight set to when running DPI aware, and the 32x32 size when running DPI unaware. So it seems like the same logic is used for imagelist's when they pick which icon size to use.
Maybe we need some way to access/override the logic used by the runtime when picking the icon sizes for buttons/tab pages/imagelists?
Re: DPI and icon sizes in sets
Hi DAW
This is now working as I would expect :), choosing the correct icon size from an icon set based on the set image size.
Next question to make it DPI aware ourselves, what's the method to determine the current DPI?
Re: DPI and icon sizes in sets
Hi Tom,
This is what I came up with. You could of course combine the two functions if you like but I prefer to have them separated because it gives me more options that is needed in some cases;
[CODE]
// Returns: DPI setting as an integer.
// Normal DPI setting: iDPI=96 is "Normal setting" 100%
// iDPI=120 is "Medium setting" 125%
// iDPI= 144 is "Large setting" 150%
Function GetCurrentDPI Returns Integer
Handle hDC
Integer iPixelsX
Move (GetDC(0)) to hDC
Move (GetDeviceCaps(hDC, LOGPIXELSX)) to iPixelsX
Move (ReleaseDC(0, hDC)) to hDC
Function_Return iPixelsX
End_Function
Function GetCorrectIconSize Returns Integer
Integer iPixelsX iRetval
Get GetCurrentDPI to iPixelsX
Case Begin
Case (iPixelsX < 120)
Move 16 to iRetval
Case Break
Case (iPixelsX = 120)
Move 24 to iRetval
Case Break
Case (iPixelsX = 144)
Move 32 to iRetval
Case Break
Case (iPixelsX > 144)
Move 48 to iRetval
Case Break
Case End
Function_Return iRetval
End_Function
[/CODE]
Which you could e.g. use in a sub-classed button class;
[CODE]
Class Button2 is a Button
Procedure Construct_Object
Integer iIconSize
Forward Send Construct_Object
Get GetCorrectIconSize to iIconSize
Set piImageSize to iIconSize
End_Procedure
End_Class
[/CODE]
Hope this helps!
Re: DPI and icon sizes in sets
Hi Nils,
[QUOTE=Nils G. Svedmyr;324040]This is what I came up with.
...
Hope this helps![/QUOTE]
Certainly does. And thanks for sharing.
Re: DPI and icon sizes in sets
I know I'm a little late to the part on this, but can I suggest a small tweak to this (very helpful) function? Unless I'm misunderstanding, it looks like at the moment that it assumes that your starting point is always a 16x16 image. But if I had a larger button with an image that was 32x32, then this function will actually make it smaller when running at 125% scaling because it will set it be size 24x24
I'm sure there's a more elegant way of handling this, but I changed it to:
[CODE]
Function GetCorrectIconSize Returns Integer
Integer iPixelsX iIndex iSize
Integer[] iaSizes
Move 16 to iaSizes[0]
Move 24 to iaSizes[1]
Move 32 to iaSizes[2]
Move 48 to iaSizes[3]
Move 64 to iaSizes[4]
Get piImageSize to iSize // the "100%" size
Move (SearchArray(iSize,iaSizes)) to iIndex
Move (0 max iIndex) to iIndex
Get GetCurrentDPI to iPixelsX
// Use a Case Statement here. Wherever we jump in we will continue onwards, regardless of whether
// we match the remaining Case statements or not. So list our Cases in reverse order, meaning we
// will increment iIndex as many times as we need here.
Case Begin
Case (iPixelsX > 144)
Increment iIndex
Case (iPixelsX = 144)
Increment iIndex
Case (iPixelsX = 120)
Increment iIndex
Case End
Move (iIndex min 4) to iIndex
Function_Return iaSizes[iIndex]
End_Function
[/CODE]
And then in the End_Construct_Object of my class I have:
[CODE]
Procedure End_Construct_Object
Integer iIconSize
Get GetCorrectIconSize to iIconSize
Set piImageSize to iIconSize
Forward Send End_Construct_Object
End_Procedure
[/CODE]
So in my object I can set the piImageSize to 32 and at runtime it will be adjusted to 48 with 125% scaling. Or if I set it to 16 it will be adjusted to 24. etc
Re: DPI and icon sizes in sets
Thanks Peter, that makes sense.