com.google.appinventor.client.explorer.SourceStructureExplorer.java Source code

Java tutorial

Introduction

Here is the source code for com.google.appinventor.client.explorer.SourceStructureExplorer.java

Source

// -*- mode: java; c-basic-offset: 2; -*-
// Copyright 2009-2011 Google, All Rights reserved
// Copyright 2011-2012 MIT, All rights reserved
// Released under the Apache License, Version 2.0
// http://www.apache.org/licenses/LICENSE-2.0

package com.google.appinventor.client.explorer;

import com.google.appinventor.client.Ode;
import com.google.appinventor.client.output.OdeLog;
import com.google.appinventor.client.widgets.TextButton;
import com.google.gwt.event.dom.client.*;
import com.google.gwt.event.logical.shared.*;
import com.google.gwt.user.client.ui.*;

import java.util.Iterator;

import static com.google.appinventor.client.Ode.MESSAGES;

/**
 * This explorer is used to outline the structure of a source file. Note that
 * this explorer is shared by all it's clients. That means that clients (most
 * likely editors) need to update its content upon activation.
 *
 * @author lizlooney@google.com (Liz Looney)
 */
public class SourceStructureExplorer extends Composite {
    // UI elements
    private final Tree tree;
    private final TextButton renameButton;
    private final TextButton deleteButton;

