/*
* SourcePane.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;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Style.Cursor;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.BeforeSelectionHandler;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.ui.*;
import com.google.inject.Inject;
import org.rstudio.core.client.events.*;
import org.rstudio.core.client.layout.RequiresVisibilityChanged;
import org.rstudio.core.client.resources.ImageResource2x;
import org.rstudio.core.client.theme.DocTabLayoutPanel;
import org.rstudio.core.client.theme.res.ThemeResources;
import org.rstudio.core.client.theme.res.ThemeStyles;
import org.rstudio.core.client.widget.BeforeShowCallback;
import org.rstudio.core.client.widget.OperationWithInput;
import org.rstudio.studio.client.common.AutoGlassAttacher;
import org.rstudio.studio.client.workbench.model.UnsavedChangesTarget;
import org.rstudio.studio.client.workbench.ui.unsaved.UnsavedChangesDialog;
import org.rstudio.studio.client.workbench.views.source.Source.Display;
import java.util.ArrayList;
public class SourcePane extends Composite implements Display,
HasEnsureVisibleHandlers,
HasEnsureHeightHandlers,
RequiresResize,
ProvidesResize,
BeforeShowCallback,
RequiresVisibilityChanged
{
@Inject
public SourcePane()
{
final int UTILITY_AREA_SIZE = 74;
panel_ = new LayoutPanel();
new AutoGlassAttacher(panel_);
tabPanel_ = new DocTabLayoutPanel(true, 65, UTILITY_AREA_SIZE);
panel_.add(tabPanel_);
panel_.setWidgetTopBottom(tabPanel_, 0, Unit.PX, 0, Unit.PX);
panel_.setWidgetLeftRight(tabPanel_, 0, Unit.PX, 0, Unit.PX);
utilPanel_ = new HTML();
utilPanel_.setStylePrimaryName(ThemeStyles.INSTANCE.multiPodUtilityArea());
panel_.add(utilPanel_);
panel_.setWidgetRightWidth(utilPanel_,
0, Unit.PX,
UTILITY_AREA_SIZE, Unit.PX);
panel_.setWidgetTopHeight(utilPanel_, 0, Unit.PX, 22, Unit.PX);
tabOverflowPopup_ = new TabOverflowPopupPanel();
tabOverflowPopup_.addCloseHandler(new CloseHandler<PopupPanel>()
{
public void onClose(CloseEvent<PopupPanel> popupPanelCloseEvent)
{
manageChevronVisibility();
}
});
chevron_ = new Image(new ImageResource2x(ThemeResources.INSTANCE.chevron2x()));
chevron_.getElement().getStyle().setCursor(Cursor.POINTER);
chevron_.addClickHandler(new ClickHandler()
{
public void onClick(ClickEvent event)
{
tabOverflowPopup_.showRelativeTo(chevron_);
}
});
panel_.add(chevron_);
panel_.setWidgetTopHeight(chevron_,
8, Unit.PX,
chevron_.getHeight(), Unit.PX);
panel_.setWidgetRightWidth(chevron_,
52, Unit.PX,
chevron_.getWidth(), Unit.PX);
initWidget(panel_);
}
@Override
protected void onLoad()
{
super.onLoad();
Scheduler.get().scheduleDeferred(new ScheduledCommand()
{
public void execute()
{
onResize();
}
});
}
public void addTab(Widget widget,
ImageResource icon,
String docId,
String name,
String tooltip,
Integer position,
boolean switchToTab)
{
tabPanel_.add(widget, icon, docId, name, tooltip, position);
if (switchToTab)
tabPanel_.selectTab(widget);
}
public void closeTab(Widget child, boolean interactive)
{
closeTab(child, interactive, null);
}
public void closeTab(Widget child, boolean interactive, Command onClosed)
{
closeTab(tabPanel_.getWidgetIndex(child), interactive, onClosed);
}
public void closeTab(int index, boolean interactive)
{
closeTab(index, interactive, null);
}
public void closeTab(int index, boolean interactive, Command onClosed)
{
if (interactive)
tabPanel_.tryCloseTab(index, onClosed);
else
tabPanel_.closeTab(index, onClosed);
}
public void setDirty(Widget widget, boolean dirty)
{
Widget tab = tabPanel_.getTabWidget(widget);
if (dirty)
tab.addStyleName(ThemeStyles.INSTANCE.dirtyTab());
else
tab.removeStyleName(ThemeStyles.INSTANCE.dirtyTab());
}
public void ensureVisible()
{
fireEvent(new EnsureVisibleEvent());
}
public void renameTab(Widget child,
ImageResource icon,
String value,
String tooltip)
{
tabPanel_.replaceDocName(tabPanel_.getWidgetIndex(child),
icon,
value,
tooltip);
}
public int getActiveTabIndex()
{
return tabPanel_.getSelectedIndex();
}
public void selectTab(int tabIndex)
{
tabPanel_.selectTab(tabIndex);
}
public void selectTab(Widget child)
{
tabPanel_.selectTab(child);
}
public int getTabCount()
{
return tabPanel_.getWidgetCount();
}
@Override
public void moveTab(int index, int delta)
{
tabPanel_.moveTab(index, delta);
}
public HandlerRegistration addTabClosingHandler(TabClosingHandler handler)
{
return tabPanel_.addTabClosingHandler(handler);
}
public HandlerRegistration addTabCloseHandler(
TabCloseHandler handler)
{
return tabPanel_.addTabCloseHandler(handler);
}
public HandlerRegistration addTabClosedHandler(TabClosedHandler handler)
{
return tabPanel_.addTabClosedHandler(handler);
}
@Override
public HandlerRegistration addTabReorderHandler(TabReorderHandler handler)
{
return tabPanel_.addTabReorderHandler(handler);
}
public HandlerRegistration addSelectionHandler(SelectionHandler<Integer> handler)
{
return tabPanel_.addSelectionHandler(handler);
}
public HandlerRegistration addBeforeSelectionHandler(BeforeSelectionHandler<Integer> handler)
{
return tabPanel_.addBeforeSelectionHandler(handler);
}
public Widget asWidget()
{
return this;
}
public HandlerRegistration addEnsureVisibleHandler(EnsureVisibleHandler handler)
{
return addHandler(handler, EnsureVisibleEvent.TYPE);
}
@Override
public HandlerRegistration addEnsureHeightHandler(
EnsureHeightHandler handler)
{
return addHandler(handler, EnsureHeightEvent.TYPE);
}
public void onResize()
{
panel_.onResize();
manageChevronVisibility();
}
public void manageChevronVisibility()
{
int tabsWidth = tabPanel_.getTabsEffectiveWidth();
setOverflowVisible(tabsWidth > getOffsetWidth() - 50);
}
public void showOverflowPopup()
{
setOverflowVisible(true);
tabOverflowPopup_.showRelativeTo(chevron_);
}
@Override
public void showUnsavedChangesDialog(
String title,
ArrayList<UnsavedChangesTarget> dirtyTargets,
OperationWithInput<UnsavedChangesDialog.Result> saveOperation,
Command onCancelled)
{
new UnsavedChangesDialog(title,
dirtyTargets,
saveOperation,
onCancelled).showModal();
}
private void setOverflowVisible(boolean visible)
{
utilPanel_.setVisible(visible);
chevron_.setVisible(visible);
}
public void onBeforeShow()
{
fireEvent(new BeforeShowEvent());
}
public HandlerRegistration addBeforeShowHandler(BeforeShowHandler handler)
{
return addHandler(handler, BeforeShowEvent.TYPE);
}
public void onVisibilityChanged(boolean visible)
{
if (getActiveTabIndex() >= 0)
{
Widget w = tabPanel_.getTabWidget(getActiveTabIndex());
if (w instanceof RequiresVisibilityChanged)
((RequiresVisibilityChanged)w).onVisibilityChanged(visible);
}
}
public void cancelTabDrag()
{
tabPanel_.cancelTabDrag();
}
private DocTabLayoutPanel tabPanel_;
private HTML utilPanel_;
private Image chevron_;
private LayoutPanel panel_;
private PopupPanel tabOverflowPopup_;
}