In the past couple of years the monitor pixel resolution has increased dramatically. Some years ago we were all happy with HD resolution or even Full HD resolution. Then "Retina" displays were promoted and now we reached a new all time height with 4 K monitors. Monitors with 4000 pixel in width.
So how do we write SWT code that runs on 800 x 600 AND also on 3840 x 2160 ?
While there are good strategies for scaling applications on Smartphones (iPhones and Android phones each using different approaches) there is no single good approach for desktops.
As an example think of a Login Dialog that you set to a fixed size of 400 x 200 pixels. Thats work great on a lot of screens but then the resolution goes up and the physical size stays the same and soon you need a magnifying glass to read it. Or Icons that you supplied with 16x16 pixels. Leaving them small or upscaling them is not an option.
So what is the solution here ?
This presentation will concentrate on desktop applications and covers all of the following aspects
- Examples of well-known applications that fail when asked to scale up to high resolution
- Which parts of SWT scales automatically and where do you need to add your own logic ?
- Frame and Dialog
- Layouts
- Layouts used for SWT views
- Layouts used for tables (header, column formatter)
- Images
- icons in buttons, menuitems, toolbars
- icon in various sizes
- icons using SVG
- Scaling the whole application
- navigation area
- close application button
- title bars
Most the proposed approaches are also available in Eclipse Riena (which we use as guinea pig) but can be achieved with any SWT application.
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Scaling SWT on high-resolution screens
1. Scaling SWT on high-res screens
Christian Campo, ECE 2014
2. Overview
• High resolution Displays
• „Windows“ based Scaling
• Desktop Applications based Scaling
› Layout (Size, Gap)
› Icons
› SVG
• Use Eclipse Riena as an example
10. Scaling Up
• Smartphones
› Scaling Up is very common
› Same UI on different resolution / sizes
• „Windows“
› no automatic scaling
› Ability for the user to define a scaling
11. Scaling Up in „Windows“
• „Make text and other items larger or smaller“
• Applied after Logoff and Login
• Change of „Logical DPI“ not „Physical DPI“
• 100 % = 96 DPI
12. Eclipse IDE - Resolution
› 3840*2160– Skalierung 100 %
15. Scaling Up in „Windows“
• Doesnt work well with all applications
• Problems
› Widgets or text are not scaled
› Blury Icons, Images
› Icons are upscaled
16. VLC
100 % 150 %
• Buttons DONT scale
• Text scales
21. The Goal
• Change „DPI“ in „Windows“
• Application should adapt Scaling:
› Windows size
› Navigationpanel size (if exists)
› Icon size, Toolbars, Menus
› Fonts, Textfield length
› Tree
› Etc.
22. SWT
› SWT Standard-Widgets
› native Widgets of the Operation System
› Fonts are scaled
› Sizes (mostly) correct ??
› Images are partially scaled
› OS Images are scaled
(e.g. Button with Arrow)
› Custom Images (gif, png) are NOT scaled
(e.g. Tree Images)
› SWT Standard-Layouts
(i.e. GridLayout, FormLayout etc.)
› Uses information from the SWT Widgets
› Sizes are not scaled
› i.e. widthHint, horizontalIndent
23. Eclipse
100 % 150 %
- Size Icon in Tree
- Size Toolbar Icon
24. Eclipse
100 % 500 %
Windows 7 Windows 8.1
- Tree icons
- Toolbar icons
33. SWT (Utility)
• DPI factors
100 % = 96 DPI = 1.0.
125 % = 120 DPI = 1.25
133 % = 128 DPI = 1.33
150 % = 144 DPI = 1.5
200 % = 192 DPI = 2.0
300 % = 288 DPI = 3.0
Note: DPI Factors could be different for X and Y but the Windows
API underneath always delivers the same values for X and Y.
34. Step 2 (Layout)
• GridLayout
› DpiGridLayout
› Copy of GridLayout*
› Scales values internally
- widthHint
- horizontalIndent
- marginWidth
- …
› GridData
(internally converted to DpiGridData)
› Swap GridLayout with DpiGridLayout in Riena
Applications
› DpiGridLayoutFactory
Note: *GridLayout is final -> Eclipse Bug #443008
35. Step 2 (Layout - example)
setLayoutData(GridData data)
• On „parent.layout()“ the DpiGridlayout converts GridData
into DpiGridData and stores it with setData(..., DpiGridData x)
38. Step3 (Icons and Images)
› Images
› „Scaling“
› One Image – several Scaling Levels
Skalierung Größe Suffix
100 % 16x16 px 00
125 % 20x20 px 01
133 % 21x21 px 02
150 % 24x24 px 03
› One PNG per Level
39. Step3 (Icons and Images)
• ImageStore.getImage(„0022a“);
• getDpiFactor() -> 1 -> suffix = „00“
• Search for „0022a00.png“
• Return SWT Image object
Note: ImageStore is a class in Riena
// always „png“ if no extension is given
40. Step3 (Images „extended“)
Actual image names can be more complex in Riena
0022a_p_00.png
0022 = image name
a = image size(a=16x16, b=22x22 etc.)
_p_ = image state (_p_= „pressed“, _d_ = „disabled“
00 = dpi scale factor (00 = 100% etc)
id = iconManager.getIconID(„0022“, IconSize.A16, IconState.PRESSED);
image = ImageStore.getInstance().getImage(id);
// implicit adds dpi scale factor „00“
42. Riena internal
› Width and Height of Shell
› Width of Navigationtree
› Checkboxes in tables (not in column 1)
› Statusbar
› PopupList with UIProcess (Jobs)
› InfoFlyout
43. Step 4: More Scaling
• DPI Factors get larger and larger
• Many different images for the various levels
• Use vector graphics and scale at runtime ?
• SVG ?
44. Step 4: More Scaling
• Image as SVG
› Vectorgraphics – stepless – limitless
› Not directly supported by SWT
› Using SVG Salamander
› https://svgsalamander.java.net/
› SVG -> AWT Image
› AWT Image -> SWT Image
› converted SWT Images are cached
45. Step 4: More Scaling
• Image as SVG
› Can be used for
› Image Sizes (a,b,c,d,e,f)
› Image Scaling (00,01,02,03)
› ONE Image per State
id = iconManager.getIconID(„cloud“, IconSize.A16);
image = ImageStore.getInstance().getImage(id);
46. Pitfalls
› Getting the DPI factor
› Only in UI Thread
› Rounding problems when scaling
› Round up / down
› Distinguish scaled numbers from
unscaled numbers
› E.g. Layout
› GridData.widthHint
› DpiGridLayout