Project

General

Profile

Bug #2772

Bug #2677: fix drawing and functional differences between P2J GUI and 4GL GUI

the ask-gui.p testcase doesn't show the message update dialog.

Added by Sergey Ivanovskiy over 8 years ago. Updated over 7 years ago.

Status:
Closed
Priority:
Normal
Start date:
10/21/2015
Due date:
% Done:

100%

billable:
No
vendor_id:
GCD
case_num:

MessageUpdate.png (25.4 KB) Sergey Ivanovskiy, 10/21/2015 11:51 AM

dialog_title.png (55.6 KB) Sergey Ivanovskiy, 10/22/2015 06:55 AM

resize_issue_2.txt Magnifier (1.58 KB) Sergey Ivanovskiy, 10/22/2015 11:40 AM

History

#1 Updated by Sergey Ivanovskiy over 8 years ago

The JS web client doesn't display "Try another program?: yes/No" dialog and the browser console produces

17:43:56.911 Window ids must be non-positive integers.1 p2j.screen.js:1840:7
me.error() p2j.screen.js:1840
me.createWindow() p2j.screen.js:1524
me.createChildWindow() p2j.screen.js:1574
me.init/ws.onmessage() p2j.socket.js:440

#2 Updated by Greg Shah over 8 years ago

Please note that on the Java side this seems to be related to the use of Window.tinyInput(). I think this is the same cause of the problem in message-update6.p.

#3 Updated by Sergey Ivanovskiy over 8 years ago

Please note that on the Java side this seems to be related to the use of Window.tinyInput(). I think this is the same cause of the problem in message-update6.p.

The JS client expects the child window id is a positive number. But the ModalWindow can have a unique id from the negative range of the signed integer type.

#4 Updated by Sergey Ivanovskiy over 8 years ago

If we permit negative numbers for window ids, then the message update dialog appears and looks like in the attached screen with a broken layout.
Constantin, do you have any objections to accept negative window ids? It needs only to change

   function isValidWindowId(wid)
   {
      return (typeof wid === 'number') /*&& (wid % 1 === 0) && wid > 0*/;
   };

#5 Updated by Constantin Asofiei over 8 years ago

Sergey Ivanovskiy wrote:

If we permit negative numbers for window ids, then the message update dialog appears and looks like in the attached screen with a broken layout.
Constantin, do you have any objections to accept negative window ids? It needs only to change
[...]

I'm OK with the change. Also, update the javadoc for the function, too.

#6 Updated by Sergey Ivanovskiy over 8 years ago

Checked that the icon if it would be defined for ModalWindow

   public ModalWindow(String title)
   {
      super(title);

      id = WidgetId.nextID();
      gd = (GuiDriver<?,?>) OutputManager.getDriver();

      // the modal window is parented to the active top-level window, not the focus owner
      setOwner(WindowManager.getActiveTopLevelWindow());

      setLayout(new WindowLayout());

      titleBar = new WindowTitleBar(WidgetId.nextID(),
                                    true, // tested the icon coordinates
                                    new CaptionButtonType[] {CaptionButtonType.CLOSE},
                                    title);
...................
}

were located correctly within ModalWindow dialog, but the dialog title and its background displayed lower. The web log probably had correct coordinates to draw the title. Thus WindowTitleBar of ModalWindow works properly for icon but not for the title.
PaintPrimitives.CLIP  3; x = 0; y = 0; width = 17; height = 17
PaintPrimitives.DRAW_IMAGE  x = 0; y = 0; width = 16; height = 16
PaintPrimitives.NO_CLIP  2
PaintPrimitives.TRANSLATE_POP  1; x = -2; y = -1
PaintPrimitives.TRANSLATE_PUSH  2; x = 19; y = 1
PaintPrimitives.CLIP  3; x = 0; y = 0; width = 95; height = 19
PaintPrimitives.SET_COLOR  r = 10; g = 36; b = 106
PaintPrimitives.FILL_RECT  x = 0; y = 0; width = 94; height = 17
PaintPrimitives.SET_COLOR  r = 255; g = 255; b = 255
PaintPrimitives.SET_FONT 
PaintPrimitives.DRAW_STRING  text = Message Update; x = 0; y = 18; centered = true

