nikhilbchilwant / google-web-toolkit-incubator

Automatically exported from code.google.com/p/google-web-toolkit-incubator
1 stars 1 forks source link

A GWTCanvas Widget inside a Grid cell, in IE, incorrectly shifts content to the right if not LEFT_ALIGNed #275

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What version of gwt and gwt-incubator are you using?

1.5.3 & last incubator drop for 1.5.3

What OS and browser are you using?

IE7 (works wrong) vs FF2 (which works right) & Windows XP

Do you see this error in hosted mode, web mode, or both?

Web mode, IE7 (likely happens in all IE browsers, and hosted mode, though)

(If possible, please include a test case that shows the problem)

public class TestGChart46 extends Grid {
   final int CANVAS_SIZE = 100;
   final int CELL_SIZE = 4*CANVAS_SIZE;

   // To reproduce, add an instance of this class to root panel.
   // In FF2, you get the correct red, green, blue squares forming the
   // expected top-to-bottom, left-to-right,pattern. In IE7, only the
   // red square is where it should be, the green is shifted
   // too far right (and thus half clipped off) and the
   // blue is shifted right off the entire canvas, and thus
   // not visible at all.

   // fixed size canvas entirely occupied by a solid fill rectangle
   GWTCanvas makeCanvasRectangle(String color) {
    GWTCanvas result = new GWTCanvas();
    result.resize(CANVAS_SIZE, CANVAS_SIZE);
    result.setFillStyle(new Color(color));
    result.fillRect(0, 0, CANVAS_SIZE, CANVAS_SIZE);
    return result;
   }
   TestGChart46() {
      super(3,1);

      // the left aligned cell
      int iRow = 0;
      setWidget(iRow, 0, makeCanvasRectangle("red"));
      getCellFormatter().setAlignment(iRow, 0,
         HasHorizontalAlignment.ALIGN_LEFT,
         HasVerticalAlignment.ALIGN_MIDDLE);
      getCellFormatter().setWidth(iRow, 0, CELL_SIZE + "px");

     // the center aligned cell
      iRow++;
      setWidget(iRow, 0, makeCanvasRectangle("green"));
      getCellFormatter().setAlignment(iRow, 0,
         HasHorizontalAlignment.ALIGN_CENTER,
         HasVerticalAlignment.ALIGN_MIDDLE);
      getCellFormatter().setWidth(iRow, 0,CELL_SIZE + "px");

     // the right aligned cell
      iRow++;
      setWidget(iRow, 0, makeCanvasRectangle("blue"));
      getCellFormatter().setAlignment(iRow, 0,
         HasHorizontalAlignment.ALIGN_RIGHT,
         HasVerticalAlignment.ALIGN_MIDDLE);
      getCellFormatter().setWidth(iRow, 0, CELL_SIZE + "px");
   }
  }

Hopefully using the test case you have generously provided, what steps will 
reproduce the problem?

1. RootPanel.get().add(new TestGChart46()); (say, in the Hello World 
onModuleLoad method, for example)
2.Open the compiled GWT page in IE7 (works wrong)
3.Open the compiled GWT page in FF2 (works right)

What is the expected output? What do you see instead?

A series of red, green blue squares, one on each row, in the left,
center, and right positions on rows 1, 2, and 3 of the Grid (as shown in 
FF2)

RR
    GG
        BB

But, in IE, only the red square is shown properly. You see only the right 
half of the green square, and you don't see the blue square at all (if you 
zoom up in the browser, you can see at the far right, a tiny sliver of the 
blue square).

RR
     G
(empty row for blue)

