package com.yoursway.experiments.birdseye; import static com.google.common.collect.Lists.newArrayListWithCapacity; import static com.google.common.collect.Maps.newHashMap; import static com.yoursway.swt.additions.YsSwtUtils.applyMiniSize; import static com.yoursway.utils.YsCollections.addIfNotNull; import static com.yoursway.utils.YsPathUtils.extension; import static com.yoursway.utils.YsStrings.emptyToNull; import static java.util.Collections.emptyList; import static org.eclipse.jface.layout.GridDataFactory.swtDefaults; import static org.eclipse.jface.layout.GridLayoutFactory.fillDefaults; import java.io.File; import java.util.Collection; import java.util.Map; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StackLayout; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.ui.part.ViewPart; import com.yoursway.experiments.birdseye.model.Container; import com.yoursway.experiments.birdseye.model.Leaf; import com.yoursway.experiments.birdseye.model.Node; import com.yoursway.swt.animations.flip.Flipper; import com.yoursway.swt.animations.flip.FlipperListener; import com.yoursway.swt.animations.flip.StackLayoutFlipperListener; import com.yoursway.utils.YsFileUtils; public class BirdsEyeView extends ViewPart implements BirdsEyeListener { private BirdsEyeComposite birdsEyeDisplay; private Label selectionDescription; private Composite stack; private Composite settingsComposite; private Flipper flipper; private Composite birdsEyeContainer; private static class Factory { private final Display display; private Color defaultColor; private Map<String, Color> extToColor = newHashMap(); public Factory(Display display) { this.display = display; defaultColor = display.getSystemColor(SWT.COLOR_CYAN); } public void associate(String ext, int color) { associate(ext, display.getSystemColor(color)); } public void associate(String ext, Color color) { if (ext == null) throw new NullPointerException("ext is null"); if (color == null) throw new NullPointerException("color is null"); extToColor.put(ext.toLowerCase(), color); } public Node createLeaf(File file, String path) { return new Leaf(Math.log(1 + file.length()), colorFor(file), path); } private Color colorFor(File file) { String ext = emptyToNull(extension(file)); Color color = (ext == null ? null : extToColor.get(ext.toLowerCase())); if (color == null) return defaultColor; else return color; } } @Override public void createPartControl(Composite parent) { parent.setLayout(fillDefaults().margins(0, 0).spacing(0, 0).create()); stack = new Composite(parent, SWT.NONE); stack.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); stack.setLayout(new StackLayout()); createBirdsEyeComposite(stack); createSettingsComposite(stack); flipper = new Flipper(birdsEyeContainer, settingsComposite, 600); new StackLayoutFlipperListener(flipper, stack); } private void createBirdsEyeComposite(Composite parent) { birdsEyeContainer = new Composite(parent, SWT.NONE); birdsEyeContainer.setLayout(fillDefaults().margins(0, 0).spacing(0, 0).create()); birdsEyeDisplay = new BirdsEyeComposite(birdsEyeContainer, SWT.NONE); birdsEyeDisplay.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); selectionDescription = new Label(birdsEyeContainer, SWT.NONE); selectionDescription.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); Factory factory = new Factory(parent.getDisplay()); factory.associate("rb", SWT.COLOR_RED); factory.associate("rhtml", SWT.COLOR_MAGENTA); factory.associate("rjs", SWT.COLOR_DARK_MAGENTA); factory.associate("yml", SWT.COLOR_BLUE); factory.associate("txt", SWT.COLOR_BLUE); factory.associate("css", SWT.COLOR_DARK_CYAN); factory.associate("js", SWT.COLOR_DARK_BLUE); factory.associate("log", SWT.COLOR_YELLOW); factory.associate("tmp", SWT.COLOR_YELLOW); factory.associate("gif", SWT.COLOR_GREEN); factory.associate("png", SWT.COLOR_GREEN); factory.associate("jpg", SWT.COLOR_GREEN); File rootFile = new File("/Users/andreyvit/Projects/ujudge/ujudge"); Node root = collect(rootFile, factory, ""); birdsEyeDisplay.display(root); birdsEyeDisplay.addListener(this); applyMiniSize(parent); birdsEyeDisplay.addListener(SWT.MouseDown, new Listener() { public void handleEvent(Event event) { flipper.flip(); } }); } private void createSettingsComposite(Composite parent) { settingsComposite = new Composite(parent, SWT.NONE); settingsComposite.setLayout(new GridLayout(1, false)); // addBorder(settingsComposite); applyMiniSize(settingsComposite); Label label = new Label(settingsComposite, SWT.NONE); label.setText("Working sets to show:"); new Button(settingsComposite, SWT.CHECK).setText("YourSway IDE"); new Button(settingsComposite, SWT.CHECK).setText("SADR"); new Button(settingsComposite, SWT.CHECK).setText("EskoArtwork"); Button settingsButton = new Button(settingsComposite, SWT.PUSH); settingsButton.setText("Done"); settingsButton.setLayoutData(swtDefaults().indent(0, 8).create()); settingsButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { flipper.flip(); } }); for (Control control : settingsComposite.getChildren()) control.setFont(settingsComposite.getFont()); } private void addBorder(final Composite composite) { composite.addPaintListener(new PaintListener() { public void paintControl(PaintEvent e) { GC gc = e.gc; Rectangle clientArea = composite.getClientArea(); gc.setForeground(e.display.getSystemColor(SWT.COLOR_BLACK)); gc.drawRectangle(clientArea.x, clientArea.y, clientArea.width - 1, clientArea.height - 1); // gc.drawRectangle(clientArea.x+1, clientArea.y+1, clientArea.width - 3, clientArea.height - 3); } }); } private Node collect(File entry, Factory factory, String prefix) { if (entry.isFile()) return factory.createLeaf(entry, prefix + entry.getName()); String name = entry.getName(); if (YsFileUtils.isBogusFile(name)) return null; File[] files = entry.listFiles(); Collection<Node> children; if (files == null) children = emptyList(); else { children = newArrayListWithCapacity(files.length); String path = prefix + entry.getName() + "/"; for (File child : files) addIfNotNull(children, collect(child, factory, path)); } if (children.isEmpty()) return null; else return new Container(children); } @Override public void setFocus() { birdsEyeDisplay.setFocus(); } public void birdsEyeHovered(Leaf node, Event event) { if (node == null) selectionDescription.setText(""); else selectionDescription.setText(node.label()); } }