It is unclear for me what happens.

#7 Updated by Greg Shah over 8 years ago

Have you compared the JS logs to the Swing logs? Since Swing is working, you should be able to see which operation gets the wrong coordinates.

#8 Updated by Sergey Ivanovskiy over 8 years ago

Have you compared the JS logs to the Swing logs? Since Swing is working, you should be able to see which operation gets the wrong coordinates.

There is a definite issue with resize sequences in the web java log and the JS client log. They are different and for JS side there is interleaves. For example, this JS drawing circle don't match the web java log. It needs to investigate what happens.
START DRAWING CYCLE FOR WINDOW -44
PaintPrimitives.CLIP 1; x = 0; y = 0; width = 141; height = 48
PaintPrimitives.SET_COLOR r = 212; g = 208; b = 200
PaintPrimitives.FILL_RECT x = 0; y = 0; width = 141; height = 48
PaintPrimitives.TRANSLATE_PUSH 1; x = 4; y = 4
PaintPrimitives.CLIP 2; x = 0; y = 0; width = 134; height = 20
PaintPrimitives.SET_COLOR r = 128; g = 128; b = 128
PaintPrimitives.FILL_RECT x = 0; y = 0; width = 133; height = 18
PaintPrimitives.SET_ICON x = 0; y = 0; width = 16; height = 16
PaintPrimitives.TRANSLATE_PUSH 2; x = 2; y = 1
PaintPrimitives.CLIP 3; x = 0; y = 0; width = 17; height = 17
PaintPrimitives.DRAW_IMAGE x = 0; y = 0; width = 16; height = 16
PaintPrimitives.NO_CLIP 2
PaintPrimitives.TRANSLATE_POP 1; x = -2; y = -1
PaintPrimitives.SET_TITLE title = Message Update
PaintPrimitives.TRANSLATE_PUSH 2; x = 19; y = 1
PaintPrimitives.CLIP 3; x = 0; y = 0; width = 95; height = 19
PaintPrimitives.SET_COLOR r = 128; g = 128; b = 128
PaintPrimitives.FILL_RECT x = 0; y = 0; width = 94; height = 17
PaintPrimitives.SET_COLOR r = 255; g = 255; b = 255
PaintPrimitives.SET_FONT
PaintPrimitives.DRAW_STRING text = Message Update; x = 0; y = 18; centered = true
PaintPrimitives.NO_CLIP 2
PaintPrimitives.TRANSLATE_POP 1; x = -19; y = -1
PaintPrimitives.TRANSLATE_PUSH 2; x = 115; y = 2
PaintPrimitives.CLIP 3; x = 0; y = 0; width = 17; height = 15
PaintPrimitives.SET_COLOR r = 212; g = 208; b = 200
PaintPrimitives.FILL_RECT x = 0; y = 0; width = 16; height = 14
PaintPrimitives.SET_COLOR r = 255; g = 255; b = 255
PaintPrimitives.DRAW_LINE x1 = 0; y1 = 0; x2 = 0; y2 = 12
PaintPrimitives.DRAW_LINE x1 = 1; y1 = 0; x2 = 14; y2 = 0
PaintPrimitives.SET_COLOR r = 64; g = 64; b = 64
PaintPrimitives.DRAW_LINE x1 = 15; y1 = 0; x2 = 15; y2 = 13
PaintPrimitives.DRAW_LINE x1 = 0; y1 = 13; x2 = 15; y2 = 13
PaintPrimitives.SET_COLOR r = 128; g = 128; b = 128
PaintPrimitives.DRAW_LINE x1 = 14; y1 = 1; x2 = 14; y2 = 12
PaintPrimitives.DRAW_LINE x1 = 1; y1 = 12; x2 = 13; y2 = 12
PaintPrimitives.DRAW_IMAGE x = 0; y = 0; width = 16; height = 14
PaintPrimitives.NO_CLIP 2
PaintPrimitives.TRANSLATE_POP 1; x = -115; y = -2
PaintPrimitives.NO_CLIP 1
PaintPrimitives.TRANSLATE_POP 0; x = -4; y = -4
PaintPrimitives.TRANSLATE_PUSH 1; x = 4; y = 23
PaintPrimitives.CLIP 2; x = 0; y = 0; width = 133; height = 21
PaintPrimitives.SET_COLOR r = 212; g = 208; b = 200
PaintPrimitives.FILL_RECT x = 0; y = 0; width = 133; height = 21
PaintPrimitives.RESIZE_WINDOW id = -44; width = 8; height = 27
PaintPrimitives.RESIZE_WINDOW id = -44; width = 141; height = 48
PaintPrimitives.NO_CLIP 1
PaintPrimitives.TRANSLATE_POP 0; x = -4; y = -23
PaintPrimitives.NO_CLIP 0
PaintPrimitives.SET_COLOR r = 212; g = 208; b = 200
PaintPrimitives.FILL_RECT x = 137; y = 0; width = 4; height = 48
PaintPrimitives.FILL_RECT x = 0; y = 44; width = 141; height = 4
PaintPrimitives.FILL_RECT x = 0; y = 0; width = 4; height = 48
PaintPrimitives.FILL_RECT x = 0; y = 0; width = 141; height = 4
PaintPrimitives.SET_COLOR r = 255; g = 255; b = 255
PaintPrimitives.DRAW_LINE x1 = 1; y1 = 1; x2 = 1; y2 = 45
PaintPrimitives.DRAW_LINE x1 = 2; y1 = 1; x2 = 138; y2 = 1
PaintPrimitives.SET_COLOR r = 128; g = 128; b = 128
PaintPrimitives.DRAW_LINE x1 = 1; y1 = 46; x2 = 139; y2 = 46
PaintPrimitives.DRAW_LINE x1 = 139; y1 = 1; x2 = 139; y2 = 46
PaintPrimitives.SET_COLOR r = 64; g = 64; b = 64
PaintPrimitives.DRAW_LINE x1 = 0; y1 = 47; x2 = 140; y2 = 47
PaintPrimitives.DRAW_LINE x1 = 140; y1 = 0; x2 = 140; y2 = 46
END DRAWING CYCLE FOR WINDOW -44

