From e1ba4da563d31efbb195446100a6298e8c02f017 Mon Sep 17 00:00:00 2001 From: Kevin Ushey Date: Tue, 2 Jun 2015 15:51:58 -0700 Subject: [PATCH] hook up icon for toggling visibility --- .../views/source/DocumentOutlineWidget.java | 55 ++++++++++++++- .../client/workbench/views/source/Source.java | 48 ++++++++++++- .../editors/text/TextEditingTarget.java | 27 +++++++- .../editors/text/TextEditingTargetWidget.java | 69 ++++++++++++++++++- .../editors/text/events/HideOutlineEvent.java | 44 ++++++++++++ .../editors/text/events/ShowOutlineEvent.java | 44 ++++++++++++ 6 files changed, 280 insertions(+), 7 deletions(-) create mode 100644 src/gwt/src/org/rstudio/studio/client/workbench/views/source/editors/text/events/HideOutlineEvent.java create mode 100644 src/gwt/src/org/rstudio/studio/client/workbench/views/source/editors/text/events/ShowOutlineEvent.java diff --git a/src/gwt/src/org/rstudio/studio/client/workbench/views/source/DocumentOutlineWidget.java b/src/gwt/src/org/rstudio/studio/client/workbench/views/source/DocumentOutlineWidget.java index 0e2d8297b44..6956b55fabd 100644 --- a/src/gwt/src/org/rstudio/studio/client/workbench/views/source/DocumentOutlineWidget.java +++ b/src/gwt/src/org/rstudio/studio/client/workbench/views/source/DocumentOutlineWidget.java @@ -2,13 +2,16 @@ import org.rstudio.core.client.StringUtil; import org.rstudio.core.client.dom.DomUtils; +import org.rstudio.core.client.theme.res.ThemeResources; import org.rstudio.core.client.widget.Toolbar; import org.rstudio.studio.client.server.Void; import org.rstudio.studio.client.workbench.views.source.editors.text.Scope; import org.rstudio.studio.client.workbench.views.source.editors.text.TextEditingTarget; +import org.rstudio.studio.client.workbench.views.source.editors.text.events.HideOutlineEvent; import org.rstudio.studio.client.workbench.views.source.editors.text.events.RenderFinishedEvent; import org.rstudio.studio.client.workbench.views.source.editors.text.status.StatusBarWidget; +import com.google.gwt.animation.client.Animation; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.JsArray; import com.google.gwt.core.client.Scheduler; @@ -19,6 +22,7 @@ import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; +import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.resources.client.ClientBundle; import com.google.gwt.resources.client.CssResource; import com.google.gwt.user.client.Timer; @@ -26,6 +30,7 @@ import com.google.gwt.user.client.ui.DockLayoutPanel; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.Tree; import com.google.gwt.user.client.ui.TreeItem; @@ -133,13 +138,30 @@ public Scope getScopeNode() private final DocumentOutlineTreeEntry entry_; } - public DocumentOutlineWidget(TextEditingTarget target) + public DocumentOutlineWidget(DockLayoutPanel parent, TextEditingTarget target) { + parent_ = parent; container_ = new DockLayoutPanel(Unit.PX); container_.addStyleName(RES.styles().container()); target_ = target; toolbar_ = new Toolbar(); + Widget separator = Toolbar.getSeparator(); + separator.getElement().getStyle().setMarginLeft(-3, Unit.PX); + toolbar_.addLeftWidget(separator); + toolbar_.setVisible(true); + + Image closeIcon = new Image(ThemeResources.INSTANCE.chevron()); + closeIcon.getElement().getStyle().setMarginRight(5, Unit.PX); + closeIcon.addClickHandler(new ClickHandler() + { + @Override + public void onClick(ClickEvent event) + { + hideOutline(true); + } + }); + toolbar_.addRightWidget(closeIcon); container_.addNorth(toolbar_, toolbar_.getHeight()); statusBar_ = new StatusBarWidget(); @@ -282,6 +304,37 @@ private boolean isActiveNode(Scope node) return node.equals(target_.getDocDisplay().getCurrentScope()); } + public HandlerRegistration addHideOutlineHandler(HideOutlineEvent.Handler handler) + { + return addHandler(handler, HideOutlineEvent.TYPE); + } + + public double getSize() + { + return parent_.getWidgetSize(this); + } + + public void setSize(double sizeInPixels) + { + parent_.setWidgetSize(this, sizeInPixels); + } + + private void hideOutline(boolean animate) + { + final int startSize = container_.getOffsetWidth(); + fireEvent(new HideOutlineEvent()); + new Animation() + { + @Override + protected void onUpdate(double progress) + { + int newSize = (int) (startSize * (1 - interpolate(progress))); + parent_.setWidgetSize(DocumentOutlineWidget.this, newSize); + } + }.run(1000); + } + + private final DockLayoutPanel parent_; private final DockLayoutPanel container_; private final Toolbar toolbar_; private final StatusBarWidget statusBar_; diff --git a/src/gwt/src/org/rstudio/studio/client/workbench/views/source/Source.java b/src/gwt/src/org/rstudio/studio/client/workbench/views/source/Source.java index b5f00578b44..2f1aa404c88 100644 --- a/src/gwt/src/org/rstudio/studio/client/workbench/views/source/Source.java +++ b/src/gwt/src/org/rstudio/studio/client/workbench/views/source/Source.java @@ -14,6 +14,7 @@ */ package org.rstudio.studio.client.workbench.views.source; +import com.google.gwt.animation.client.Animation; import com.google.gwt.core.client.JsArray; import com.google.gwt.core.client.JsArrayString; import com.google.gwt.core.client.Scheduler; @@ -46,6 +47,7 @@ import org.rstudio.core.client.command.KeyboardShortcut; import org.rstudio.core.client.command.ShortcutManager; import org.rstudio.core.client.events.*; +import org.rstudio.core.client.events.MouseDragHandler.State; import org.rstudio.core.client.files.FileSystemItem; import org.rstudio.core.client.js.JsObject; import org.rstudio.core.client.widget.Operation; @@ -112,6 +114,8 @@ import org.rstudio.studio.client.workbench.views.source.editors.text.ace.Position; import org.rstudio.studio.client.workbench.views.source.editors.text.events.FileTypeChangedEvent; import org.rstudio.studio.client.workbench.views.source.editors.text.events.FileTypeChangedHandler; +import org.rstudio.studio.client.workbench.views.source.editors.text.events.HideOutlineEvent; +import org.rstudio.studio.client.workbench.views.source.editors.text.events.ShowOutlineEvent; import org.rstudio.studio.client.workbench.views.source.editors.text.events.SourceOnSaveChangedEvent; import org.rstudio.studio.client.workbench.views.source.editors.text.events.SourceOnSaveChangedHandler; import org.rstudio.studio.client.workbench.views.source.editors.text.ui.NewRMarkdownDialog; @@ -2068,10 +2072,47 @@ public void onResponseReceived(SourceDocument document) }); } - Widget createWidgetWithOutline(TextEditingTarget target) + Widget createWidgetWithOutline(final TextEditingTarget target) { final DockLayoutPanel panel = new DockLayoutPanel(Unit.PX); - final DocumentOutlineWidget outline = new DocumentOutlineWidget(target); + final DocumentOutlineWidget outline = new DocumentOutlineWidget(panel, target); + + outline.addHideOutlineHandler(new HideOutlineEvent.Handler() + { + @Override + public void onHideOutline(HideOutlineEvent event) + { + target.showOutlineIcon(true); + } + }); + + target.addShowOutlineHandler(new ShowOutlineEvent.Handler() + { + final State state = State.create(); + + @Override + public void onShowOutline(ShowOutlineEvent event) + { + new Animation() + { + @Override + protected void onStart() + { + state.set("initial.size", outline.getSize()); + } + + @Override + protected void onUpdate(double progress) + { + double initialSize = state.get("initial.size"); + double ratio = interpolate(progress); + outline.setSize( + (200 * ratio) + + (initialSize * (1 - ratio))); + } + }.run(1000); + } + }); MouseDragHandler.addHandler( outline.getLeftSeparator(), @@ -2102,7 +2143,8 @@ public void onDrag(MouseDragEvent event, State state) Widget createWidget(EditingTarget target) { - if (target instanceof TextEditingTarget && ((TextEditingTarget) target).getDocDisplay().hasScopeTree()) + if (target instanceof TextEditingTarget && + ((TextEditingTarget) target).getDocDisplay().hasScopeTree()) return createWidgetWithOutline((TextEditingTarget) target); return target.asWidget(); diff --git a/src/gwt/src/org/rstudio/studio/client/workbench/views/source/editors/text/TextEditingTarget.java b/src/gwt/src/org/rstudio/studio/client/workbench/views/source/editors/text/TextEditingTarget.java index 6c540114142..b74d572c1aa 100644 --- a/src/gwt/src/org/rstudio/studio/client/workbench/views/source/editors/text/TextEditingTarget.java +++ b/src/gwt/src/org/rstudio/studio/client/workbench/views/source/editors/text/TextEditingTarget.java @@ -27,6 +27,7 @@ import com.google.gwt.event.shared.GwtEvent; import com.google.gwt.event.shared.HandlerManager; import com.google.gwt.event.shared.HandlerRegistration; +import com.google.gwt.event.shared.HasHandlers; import com.google.gwt.http.client.URL; import com.google.gwt.resources.client.ImageResource; import com.google.gwt.safehtml.shared.SafeHtmlBuilder; @@ -166,8 +167,9 @@ interface MyCommandBinder private static final MyCommandBinder commandBinder = GWT.create(MyCommandBinder.class); - public interface Display extends TextDisplay, + public interface Display extends TextDisplay, WarningBarDisplay, + HasHandlers, HasEnsureVisibleHandlers, HasEnsureHeightHandlers { @@ -181,6 +183,8 @@ public interface Display extends TextDisplay, void replaceAndFind(); StatusBar getStatusBar(); + + void showOutlineIcon(boolean show); boolean isAttached(); @@ -197,9 +201,13 @@ void setFormatOptions(TextFileType fileType, List extensions, String selected); void setFormatOptionsVisible(boolean visible); + HandlerRegistration addRmdFormatChangedHandler( RmdOutputFormatChangedEvent.Handler handler); + HandlerRegistration addShowOutlineHandler(ShowOutlineEvent.Handler handler); + HandlerRegistration addHideOutlineHandler(HideOutlineEvent.Handler handler); + void setPublishPath(String type, String publishPath); } @@ -1525,7 +1533,7 @@ public String getSelectedText() else return ""; } - + public HandlerRegistration addEnsureVisibleHandler(EnsureVisibleHandler handler) { return view_.addEnsureVisibleHandler(handler); @@ -1540,6 +1548,16 @@ public HandlerRegistration addCloseHandler(CloseHandler handler) { return handlers_.addHandler(CloseEvent.getType(), handler); } + + public HandlerRegistration addHideOutlineHandler(HideOutlineEvent.Handler handler) + { + return view_.addHideOutlineHandler(handler); + } + + public HandlerRegistration addShowOutlineHandler(ShowOutlineEvent.Handler handler) + { + return view_.addShowOutlineHandler(handler); + } public void fireEvent(GwtEvent event) { @@ -4826,6 +4844,11 @@ private void syncPublishPath(String path) } } + public void showOutlineIcon(boolean show) + { + view_.showOutlineIcon(show); + } + private StatusBar statusBar_; private final DocDisplay docDisplay_; private final UIPrefs prefs_; diff --git a/src/gwt/src/org/rstudio/studio/client/workbench/views/source/editors/text/TextEditingTargetWidget.java b/src/gwt/src/org/rstudio/studio/client/workbench/views/source/editors/text/TextEditingTargetWidget.java index e960ec677f6..7052928ba24 100644 --- a/src/gwt/src/org/rstudio/studio/client/workbench/views/source/editors/text/TextEditingTargetWidget.java +++ b/src/gwt/src/org/rstudio/studio/client/workbench/views/source/editors/text/TextEditingTargetWidget.java @@ -16,6 +16,7 @@ import java.util.List; +import com.google.gwt.animation.client.Animation; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.dom.client.Style.Unit; @@ -58,6 +59,8 @@ import org.rstudio.studio.client.workbench.views.source.PanelWithToolbars; import org.rstudio.studio.client.workbench.views.source.editors.EditingTargetToolbar; import org.rstudio.studio.client.workbench.views.source.editors.text.TextEditingTarget.Display; +import org.rstudio.studio.client.workbench.views.source.editors.text.events.HideOutlineEvent; +import org.rstudio.studio.client.workbench.views.source.editors.text.events.ShowOutlineEvent; import org.rstudio.studio.client.workbench.views.source.editors.text.findreplace.FindReplaceBar; import org.rstudio.studio.client.workbench.views.source.editors.text.status.StatusBar; import org.rstudio.studio.client.workbench.views.source.editors.text.status.StatusBarWidget; @@ -257,6 +260,34 @@ public void onValueChange(ValueChangeEvent event) toolbar.addRightWidget(publishButton_); } + toolbar.addRightSeparator(); + viewOutlineIcon_ = new Image(ThemeResources.INSTANCE.chevron()); + viewOutlineIcon_.getElement().getStyle().setMarginRight(5, Unit.PX); + viewOutlineIcon_.addHandler(new ClickHandler() + { + @Override + public void onClick(ClickEvent event) + { + fireEvent(new ShowOutlineEvent()); + new Animation() + { + @Override + protected void onUpdate(double progress) + { + viewOutlineIcon_.getElement().getStyle().setOpacity(1 - progress); + } + + @Override + protected void onComplete() + { + viewOutlineIcon_.setVisible(false); + toolbar_.invalidateSeparators(); + } + }.run(1000); + } + }, ClickEvent.getType()); + toolbar.addRightWidget(viewOutlineIcon_); + return toolbar; } @@ -746,7 +777,7 @@ else if (shinyAppState_.equals(ShinyApplicationParams.STATE_STOPPED)) sourceButton_.setTitle(sourceCommandDesc); sourceButton_.setText(sourceCommandText_); } - + public HandlerRegistration addEnsureVisibleHandler(EnsureVisibleHandler handler) { return addHandler(handler, EnsureVisibleEvent.TYPE); @@ -788,6 +819,41 @@ private void addRmdViewerMenuItems(ToolbarPopupMenu menu) menu.addItem(rmdViewerWindowMenuItem_); } + public HandlerRegistration addShowOutlineHandler(ShowOutlineEvent.Handler handler) + { + return addHandler(handler, ShowOutlineEvent.TYPE); + } + + public HandlerRegistration addHideOutlineHandler(HideOutlineEvent.Handler handler) + { + return addHandler(handler, HideOutlineEvent.TYPE); + } + + public void showOutlineIcon(boolean show) + { + new Animation() + { + @Override + protected void onStart() + { + viewOutlineIcon_.setVisible(true); + viewOutlineIcon_.getElement().getStyle().setOpacity(0); + } + + @Override + protected void onUpdate(double progress) + { + viewOutlineIcon_.getElement().getStyle().setOpacity(progress); + } + + @Override + protected void onComplete() + { + toolbar_.invalidateSeparators(); + } + }.run(1000); + } + private final Commands commands_; private final UIPrefs uiPrefs_; private final Session session_; @@ -814,6 +880,7 @@ private void addRmdViewerMenuItems(ToolbarPopupMenu menu) private ToolbarButton rcppHelpButton_; private ToolbarButton shinyLaunchButton_; private ToolbarButton editRmdFormatButton_; + private Image viewOutlineIcon_; private ToolbarPopupMenuButton rmdFormatButton_; private RSConnectPublishButton publishButton_; private MenuItem rmdViewerPaneMenuItem_; diff --git a/src/gwt/src/org/rstudio/studio/client/workbench/views/source/editors/text/events/HideOutlineEvent.java b/src/gwt/src/org/rstudio/studio/client/workbench/views/source/editors/text/events/HideOutlineEvent.java new file mode 100644 index 00000000000..bfa9140279b --- /dev/null +++ b/src/gwt/src/org/rstudio/studio/client/workbench/views/source/editors/text/events/HideOutlineEvent.java @@ -0,0 +1,44 @@ +/* + * HideOutlineEvent.java + * + * Copyright (C) 2009-12 by RStudio, Inc. + * + * Unless you have received this program directly from RStudio pursuant + * to the terms of a commercial license agreement with RStudio, then + * this program is licensed to you under the terms of version 3 of the + * GNU Affero General Public License. This program is distributed WITHOUT + * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the + * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details. + * + */ +package org.rstudio.studio.client.workbench.views.source.editors.text.events; + +import com.google.gwt.event.shared.EventHandler; +import com.google.gwt.event.shared.GwtEvent; + +public class HideOutlineEvent extends GwtEvent +{ + public interface Handler extends EventHandler + { + void onHideOutline(HideOutlineEvent event); + } + + public HideOutlineEvent() + { + } + + @Override + public Type getAssociatedType() + { + return TYPE; + } + + @Override + protected void dispatch(Handler handler) + { + handler.onHideOutline(this); + } + + public static final Type TYPE = new Type(); +} diff --git a/src/gwt/src/org/rstudio/studio/client/workbench/views/source/editors/text/events/ShowOutlineEvent.java b/src/gwt/src/org/rstudio/studio/client/workbench/views/source/editors/text/events/ShowOutlineEvent.java new file mode 100644 index 00000000000..55379fc077b --- /dev/null +++ b/src/gwt/src/org/rstudio/studio/client/workbench/views/source/editors/text/events/ShowOutlineEvent.java @@ -0,0 +1,44 @@ +/* + * ShowOutlineEvent.java + * + * Copyright (C) 2009-12 by RStudio, Inc. + * + * Unless you have received this program directly from RStudio pursuant + * to the terms of a commercial license agreement with RStudio, then + * this program is licensed to you under the terms of version 3 of the + * GNU Affero General Public License. This program is distributed WITHOUT + * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the + * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details. + * + */ +package org.rstudio.studio.client.workbench.views.source.editors.text.events; + +import com.google.gwt.event.shared.EventHandler; +import com.google.gwt.event.shared.GwtEvent; + +public class ShowOutlineEvent extends GwtEvent +{ + public interface Handler extends EventHandler + { + void onShowOutline(ShowOutlineEvent event); + } + + public ShowOutlineEvent() + { + } + + @Override + public Type getAssociatedType() + { + return TYPE; + } + + @Override + protected void dispatch(Handler handler) + { + handler.onShowOutline(this); + } + + public static final Type TYPE = new Type(); +}