Search code examples
gwttreeiconsoverlaygxt

Overlay images in gxt Tree Panel


I'm developing a gxt application that provides a view for svn-like versioning: A TreePanel that displays a file system structure with files and folders having different states (new, modified, deleted, etc.).

I want to display a small overlay icon on each of the items to reflect its state. What I could do, is to create an icon for each state, but I don't want to do that, because I would end up in creating a large bundle of redundant images.

What would be the best way to implement overlay icon capabilities in trees or grids?


Solution

  • After checking the dom of the tree structure, I figured out that a tree icon is displayed using the background-url css attribute. To ensure the image is being displayed with correct size, the src attribute of the element is filled with a placeholder image url.

    The trick is, to replace the placeholder image with the overlay icon, since it is displayed above the actual image.

    To accomplish this, I extended ClippedImagePrototype to inject the url of the overlay image:

    public class OverlayImagePrototype extends ClippedImagePrototype {
      protected String overlayImageUrl = null;
    
      public static AbstractImagePrototype create(ImageResource resource, String overlayUrl) {
        return new OverlayImagePrototype(resource.getSafeUri(),
                     resource.getLeft(), resource.getTop(), resource.getWidth(),
                     resource.getHeight(), overlayUrl);
      }
    
      private OverlayImagePrototype(SafeUri url, int left, int top, int width,
                                    int height, String overlayUrl) {
        super(url, left, top, width, height);
        this.overlayImageUrl = overlayUrl;
      }
    
      public ImagePrototypeElement createElement() {
        ImagePrototypeElement imgEl = super.createElement();
        if (overlayImageUrl != null) {
          imgEl.setAttribute("src", overlayImageUrl);
        }
        return imgEl;
      }
    }
    

    This is how I use OverlayImagePrototype in the IconProvider implementation:

    tree.setIconProvider(new ModelIconProvider<ModelData>() {
      public AbstractImagePrototype getIcon(ModelData model) {
        return OverlayImagePrototype.create(model.get("icon"), model.get("overlayIconUrl"));
      }
    });