#9 Updated by Sergey Ivanovskiy over 8 years ago

Committed revision 11012 only changes to accept negative window ids and to log drawing circles.
Please, help to explain in general words the implementation of draw function of FrameWindowGuiImpl? There are contentPane.doLayout(); and doLayout(); invocations

   /**
    * Draw widget.
    */
   @Override
   public void draw()
   {
      contentPane.doLayout();
      doLayout();

      super.draw();
   }

#10 Updated by Hynek Cihlar over 8 years ago

Sergey Ivanovskiy wrote:

Please, help to explain in general words the implementation of draw function of FrameWindowGuiImpl? There are contentPane.doLayout(); and doLayout(); invocations

doLayout() layouts the window itself - window title, etc. contentPane.doLayout() layouts the content.

#11 Updated by Sergey Ivanovskiy over 8 years ago

I have some troubles, the JS client can't handle correctly resizes requests in the middle of the drawings. It leads to position previously drawings incorrectly. But all resizes requests are from WindowLayout in our case of ModalWindow (see usages of gd.resizeWindow) I blocked the JS resize for the particular unfitted values in order to produce this screen.

#12 Updated by Hynek Cihlar over 8 years ago

Sergey Ivanovskiy wrote:

I have some troubles, the JS client can't handle correctly resizes requests in the middle of the drawings. It leads to position previously drawings incorrectly. But all resizes requests are from WindowLayout in our case of ModalWindow (see usages of gd.resizeWindow) I blocked the JS resize for the particular unfitted values in order to produce this screen.

How come the title is drawn? Do we have any logic that assumes window title is always visible?

