1 /*
2  * DockPanelSidebarDragHandler.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 
17 package org.rstudio.core.client.widget;
18 
19 import org.rstudio.core.client.MathUtil;
20 import org.rstudio.core.client.events.MouseDragHandler;
21 
22 import com.google.gwt.event.dom.client.MouseDownEvent;
23 import com.google.gwt.user.client.ui.DockLayoutPanel;
24 import com.google.gwt.user.client.ui.Widget;
25 
26 
27 public abstract class DockPanelSidebarDragHandler extends MouseDragHandler
28 {
DockPanelSidebarDragHandler(DockLayoutPanel panel, Widget sidebar)29    public DockPanelSidebarDragHandler(DockLayoutPanel panel, Widget sidebar)
30    {
31       panel_ = panel;
32       sidebar_ = sidebar;
33    }
34 
35    @Override
beginDrag(MouseDownEvent event)36    public boolean beginDrag(MouseDownEvent event)
37    {
38       initialWidth_ = panel_.getWidgetSize(sidebar_);
39       return true;
40    }
41 
42    @Override
onDrag(MouseDragEvent event)43    public void onDrag(MouseDragEvent event)
44    {
45       double initialWidth = initialWidth_;
46       double xDiff = event.getTotalDelta().getMouseX();
47       double newSize = initialWidth - xDiff;
48 
49       // We allow an extra pixel here just to 'hide' the border
50       // if the outline is maximized, since the 'separator'
51       // lives as part of the outline instead of 'between' the
52       // two widgets
53       double maxSize = panel_.getOffsetWidth() + 1;
54 
55       double clamped = MathUtil.clamp(newSize, 0, maxSize);
56 
57       // If the size is below '5px', interpret this as a request
58       // to close the outline widget.
59       if (clamped < 5)
60          clamped = 0;
61 
62       panel_.setWidgetSize(sidebar_, clamped);
63 
64       onResized(clamped != 0);
65 
66    }
67 
68    @Override
endDrag()69    public void endDrag()
70    {
71       double size = panel_.getWidgetSize(sidebar_);
72 
73       // We only update the preferred size if the user hasn't closed
74       // the widget.
75       if (size > 0)
76          onPreferredWidth(size);
77 
78       onPreferredVisibility(size > 0);
79    }
80 
81 
onResized(boolean visible)82    public abstract void onResized(boolean visible);
onPreferredWidth(double size)83    public void onPreferredWidth(double size) {}
onPreferredVisibility(boolean visible)84    public void onPreferredVisibility(boolean visible) {}
85 
86    final Widget sidebar_;
87    final DockLayoutPanel panel_;
88    double initialWidth_ = 0;
89 }
90 
91