Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    How to get tiles to auto-fit to contents

    I have a TileGrid where I am filling each tile with a snippet of html using getTileHTML(). I can set the tiles to a fixed size, but I'd rather they size themselves to fit the html contents which can vary somewhat. If I don't set a tile size they are all sized at 50x50. How can I get them to auto-size based on the contents of each tile?

    #2
    Any tips on how to accomplish this?

    Comment


      #3
      Your use case seems much closer to a TileLayout than a TileGrid. In a TileLayout, you have complete control over how the tiles are created, so you can setOverflow(visible) to cause autosizing.

      Comment


        #4
        But I lose the data-binding features of TileGrid if I use TileLayout instead. Is there a way to get both variable sized tiles that automatically flow and grid like data binding?

        Comment


          #5
          Not exactly. Most of the features of TileGrid are oriented around working with potentially large datasets (where autosizing and varying number of tiles like you want would not be possible).

          By making a direct call to DataSource.fetchData() to get data and creating a DetailViewer form each tile, binding the DetailViewer to the DataSource you were using for the TileGrid, you've basically re-introduced the core databinding features of TileGrid which actually apply to your use case.

          Comment


            #6
            I'm finally getting back to this after two years! I've changed from using TileGrid to a TileLayout, doing a fetch from the datasource and then calling addTile() to add each one. Here is the code.
            Code:
            TileLayout itemImageLayout = new TileLayout();
            itemImageLayout.setShowEdges(false);
            itemImageLayout.setCanDragResize(true);
            itemImageLayout.setShowResizeBar(true);
            itemImageLayout.setHeight100();
            itemImageLayout.setWidth100();
            itemImageLayout.setOverflow(Overflow.VISIBLE);
            
            itemSummaryImagesDS.fetchData(request.getCriteria(), new DSCallback() {
            	
            	@Override
            	public void execute(DSResponse response, Object rawData, DSRequest request) {
            		itemImageLayout.clear();
            		for (Record record : response.getData()) {
            			itemImageLayout.addTile(getImageTile(record));
            		}
            		itemImageLayout.markForRedraw();
            	}
            });
            
            private VLayout getImageTile(Record record) {
            	Img img = new Img(record.getAttribute("ImageLink"));
            	img.setImageType(ImageStyle.NORMAL);
            	Label description = new Label(record.getAttribute("Description"));
            	description.setWrap(false);
            	description.setHeight(10);
            	Label priceRange = new Label();  
            	priceRange.setWrap(false);
            	priceRange.setHeight(10);
            	Double fromPrice = record.getAttributeAsDouble("FromPrice");
            	Double toPrice = record.getAttributeAsDouble("ToPrice");
            	if (fromPrice.equals(toPrice))
            		priceRange.setContents(IPGui.homeCurrencyFormat(fromPrice));
            	else
            		priceRange.setContents(IPGui.homeCurrencyFormat(fromPrice) +
            		" - " + IPGui.homeCurrencyFormat(toPrice));  
            	VLayout imageLayout = new VLayout();
            	imageLayout.setMembers(img, description, priceRange);
            	imageLayout.setHeight100();
            	imageLayout.setWidth100();
            	imageLayout.setOverflow(Overflow.VISIBLE);
            	return imageLayout;
            }
            Two problems.

            1) Nothing shows up in the TileLayout until I nudge the resize bar to force it to redraw. That's why I added the itemImageLayout.markForRedraw(), which had no effect.

            2) After the layout does draw, the image is cropped at 50x100 even though I've set ImageStyle.NORMAL.

            What am I doing wrong?

            Comment


              #7
              The first problem is that you're calling setWidth/Height100 on the VLayout you're returning to the TileLayout. That would normally mean the VLayout should fill it's container completely, which is obviously not what you want. Set width and height to a minimum size instead.

              Second problem is that this system isn't going to auto-size to images that are loaded asynchronously. You'll need to either ensure the images are loaded in advance, or get the image dimensions via GWT's built-in Image class, and apply those to the Img widget before providing it to the TileLayout.

              Comment


                #8
                I don't understand what you mean by "ensure the images are loaded in advance". How would I do that?

                Same for using GWT Image widget. Would I use that instead of Img? Wouldn't it also need to wait until the image is loaded to know what size it is?

                Also - can you explain why the TileLayout would be blank until the container size is changed to force a redraw?
                Last edited by jay.l.fisher; 12 Dec 2011, 19:12.

                Comment


                  #9
                  You would ensure the images are loaded in advance through standard image caching techiques, which basically means offscreen <img> tags (possibly done for you by some API, such as the FileLoader.cacheFiles() API in SmartClient).

                  You want to the GWT Image API just to discover dimensions (not render). GWT knows the dimensions of files in war/ because it can check them at compile time.

                  If the images are entirely dynamic, you need a caching approach like the above instead.

                  Comment


                    #10
                    The images are dynamic and they must be loaded on demand as there are many thousands of images and only one or a few will be requested at any one time. Is there some way to resize the Img widget once the image is actually loaded?

                    Comment


                      #11
                      Yes, the normal way: resizeTo(). However, you'll still want to use GWT's Image API to get dimensions - they should be available once the image is loaded.

                      Comment

                      Working...
                      X