#13 Updated by Sergey Ivanovskiy over 8 years ago

How come the title is drawn? Do we have any logic that assumes window title is always visible?

WindowTitleBar is responsible for drawing WindowTitle and it seems that there are no implementations of visibility logic by WindowTitle and WindowTitleBar.

#14 Updated by Hynek Cihlar over 8 years ago

Please ignore note 12.

#15 Updated by Sergey Ivanovskiy over 8 years ago

Please ignore note 12.

Debugging this method

public MessageReturnValue tinyInput(String       text,
                                       int          row,
                                       BaseDataType var,
                                       String       format,
                                       boolean      auto,
                                       boolean      set)

of Window leads ModalWindow.doLayout and contentPane.doLayout(); are called several times from line 1569
Frame frame = (Frame) screen.getRegistry().getComponent(id0);, from line 1598 of Window.java : frame.doLayout(); and third time from line 1621 of Window.java : tc.enable(id0, null, sb, true, wndId);. The last one invokes contentPane.doLayout(); and here it is set the old size for our modal window. It looks private void fillSpace(Container<O> container, Widget<O> innerPane) of BorderLayout calls WindowLayout but the caller class has no knowledge about the size is already calculated. Thus these invocations lead these resize events
16:21:47.136 !!!! w = 8 h = 27 p2j.screen.js:591:10
16:21:47.139 !!!! w = 141 h = 48 p2j.screen.js:591:10
16:21:47.244 !!!! w = 8 h = 27 p2j.screen.js:591:10
16:21:47.248 !!!! w = 141 h = 48
on the JS side. It only explains an overview due to the complexity of the invoked code.

#16 Updated by Sergey Ivanovskiy over 8 years ago

If we call doLayout inside draw it leads to resize events are inside drawing circles!

#17 Updated by Constantin Asofiei over 8 years ago

Sergey Ivanovskiy wrote:

If we call doLayout inside draw it leads to resize events are inside drawing circles!

Are you referring to doLayout called from the BorderPanel.draw code?

#18 Updated by Sergey Ivanovskiy over 8 years ago

If we call doLayout inside draw it leads to resize events are inside drawing circles!

Are you referring to doLayout called from the BorderPanel.draw code?

Yes, draw method of FrameWindowGuiImpl #note-9 invokes doLayout of BorderedPanel<GuiOutputManager> contentPane, and the resize events are inside the drawing circle due to BorderedPanel.doLayout returns different size for ModalWindow that contains it.

#19 Updated by Constantin Asofiei over 8 years ago

Sergey Ivanovskiy wrote:

If we call doLayout inside draw it leads to resize events are inside drawing circles!

Are you referring to doLayout called from the BorderPanel.draw code?

Yes, draw method of FrameWindowGuiImpl #note-9 invokes doLayout of BorderedPanel<GuiOutputManager> contentPane, and the resize events are inside the drawing circle due to BorderedPanel.doLayout returns different size for ModalWindow that contains it.

OK, I don't think this is correct. At the time draw is called, all PaintEvent's are posted with the widget's coordinates/dimensions as at the time of the repaint. So, all clipping rectangles will be forced to draw using that dimensions... and calling doLayout() again in draw() might modify the widget's dimension/location, which in turn will no longer match its associated PaintEvent (and bitmap rectangles added to the ScreenBitmap).

Hynek, do you think is OK to move the doLayout() calls from FrameWindowGuiImpl.draw() to its show() method? Also, shouldn't the layout code from BorderedPanel.draw() be in its own doLayout() method?

#20 Updated by Hynek Cihlar over 8 years ago

Constantin Asofiei wrote:

Sergey Ivanovskiy wrote:

If we call doLayout inside draw it leads to resize events are inside drawing circles!

Are you referring to doLayout called from the BorderPanel.draw code?

Yes, draw method of FrameWindowGuiImpl #note-9 invokes doLayout of BorderedPanel<GuiOutputManager> contentPane, and the resize events are inside the drawing circle due to BorderedPanel.doLayout returns different size for ModalWindow that contains it.

