package com.baselet.gwt.client.view;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.vectomatic.file.FileUploadExt;
import com.baselet.control.config.SharedConfig;
import com.baselet.gwt.client.base.Notification;
import com.baselet.gwt.client.element.BrowserStorage;
import com.baselet.gwt.client.element.DiagramXmlParser;
import com.baselet.gwt.client.view.panel.wrapper.AutoResizeScrollDropPanel;
import com.baselet.gwt.client.view.panel.wrapper.FileOpenHandler;
import com.baselet.gwt.client.view.utils.DropboxIntegration;
import com.baselet.gwt.client.view.widgets.DownloadPopupPanel;
import com.baselet.gwt.client.view.widgets.FilenameHolder;
import com.baselet.gwt.client.view.widgets.SaveDialogBox;
import com.baselet.gwt.client.view.widgets.SaveDialogBox.Callback;
import com.baselet.gwt.client.view.widgets.ShortcutDialogBox;
import com.baselet.gwt.client.view.widgets.propertiespanel.PropertiesTextArea;
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.core.client.ScriptInjector;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.DomEvent;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.dom.client.MouseWheelEvent;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.SimpleLayoutPanel;
import com.google.gwt.user.client.ui.SplitLayoutPanel;
import com.google.gwt.user.client.ui.Widget;
public class MainView extends Composite {
private static MainViewUiBinder uiBinder = GWT.create(MainViewUiBinder.class);
interface MainViewUiBinder extends UiBinder<Widget, MainView> {}
interface MyStyle extends CssResource {
String menuItem();
}
@UiField
MyStyle style;
@UiField
FocusPanel mainPanel;
@UiField(provided = true)
SplitLayoutPanel diagramPaletteSplitter = new SplitLayoutPanel(4) {
@Override
public void onResize() {
super.onResize();
updateNotificationPosition();
}
};
@UiField
FlowPanel menuPanel;
@UiField
FlowPanel restoreMenuPanel;
@UiField(provided = true)
SplitLayoutPanel palettePropertiesSplitter = new SplitLayoutPanel() {
@Override
public void onResize() {
diagramPanel.redraw();
palettePanel.redraw();
}
};
@UiField
DockLayoutPanel paletteChooserCanvasSplitter;
@UiField
SimpleLayoutPanel diagramPanelWrapper;
@UiField
ListBox paletteChooser;
@UiField
PropertiesTextArea propertiesPanel;
@UiField
SimpleLayoutPanel palettePanelWrapper;
private final DrawPanel diagramPanel;
private final AutoResizeScrollDropPanel diagramScrollPanel;
private final DrawPanel palettePanel;
private final AutoResizeScrollDropPanel paletteScrollPanel;
private final FileUploadExt hiddenUploadButton = new FileUploadExt();
private final FileOpenHandler handler;
private final Logger log = LoggerFactory.getLogger(MainView.class);
private final DropboxIntegration dropboxInt;
private final FilenameHolder lastExportFilename = new FilenameHolder("");
private final ScheduledCommand saveCommand = new ScheduledCommand() {
private final SaveDialogBox saveDialogBox = new SaveDialogBox(new Callback() {
@Override
public void callback(final String chosenName) {
boolean itemIsNewlyAdded = BrowserStorage.getSavedDiagram(chosenName) == null;
BrowserStorage.addSavedDiagram(chosenName, DiagramXmlParser.diagramToXml(diagramPanel.getDiagram()));
if (itemIsNewlyAdded) {
addRestoreMenuItem(chosenName);
}
Notification.showInfo("Diagram saved as: " + chosenName);
}
});
@Override
public void execute() {
saveDialogBox.clearAndCenter();
}
};
private final ScheduledCommand exportToDropbox = new ScheduledCommand() {
private final SaveDialogBox saveDialogBox = new SaveDialogBox(new Callback() {
@Override
public void callback(final String chosenName) {
String uxfUrl = "data:text/xml;charset=utf-8," + DiagramXmlParser.diagramToXml(true, false, diagramPanel.getDiagram());
dropboxInt.openDropboxExport(uxfUrl, chosenName);
}
}, "Export to Dropbox");
@Override
public void execute() {
saveDialogBox.clearAndCenter();
}
};
public ScheduledCommand getSaveCommand() {
return saveCommand;
}
public MainView() {
initWidget(uiBinder.createAndBindUi(this));
diagramPaletteSplitter.setWidgetToggleDisplayAllowed(palettePropertiesSplitter, true);
diagramPaletteSplitter.setWidgetSnapClosedSize(palettePropertiesSplitter, 100);
diagramPaletteSplitter.setWidgetMinSize(palettePropertiesSplitter, 200);
diagramPaletteSplitter.setWidgetToggleDisplayAllowed(menuPanel, true);
diagramPaletteSplitter.setWidgetSnapClosedSize(menuPanel, 25);
diagramPaletteSplitter.setWidgetMinSize(menuPanel, 50);
palettePropertiesSplitter.setWidgetToggleDisplayAllowed(paletteChooserCanvasSplitter, true);
diagramPanel = new DrawPanelDiagram(this, propertiesPanel);
palettePanel = new DrawPanelPalette(this, propertiesPanel, paletteChooser);
diagramPanel.setOtherDrawFocusPanel(palettePanel);
palettePanel.setOtherDrawFocusPanel(diagramPanel);
diagramScrollPanel = new AutoResizeScrollDropPanel(diagramPanel);
paletteScrollPanel = new AutoResizeScrollDropPanel(palettePanel);
updateNotificationPosition();
for (String diagramName : BrowserStorage.getSavedDiagramKeys()) {
addRestoreMenuItem(diagramName);
}
log.trace("Main View initialized");
handler = new FileOpenHandler(diagramPanel);
diagramPanelWrapper.add(diagramScrollPanel);
palettePanelWrapper.add(paletteScrollPanel);
RootLayoutPanel.get().add(hiddenUploadButton);
hiddenUploadButton.setVisible(false);
hiddenUploadButton.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
handler.processFiles(hiddenUploadButton.getFiles());
}
});
EventHandlingUtils.addEventHandler(mainPanel, diagramPanel, palettePanel);
mainPanel.addFocusHandler(new FocusHandler() {
@Override
public void onFocus(FocusEvent event) {
SharedConfig.getInstance().setStickingEnabled(true); // shift button may have stopped being pressed, therefore assume sticking is enabled again
}
});
// Add Dropbox dropins.js
ScriptInjector.fromUrl("https://www.dropbox.com/static/api/2/dropins.js?data-app-key='3mmyizdvtldctng'")
.setWindow(ScriptInjector.TOP_WINDOW)
.inject();
dropboxInt = new DropboxIntegration(diagramPanel);
dropboxInt.exposeDropboxImportJSCallback(dropboxInt);
dropboxInt.exposeDropboxShowNotification(dropboxInt);
}
private void addRestoreMenuItem(final String chosenName) {
final HorizontalPanel hp = new HorizontalPanel();
Label label = new Label(chosenName);
label.setTitle("open diagram " + chosenName);
label.addStyleName(style.menuItem());
label.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
diagramPanel.setDiagram(DiagramXmlParser.xmlToDiagram(BrowserStorage.getSavedDiagram(chosenName)));
Notification.showInfo("Diagram opened: " + chosenName);
}
});
Image img = new Image("data:image/gif;base64,R0lGODlhCgAKAJEAAAAAAP////8AAP///yH5BAEAAAMALAAAAAAKAAoAAAIUnI8jgmvLlHtwnpqkpZh72UTZUQAAOw==");
img.setTitle("delete diagram " + chosenName);
img.addStyleName(style.menuItem());
img.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
if (Window.confirm("Delete saved diagram " + chosenName)) {
BrowserStorage.removeSavedDiagram(chosenName);
restoreMenuPanel.remove(hp);
Notification.showInfo("Deleted diagram: " + chosenName);
}
}
});
hp.add(img);
hp.add(label);
restoreMenuPanel.add(hp);
}
@UiHandler("importMenuItem")
void onImportMenuItemClick(ClickEvent event) {
hiddenUploadButton.click();
}
@UiHandler("exportMenuItem")
void onExportMenuItemClick(ClickEvent event) {
String uxfUrl = "data:text/xml;charset=utf-8," + DiagramXmlParser.diagramToXml(true, true, diagramPanel.getDiagram());
log.info("Exporting: " + uxfUrl);
String pngUrl = CanvasUtils.createPngCanvasDataUrl(diagramPanel.getDiagram());
new DownloadPopupPanel(uxfUrl, pngUrl, lastExportFilename).center();
}
@UiHandler("importDropboxMenuItem")
void onImportDropboxMenuItemClick(ClickEvent event) {
dropboxInt.openDropboxImport();
}
@UiHandler("exportDropboxMenuItem")
void onExportDropboxMenuItemClick(ClickEvent event) {
exportToDropbox.execute();
}
@UiHandler("saveMenuItem")
void onSaveMenuItemClick(ClickEvent event) {
saveCommand.execute();
}
@UiHandler("helpMenuItem")
void onHelpMenuItemClick(ClickEvent event) {
ShortcutDialogBox.getInstance().center();
}
@UiHandler("paletteChooser")
void onPaletteChooserMouseWheel(MouseWheelEvent event) {
// determine new index based on scroll direction
int newIndex = paletteChooser.getSelectedIndex();
if (event.getDeltaY() < 0) {
newIndex--;
}
else {
newIndex++;
}
// set new index (if it's valid) and trigger change event (is not automatically triggered)
if (newIndex >= 0 && newIndex < paletteChooser.getItemCount()) {
paletteChooser.setSelectedIndex(newIndex);
DomEvent.fireNativeEvent(Document.get().createChangeEvent(), paletteChooser);
}
}
private void updateNotificationPosition() {
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
@Override
public void execute() {
RootPanel.get("featurewarning").getElement().getStyle().setMarginLeft(menuPanel.getOffsetWidth(), Unit.PX);
}
});
}
}