1 /*
2  * ZoomUtils.java
3  *
4  * Copyright (C) 2021 by RStudio, PBC
5  *
6  * Unless you have received this program directly from RStudio pursuant
7  * to the terms of a commercial license agreement with RStudio, then
8  * this program is licensed to you under the terms of version 3 of the
9  * GNU Affero General Public License. This program is distributed WITHOUT
10  * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
11  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
12  * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
13  *
14  */
15 
16 package org.rstudio.studio.client.common.zoom;
17 
18 import org.rstudio.core.client.Size;
19 import org.rstudio.core.client.dom.NativeScreen;
20 import org.rstudio.core.client.dom.WindowEx;
21 import org.rstudio.core.client.widget.OperationWithInput;
22 import org.rstudio.studio.client.RStudioGinjector;
23 import org.rstudio.studio.client.common.GlobalDisplay.NewWindowOptions;
24 
25 import com.google.gwt.user.client.Window;
26 
27 
28 public class ZoomUtils
29 {
getZoomWindowSize(Size sourceFrameSize, Size defaultSize)30    public static Size getZoomWindowSize(Size sourceFrameSize, Size defaultSize)
31    {
32       int width, height;
33       if (defaultSize != null)
34       {
35          // trim based on available screen size
36          NativeScreen screen = NativeScreen.get();
37          width = Math.min(screen.getAvailWidth(), defaultSize.width);
38          height = Math.min(screen.getAvailHeight(), defaultSize.height);
39       }
40       else
41       {
42          final int PADDING = 20;
43 
44          // calculate ideal height and width. try to be as large as possible
45          // within the bounds of the current client size
46          Size bounds = new Size(Window.getClientWidth() - PADDING,
47                                 Window.getClientHeight() - PADDING);
48 
49          float widthRatio = bounds.width / ((float)sourceFrameSize.width);
50          float heightRatio = bounds.height / ((float)sourceFrameSize.height);
51          float ratio = Math.min(widthRatio, heightRatio);
52 
53          // constrain initial width to between 300 and 1,200 pixels
54          width = Math.max(300, (int) (ratio * sourceFrameSize.width));
55          width = Math.min(1200, width);
56 
57          // constrain initial height to between 300 and 900 pixels
58          height = Math.max(300, (int) (ratio * sourceFrameSize.height));
59          height = Math.min(900, height);
60       }
61 
62       return new Size(width, height);
63    }
64 
getZoomedSize(Size size, Size minSize, Size maxSize)65    public static Size getZoomedSize(Size size, Size minSize, Size maxSize)
66    {
67       float widthRatio = maxSize.width / ((float)size.width);
68       float heightRatio = maxSize.height / ((float)size.height);
69       float ratio = Math.min(widthRatio, heightRatio);
70 
71       // constrain width
72       int width = Math.max(minSize.width, (int) (ratio * size.width));
73       width = Math.min(maxSize.width, width);
74 
75       // constrain height
76       int height = Math.max(minSize.height, (int) (ratio * size.height));
77       height = Math.min(maxSize.height, height);
78 
79       return new Size(width, height);
80    }
81 
openZoomWindow(String name, String url, Size size, final OperationWithInput<WindowEx> onOpened)82    public static void openZoomWindow(String name, String url, Size size,
83                                      final OperationWithInput<WindowEx> onOpened)
84    {
85       NewWindowOptions options = new NewWindowOptions();
86       options.setName(name);
87       options.setFocus(true);
88       options.setCallback(onOpened);
89       RStudioGinjector.INSTANCE.getGlobalDisplay().openMinimalWindow(
90                                        url,
91                                        false,
92                                        size.width,
93                                        size.height,
94                                        options);
95    }
96 
97 
98 }
99