OK, I don't think this is correct. At the time draw is called, all PaintEvent's are posted with the widget's coordinates/dimensions as at the time of the repaint. So, all clipping rectangles will be forced to draw using that dimensions... and calling doLayout() again in draw() might modify the widget's dimension/location, which in turn will no longer match its associated PaintEvent (and bitmap rectangles added to the ScreenBitmap).

Hynek, do you think is OK to move the doLayout() calls from FrameWindowGuiImpl.draw() to its show() method?

I think I put doLayout() into draw() to cover the window resize case. But since, window resize events moved from Window to TopLevelWindow (and cover FrameWindowGuiImpl), so it shoud be ok to move to show().

Also, shouldn't the layout code from BorderedPanel.draw() be in its own doLayout() method?

Probably should. I never investigated this code in more detail. Also some caution should be taken, this is common to both ChUI and GUI

#21 Updated by Constantin Asofiei over 8 years ago

Hynek Cihlar wrote:

Hynek, do you think is OK to move the doLayout() calls from FrameWindowGuiImpl.draw() to its show() method?

I think I put doLayout() into draw() to cover the window resize case. But since window resize events moved from Window to TopLevelWindow (and cover FrameWindowGuiImpl), so it shoud be ok to move to show().

Also, shouldn't the layout code from BorderedPanel.draw() be in its own doLayout() method?

Probably should. I never investigated this code in more detail. Also some caution should be taken, this is common to both ChUI and GUI

Sergey, please test the FrameWindowGuiImpl change as described above and leave the BorderedPanel.draw() as is for now (BorderedPanel change has a more chance at regressions, so if it works with changing only FrameWindowGuiImpl, we will check BorderedPanel after 1811s).

#22 Updated by Hynek Cihlar over 8 years ago

Constantin Asofiei wrote:

Hynek Cihlar wrote:

Hynek, do you think is OK to move the doLayout() calls from FrameWindowGuiImpl.draw() to its show() method?

I think I put doLayout() into draw() to cover the window resize case. But since window resize events moved from Window to TopLevelWindow (and cover FrameWindowGuiImpl), so it shoud be ok to move to show().

Also, shouldn't the layout code from BorderedPanel.draw() be in its own doLayout() method?

Probably should. I never investigated this code in more detail. Also some caution should be taken, this is common to both ChUI and GUI

Sergey, please test the FrameWindowGuiImpl change as described above

Create a simple frame in DIALOG-BOX and then change its size through WIDTH/HEIGHT attributes.

#23 Updated by Sergey Ivanovskiy over 8 years ago

It doesn't help because of this stack trace

BorderLayout<O>.fillSpace(Container<O>, Widget<O>) line: 135    
BorderLayout<O>.doLayout(Container<O>) line: 93    
BorderedPanelGuiImpl(BorderedPanel<O>).draw() line: 136    
BorderedPanelGuiImpl.access$501(BorderedPanelGuiImpl) line: 37    
BorderedPanelGuiImpl$1$1.run() line: 200    
GuiWebDriver(AbstractGuiDriver<F>).draw(NativePoint, NativeRectangle, Runnable) line: 1923    
BorderedPanelGuiImpl$1.run() line: 189    
GuiWebDriver(AbstractGuiDriver<F>).draw(NativePoint, NativeRectangle, Runnable) line: 1923    
BorderedPanelGuiImpl.draw() line: 136    
BorderedPanelGuiImpl(AbstractContainer<O>).draw() line: 326    
BorderedPanelGuiImpl(BorderedPanel<O>).draw() line: 139    
BorderedPanelGuiImpl.access$501(BorderedPanelGuiImpl) line: 37    
BorderedPanelGuiImpl$1$1.run() line: 200    
GuiWebDriver(AbstractGuiDriver<F>).draw(NativePoint, NativeRectangle, Runnable) line: 1923    
BorderedPanelGuiImpl$1.run() line: 189    
GuiWebDriver(AbstractGuiDriver<F>).draw(NativePoint, NativeRectangle, Runnable) line: 1923    
BorderedPanelGuiImpl.draw() line: 136    
FrameWindowGuiImpl(AbstractContainer<O>).draw() line: 326    
FrameWindowGuiImpl(TitledWindow<O>).draw() line: 100    
FrameWindowGuiImpl(OuterFrame<O>).drawInt() line: 98    
FrameWindowGuiImpl(OuterFrame<O>).draw() line: 90    
FrameWindowGuiImpl(ModalWindow).draw() line: 159    
FrameWindowGuiImpl.draw() line: 159    
GuiOutputManager(OutputManager<P>).setInvalidate(Widget<?>, boolean, boolean) line: 1275    
ThinClient.eventDrawingBracket(Widget<?>, boolean, boolean, Runnable) line: 13653    
ThinClient.independentEventDrawingBracket(Widget, Runnable) line: 13519    
ThinClient.viewWorker(Widget, ScreenBuffer, int[], boolean, int) line: 9285    
ThinClient.enableWorker(int[], ScreenBuffer, boolean, Widget, Frame, boolean, int) line: 4346    
ThinClient.enable(int, int[], ScreenBuffer, boolean, int, boolean) line: 4213    
ThinClient.enable(int, int[], ScreenBuffer, boolean, int) line: 4119    
WindowGuiImpl(Window<O>).tinyInput(String, int, BaseDataType, String, boolean, boolean) line: 1621    

