package com.project.website.canvas.client.canvastools.video; import java.util.ArrayList; import java.util.Collection; import com.google.common.base.Objects; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.LoadEvent; import com.google.gwt.event.dom.client.LoadHandler; import com.google.gwt.event.dom.client.MouseDownEvent; import com.google.gwt.event.dom.client.MouseDownHandler; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.DialogBox; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.Frame; import com.google.gwt.user.client.ui.HTMLPanel; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import com.project.shared.client.events.SimpleEvent; import com.project.shared.client.handlers.RegistrationsManager; import com.project.shared.client.utils.ElementUtils; import com.project.shared.client.utils.UrlUtils; import com.project.shared.client.utils.widgets.DialogWithZIndex; import com.project.shared.client.utils.widgets.WidgetUtils; import com.project.shared.data.Point2D; import com.project.shared.utils.StringUtils; import com.project.website.canvas.client.canvastools.base.CanvasToolCommon; import com.project.website.canvas.client.canvastools.base.CanvasToolEvents; import com.project.website.canvas.client.canvastools.base.ResizeMode; import com.project.website.canvas.client.canvastools.base.eventargs.LoadStartedEventArgs; import com.project.website.canvas.client.canvastools.base.interfaces.CanvasTool; import com.project.website.canvas.client.canvastools.base.interfaces.ICanvasToolEvents; import com.project.website.canvas.client.resources.CanvasResources; import com.project.website.canvas.client.shared.dialogs.SelectVideoDialog; import com.project.website.canvas.client.shared.searchProviders.interfaces.VideoSearchProvider; import com.project.website.canvas.shared.data.ElementData; import com.project.website.canvas.shared.data.VideoData; import com.project.website.canvas.shared.data.VideoInformation; public class VideoTool extends Composite implements CanvasTool<VideoData> { private static VideoToolUiBinder uiBinder = GWT.create(VideoToolUiBinder.class); interface VideoToolUiBinder extends UiBinder<Widget, VideoTool>{ } @UiField HTMLPanel rootPanel; @UiField Button optionsLabel; @UiField FlowPanel optionsBar; @UiField Frame videoFrame; private static final String OPTIONS_LABEL_VIDEO_SET = "Change video..."; private CanvasToolEvents _toolEvents = new CanvasToolEvents(this); private final RegistrationsManager registrationsManager = new RegistrationsManager(); private final RegistrationsManager _editModeRegistrations = new RegistrationsManager(); private VideoData data = null; private SelectVideoDialog selectVideoDialog; private DialogBox dialogContainer; private boolean optionsWidgetInited = false; private ArrayList<VideoSearchProvider> searchProviders = new ArrayList<VideoSearchProvider>(); private boolean viewMode; public VideoTool(Collection<VideoSearchProvider> videoSearchProviders) { initWidget(uiBinder.createAndBindUi(this)); CanvasToolCommon.initCanvasToolWidget(this); this.registerGeneralHandlers(); searchProviders.addAll(videoSearchProviders); WidgetUtils.mouseDownPreventDefault(this); super.addStyleName(CanvasResources.INSTANCE.main().videoToolEmpty()); //this.videoFrame.setVisible(false); } @Override public ICanvasToolEvents getToolEvents() { return this._toolEvents; } @Override public void bind() { super.setTitle("Control-click to drag"); this.setViewMode(viewMode); // do whatever bindings necessary for our mode } @Override protected void onLoad() { super.onLoad(); ElementUtils.setTextSelectionEnabled(this.getElement(), false); } private void registerGeneralHandlers() { registrationsManager.add(this.videoFrame.addLoadHandler(new LoadHandler() { @Override public void onLoad(LoadEvent event) { _toolEvents.dispatchLoadEndedEvent(); } })); } private void registerEditModeHandlers() { this._editModeRegistrations.add(this.rootPanel.addDomHandler(new MouseDownHandler() { @Override public void onMouseDown(MouseDownEvent event) { if (event.isControlKeyDown()) { _toolEvents.dispatchMoveStartRequestEvent(event); } } }, MouseDownEvent.getType())); this._editModeRegistrations.add(this.optionsLabel.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { showOptionsDialog(); } })); } private void showOptionsDialog() { initOptionsWidget(); this.selectVideoDialog.setValue(new VideoInformation(data.videoInformation)); Scheduler.get().scheduleDeferred(new ScheduledCommand() { @Override public void execute() { selectVideoDialog.setFocus(true); dialogContainer.center(); } }); } private void initOptionsWidget() { if (optionsWidgetInited) { return; } this.optionsWidgetInited = true; this.dialogContainer = new DialogWithZIndex(false, true); dialogContainer.setGlassEnabled(true); dialogContainer.setText("Video options"); this.selectVideoDialog = new SelectVideoDialog(); dialogContainer.add(this.selectVideoDialog); this.selectVideoDialog.setSearchProviders(this.searchProviders); this.selectVideoDialog.addCancelHandler(new SimpleEvent.Handler<Void>() { @Override public void onFire(Void arg) { dialogContainer.hide(); } }); this.selectVideoDialog.addDoneHandler(new SimpleEvent.Handler<VideoInformation>() { @Override public void onFire(VideoInformation arg) { setVideoInformation(arg); dialogContainer.hide(); } }); } private void setVideoInformation(VideoInformation videoInformation) { if (Objects.equal(data.videoInformation, videoInformation)) { return; } //Make sure we don't set arbitrary html or invalid urls videoInformation.url = UrlUtils.encodeOnce(videoInformation.url); boolean autoSize = false; if (data.videoInformation.size.equals(Point2D.zero)) { autoSize = true; } data.videoInformation = videoInformation; setVideo(autoSize); } @Override public void setActive(boolean isFocused) { // do nothing. } @Override public VideoData getValue() { return this.data; } @Override public void setValue(VideoData data) { this.setValue(data, false); } @Override public void setElementData(ElementData data) { this.setValue((VideoData) data); } @Override public boolean canRotate() { // TODO: The only reason this is disabled is because Chrome doesn't properly rotate videos. // if chrome's bug is fixed, this should be enabled. return false; } @Override public ResizeMode getResizeMode() { return ResizeMode.BOTH; } @Override public void setViewMode(boolean isViewMode) { this.viewMode = isViewMode; this.refreshVisibility(); if (isViewMode) { this._editModeRegistrations.clear(); } else { this.registerEditModeHandlers(); } } private void refreshVisibility() { if ((this.viewMode) && (StringUtils.isWhitespaceOrNull(this.data.videoInformation.url))) { this.setVisible(false); } else { this.setVisible(true); } } private void setValue(VideoData data, boolean autoSize) { this.data = data; this.setVideo(autoSize); } private void setVideo(boolean autoSize) { this.refreshVisibility(); if (StringUtils.isWhitespaceOrNull(this.data.videoInformation.url)) { this.clearData(); return; } // Make sure we don't set arbitrary html or invalid urls String url = UrlUtils.encodeOnce(this.data.videoInformation.url); if (autoSize) { WidgetUtils.setWidgetSize(this, this.data.videoInformation.size); } // Only set the url if it changed, because there will be a refresh of the iframe if (autoSize || (false == UrlUtils.areEquivalent(url, videoFrame.getUrl()))) { _toolEvents.dispatchLoadStartedEvent(new LoadStartedEventArgs(false)); videoFrame.setUrl(url); } optionsLabel.setText(OPTIONS_LABEL_VIDEO_SET); super.removeStyleName(CanvasResources.INSTANCE.main().videoToolEmpty()); super.addStyleName(CanvasResources.INSTANCE.main().videoToolSet()); } private void clearData() { super.addStyleName(CanvasResources.INSTANCE.main().videoToolEmpty()); super.removeStyleName(CanvasResources.INSTANCE.main().videoToolSet()); this.videoFrame.setUrl(""); } @Override public void onResize() { // TODO Auto-generated method stub } @Override public IsWidget getToolbar() { // TODO Auto-generated method stub return null; } }