In IE7, using Firebug Lite (great tool: http://getfirebug.com/lite.html) 
you can notice that it is as if the alignment applied to the table cell 
gets applied directly to the VML rectangle element placed on the canvas, 
but as if that graphical element were in a zero-sized div attached to the 
VML element's leftmost edge. The actual div that holds the canvas is 
positioned properly, somehow the stuff drawn inside of that div get 
incorrectly shifted to the right.

Workaround if you have one:

Add the canvas to an absolute panel sized to take up the entire grid cell. 
Then use the one alignment for that cell that works (ALIGN_LEFT) and 
explicitly position the canvas so that it gets moved so as to emulate 
centering or right alignment. This won't work unless you know the exact 
width of the Grid cell and of the canvas before the page is rendered, 
though.

Please provide any additional information below,  and thank you for taking 
the time and effort to report this issue, as good issue reports are 
critical for our quest to make GWT's new widgets and libraries shine.

First reported on the GWT forum here:

http://groups.google.com/group/Google-Web-
Toolkit/browse_thread/thread/5ca95553cab5f07d/350b157da9f18acf?
#350b157da9f18acf

I don't think there is anything like this going on with the vertical 
alignment, which I think works just fine.

Reading GWTCanvasImpIE6.java when this bug first hit me, I stumbled upon 
what appears to be an obvious typo ("width" instead of "height") in 
setCoordHeight ("width" rather than "height"). Doubt this typo is related 
to this bug, but you never know:

  public void setCoordHeight(Element elem, int height) {
    DOM.setElementAttribute(elem, "width", String.valueOf(height));
    clear(0, 0);
  }

I first found this bug while doing some prelim testing for the next version 
(2.5) of http://gchart.googlecode.com, which aims to improve continuous 
chart elements (pie slices, filled areas, connected lines) with GWTCanvas. 
The usage scenario is when users add another canvas-rendered chart Widget 
(via setAnnotationWidget) as an annotation or popup-annotation (for 
example, the pie chart that pops up when you hover over the the GChart live 
demo's bar chart is placed into such an annotation). Those annotations use 
a Grid and ALIGN_LEFT, ALIGN_CENTER, etc. to support compass point 
positioning of the annotations, so such popup charts get mangled badly in 
IE7 by this bug.

Right now, am planning to just javadoc the appropriate form of the 
workaround mentioned above for my product (using setShiftX to introduce the 
explicit shifts to emulate centering, etc.) but if this were fixed it would 
be much nicer.

John

Original issue reported on code.google.com by johncurt...@gmail.com on 7 May 2009 at 2:33

GoogleCodeExporter commented 9 years ago
I added this one-line comment that, if un-commented, makes
everything work correctly, even in IE:

// If you uncomment this line, IE7 works as it should:  
//    DOM.setElementAttribute(gwtCanvas.getElement(), "align", "left");

Here's the revised code-to-reproduce, including the above line:

public class TestGChart46 extends Grid {
   final int CANVAS_SIZE = 100;
   final int CELL_SIZE = 4*CANVAS_SIZE;

   /* To reproduce, add an instance of this class to root panel.
    * In FF, you get the red, green, blue squares forming the
    * expected top-to-bottom, left-to-right,pattern. In IE7, only the
    * red square is where it should be, the green is shifted
    * too far right (and thus half clipped off) and the
    * blue is shifted right off the entire canvas, and thus
    * not visible at all.
    *
    * See commented out line below for a workaround.
    * 
    */ 

   // fixed size canvas entirely occupied by a solid fill rectangle
   GWTCanvas makeCanvasRectangle(String color) {
    GWTCanvas gwtCanvas = new GWTCanvas();
    gwtCanvas.resize(CANVAS_SIZE, CANVAS_SIZE);
    gwtCanvas.setFillStyle(new Color(color));
    gwtCanvas.fillRect(0, 0, CANVAS_SIZE, CANVAS_SIZE);
// Workaround: if you uncomment the next line, IE7 works as it should  
//    DOM.setElementAttribute(gwtCanvas.getElement(), "align", "left");
    return gwtCanvas;
   }
   TestGChart46() {
      super(3,1);

      // the left aligned cell
      int iRow = 0;
      setWidget(iRow, 0, makeCanvasRectangle("red"));
      getCellFormatter().setAlignment(iRow, 0,
         HasHorizontalAlignment.ALIGN_LEFT,
         HasVerticalAlignment.ALIGN_MIDDLE);
      getCellFormatter().setWidth(iRow, 0, CELL_SIZE + "px");

     // the center aligned cell
      iRow++;
      setWidget(iRow, 0, makeCanvasRectangle("green"));
      getCellFormatter().setAlignment(iRow, 0,
         HasHorizontalAlignment.ALIGN_CENTER,
         HasVerticalAlignment.ALIGN_MIDDLE);
      getCellFormatter().setWidth(iRow, 0,CELL_SIZE + "px");

     // the right aligned cell
      iRow++;
      setWidget(iRow, 0, makeCanvasRectangle("blue"));
      getCellFormatter().setAlignment(iRow, 0,
         HasHorizontalAlignment.ALIGN_RIGHT,
         HasVerticalAlignment.ALIGN_MIDDLE);
      getCellFormatter().setWidth(iRow, 0, CELL_SIZE + "px");
   }
  }

With this workaround I finally have an explanation that kind of
makes sense for this IE behavior: the alignment property of the
table cell gets inherited by the div that GWTCanvas uses to hold the
VML element, and then that alignment gets inherited by the VML element(s)
within that div. I can't imagine a scenario where having the VML
inherit the alignment would be helpful (it's very un-vector-
graphics-like) but I guess, if shapes are elements, it kind of
makes sense from the VML perspective.

The behavior of this test implies that, for horizontal alignment
purposes, the VML element is horizonally positioned by it's left edge,
as if it had zero width (sounds strange, until you
realize that it can be kind of hard to compute the actual width
of a complex VML element, and so this may have just been the easiest way for
the VML guys code it). 

If you buy the above argument it means that other inherited
attributes/properties might "bleed through" the div into the VML
elements, wreaking unknown havoc for the innocent GWTCanvas user.
Thus maybe worthwhile to come up with a list of other likely bad
actors and, if they make the VML shift in incorrect ways, etc.,
to short-circuit any similar problems via appropriate properties
added to the parent div that holds the VML. Maybe there is a
single VML switch that says "enough already, just ignore the
parent alignment, etc. and position things like a vector-graphics
package would"?

Big picture: Even though they are elements and apparently subject
to at least one inherited attributes/properties, they must be
positioned as they would have had they been instead part of a
simple, pixel-based, vector graphics system, regardless of the
properties/attributes in the parent container. Some insulation
required.

Original comment by johncurt...@gmail.com on 8 May 2009 at 3:09

GoogleCodeExporter commented 9 years ago

Original comment by jaime...@google.com on 5 Aug 2009 at 12:05