It needs somehow to work around BorderedPanelGuiImpl(BorderedPanel<O>).draw()

#24 Updated by Sergey Ivanovskiy over 8 years ago

But if we comment this code

   /** 
    * Draw widget.
    */
   @Override
   public void draw()
   {
//      LayoutManager<O> layout = getLayout();
//      if (layout != null)
//      {
//         layout.doLayout(this);
//      }

      super.draw();
   }

then we fix the issue.

#25 Updated by Constantin Asofiei over 8 years ago

Sergey Ivanovskiy wrote:

But if we comment this code
[...]
then we fix the issue.

Try creating a BorderedPanel.doLayout() method and move the code there.

#26 Updated by Sergey Ivanovskiy over 8 years ago

Constantin, look at this, BorderPanel extends AbstractContainer and it already has doLayout.

   /**
    * Lay out container.
    */
   @Override
   public void doLayout()
   {
      if (layoutManager != null)
         layoutManager.doLayout(this);
   }

How to check inside BorderPanel that chui mode is on?

#27 Updated by Constantin Asofiei over 8 years ago

Sergey Ivanovskiy wrote:

Constantin, look at this, BorderPanel extends AbstractContainer and it already has doLayout.
[...]
How to check inside BorderPanel that chui mode is on?

There are ChUI and GUI specific sub-classes - BorderPanelImpl and BorderedPanelGuiImpl, so you don't need to explicitly check.

#28 Updated by Sergey Ivanovskiy over 8 years ago

Thanks Constantin and Hynek, committed revision 11016 (branch 1811) should fix the issue. Committed revision 11017 adds comments and removes draw method of BorderPanel.

#29 Updated by Hynek Cihlar over 8 years ago

Sergey Ivanovskiy wrote:

Thanks Constantin and Hynek, committed revision 11016 (branch 1811) should fix the issue. Committed revision 11017 adds comments and removes draw method of BorderPanel.

Sergey, just a minor thing. In FrameWindowGuiImpl.show(), super.doLayout() should be doLayout().

#30 Updated by Sergey Ivanovskiy over 8 years ago

Sergey, just a minor thing. In FrameWindowGuiImpl.show(), super.doLayout() should be doLayout().

Committed revision 11019 fixes this issue.

#31 Updated by Greg Shah over 8 years ago

  • Status changed from New to Closed
  • Target version set to Milestone 12

#32 Updated by Greg Shah over 8 years ago

  • % Done changed from 0 to 100

#33 Updated by Greg Shah over 7 years ago

  • Target version changed from Milestone 12 to GUI Support for a Complex ADM2 App

Also available in: Atom PDF