    /**
     * Creates a new source structure explorer.
     */
    public SourceStructureExplorer() {
        // Initialize UI elements
        tree = new Tree(Ode.getImageBundle());
        tree.setAnimationEnabled(true);
        tree.addCloseHandler(new CloseHandler<TreeItem>() {
            @Override
            public void onClose(CloseEvent<TreeItem> event) {
                TreeItem treeItem = event.getTarget();
                if (treeItem != null) {
                    Object userObject = treeItem.getUserObject();
                    if (userObject instanceof SourceStructureExplorerItem) {
                        SourceStructureExplorerItem item = (SourceStructureExplorerItem) userObject;
                        item.onStateChange(false);
                    }
                }
            }
        });
        tree.addOpenHandler(new OpenHandler<TreeItem>() {
            @Override
            public void onOpen(OpenEvent<TreeItem> event) {
                TreeItem treeItem = event.getTarget();
                if (treeItem != null) {
                    Object userObject = treeItem.getUserObject();
                    if (userObject instanceof SourceStructureExplorerItem) {
                        SourceStructureExplorerItem item = (SourceStructureExplorerItem) userObject;
                        item.onStateChange(true);
                    }
                }
            }
        });
        tree.addSelectionHandler(new SelectionHandler<TreeItem>() {
            @Override
            public void onSelection(SelectionEvent<TreeItem> event) {
                TreeItem treeItem = event.getSelectedItem();
                if (treeItem != null) {
                    Object userObject = treeItem.getUserObject();
                    if (userObject instanceof SourceStructureExplorerItem) {
                        SourceStructureExplorerItem item = (SourceStructureExplorerItem) userObject;
                        enableButtons(item);
                        //showBlocks(item);
                        item.onSelected();
                    } else {
                        disableButtons();
                        //hideComponent();
                    }
                } else {
                    disableButtons();
                }
            }
        });
        tree.addKeyDownHandler(new KeyDownHandler() {
            @Override
            public void onKeyDown(KeyDownEvent event) {
                int keyCode = event.getNativeKeyCode();
                if (keyCode == KeyCodes.KEY_DELETE || keyCode == KeyCodes.KEY_BACKSPACE) {
                    event.preventDefault();
                    deleteItemFromTree();
                }
            }
        });

        // Put a ScrollPanel around the tree.
        ScrollPanel scrollPanel = new ScrollPanel(tree);
        scrollPanel.setWidth("200px"); // wide enough to avoid a horizontal scrollbar most of the time
        scrollPanel.setHeight("480px"); // approximately the same height as the viewer

        HorizontalPanel buttonPanel = new HorizontalPanel();
        buttonPanel.setStyleName("ode-PanelButtons");
        buttonPanel.setSpacing(4);

        renameButton = new TextButton(MESSAGES.renameButton());
        renameButton.setEnabled(false);
        renameButton.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                TreeItem treeItem = tree.getSelectedItem();
                if (treeItem != null) {
                    Object userObject = treeItem.getUserObject();
                    if (userObject instanceof SourceStructureExplorerItem) {
                        SourceStructureExplorerItem item = (SourceStructureExplorerItem) userObject;
                        item.rename();
                    }
                }
            }
        });
        buttonPanel.add(renameButton);
        buttonPanel.setCellHorizontalAlignment(renameButton, HorizontalPanel.ALIGN_RIGHT);

        deleteButton = new TextButton(MESSAGES.deleteButton());
        deleteButton.setEnabled(false);
        deleteButton.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                deleteItemFromTree();
            }
        });
        buttonPanel.add(deleteButton);
        buttonPanel.setCellHorizontalAlignment(deleteButton, HorizontalPanel.ALIGN_LEFT);

        VerticalPanel panel = new VerticalPanel();
        panel.add(scrollPanel);
        panel.add(new Label());
        panel.add(buttonPanel);
        panel.setCellHorizontalAlignment(buttonPanel, HorizontalPanel.ALIGN_CENTER);
        initWidget(panel);
    }

    private void deleteItemFromTree() {
        TreeItem treeItem = tree.getSelectedItem();
        if (treeItem != null) {
            Object userObject = treeItem.getUserObject();
            if (userObject instanceof SourceStructureExplorerItem) {
                SourceStructureExplorerItem item = (SourceStructureExplorerItem) userObject;
                item.delete();
            }
        }
    }

    private void enableButtons(SourceStructureExplorerItem item) {
        renameButton.setEnabled(item.canRename());
        deleteButton.setEnabled(item.canDelete());
    }

    private void disableButtons() {
        renameButton.setEnabled(false);
        deleteButton.setEnabled(false);
    }

    /* move this logic to declarations of SourceStructureExplorerItem subtypes
    private void showBlocks(SourceStructureExplorerItem item) {
      // are we showing the blocks editor?
      if (Ode.getInstance().getCurrentFileEditor() instanceof YaBlocksEditor) {
        YaBlocksEditor editor = 
      (YaBlocksEditor) Ode.getInstance().getCurrentFileEditor();
        OdeLog.log("Showing item " + item.getItemName());
        if (item.isComponent()) {
    editor.showComponentBlocks(item.getItemName());
        } else {
    editor.showBuiltinBlocks(item.getItemName());
        }
      }
    }
        
    private void hideComponent() {
      if (Ode.getInstance().getCurrentFileEditor() instanceof YaBlocksEditor) {
        YaBlocksEditor editor =
      (YaBlocksEditor) Ode.getInstance().getCurrentFileEditor();
        OdeLog.log("Hiding selected item");
        editor.hideComponentBlocks();
      }  
    }
     */

    /**
     * Clears the tree.
     */
    public void clearTree() {
        tree.clear();
        disableButtons();
    }

    /**
     * Updates the tree
     *
     * @param root the new root TreeItem
     * @param itemToSelect item to select, or null for no selected item
     */
    public void updateTree(TreeItem root, SourceStructureExplorerItem itemToSelect) {
        TreeItem items[] = new TreeItem[1];
        items[0] = root;
        updateTree(items, itemToSelect);
    }

    /**
     * Updates the tree
     *
     * @param roots An array of root items (all top level)
     * @param itemToSelect item to select, or null for no selected item
     */
    public void updateTree(TreeItem[] roots, SourceStructureExplorerItem itemToSelect) {
        tree.clear();
        for (TreeItem root : roots) {
            tree.addItem(root);
        }
        if (itemToSelect != null) {
            selectItem(itemToSelect, true);
        } else {
            disableButtons();
        }
    }

    /**
     * Select or unselect an item in the tree
     *
     * @param item to select or unselect
     * @param select true to select, false to unselect
     */
    private void selectItem(SourceStructureExplorerItem item, boolean select) {
        Iterator<TreeItem> iter = tree.treeItemIterator();
        while (iter.hasNext()) {
            TreeItem treeItem = iter.next();
            if (item.equals(treeItem.getUserObject())) {
                // NOTE(lizlooney) - It turns out that calling TreeItem.setSelected(true) doesn't actually
                // select the item in the tree. It looks selected, but Tree.getSelectedItem() will return
                // null. Instead, we have to call Tree.setSelectedItem.
                if (select) {
                    tree.setSelectedItem(treeItem, false); // false means don't trigger a SelectionEvent
                    enableButtons(item);
                    //showBlocks(item);
                } else {
                    tree.setSelectedItem(null, false); // false means don't trigger a SelectionEvent
                    disableButtons();
                    //hideComponent();
                }
                break;
            }
        }
    }

    /**
     * Select an item in the tree
     *
     * @param item item to select
     */
    public void selectItem(SourceStructureExplorerItem item) {
        selectItem(item, true);
    }

    /**
     * Select an item in the tree
     *
     * @param item item to unselect
     */
    public void unselectItem(SourceStructureExplorerItem item) {
        selectItem(item, false);
    }
}