Jump to content


Photo

Resize event


  • Please log in to reply
3 replies to this topic

#1 ron

ron
  • Members
  • 31 posts

Posted 31 March 2016 - 08:31 PM

Hi,

can anyone tell me why the resize event executes 3 times and when you wait another 15 sec the event executes again..



Ron

Attached Files



#2 markus_ja

markus_ja
  • Members
  • 319 posts
  • LocationAustria

Posted 01 April 2016 - 10:03 AM

I'm interessted too.



#3 Cipher Diaz

Cipher Diaz
  • Administrators
  • 313 posts

Posted 02 April 2016 - 03:40 AM

This happens because all forms are hosted on a display, which in turn is hosted inside a root-container.

The organization is as such:

 

  • Display Container (TW3Display)

  • Display View (TW3DisplayView)

  • Form[s]

This organization has to do with animations and moving forms in and out of view. You can also create components directly on these host containers (they are TW3CustomControl based after all). So if you want a static header, like iOS apps typically have -- one that is not affected by scrolling or moving between forms, just create it in TW3Display(!). Then the toolbar will be completely unaffected by whatever happens in the form container (which is subject to CSS3 GPU scrolling).

 

So this architecture is there for a reason, although they do cause a couple of extra resizes on startup.

But that will change very soon.

 

More technical, why does resize fire at all before things are fully visible?

 

Well, browsers differ, but there is always a short delay between when an object is created by your constructor - and when the visual element is injected into the DOM and fully ready to be used. This can cause some confusion when coming from Delphi, because WinAPI does not issue events before everything is ready (which sadly JS does!). Naturally, when TW3Display resizes it forces TW3DisplayView to resize as well -- which in turn causes the forms to resize.

 

The resize that you get after a couple of ms is the one issued when the DOM is actually 100% ready. So the 3 first should actually never fire at all. But what you should do in all your code, is to check the csReady component state. Always.

 

Procedure TForm1.Resize;

begin

  if  Handle.Valid and (csReady in ComponentState) then

  begin

    // Ok, form is now setup -- but it can take 1-2 ms before the browser has realized the controls!

  end;

end;

 

This is something we have worked on a lot! In fact, i re-wrote the whole form/display system at least 4 times trying to get rid of it. It used to issue 10-20 calls, so getting it down to 4 took a lot of work, considering we target a myriad of browsers, builds and platforms.

 

But in such a complex system, fixing one thing can often cause problems with legacy code. So we decided to opt for some manual labour like you will find in C#/Mono and iOS development. There you have to check everything. So i think we found a good balance.

 

Tips:

1. Just because an object has been created, does not mean its fully realized in the DOM (mozilla is better than chrome here)

2. Remember that all handles have helper classes which gives you functions to test them (!)

3. Always check references before using them in resize handlers (always!)

 

 

procedure TForm1.Resize;

begin

  if  Handle.Valid and (csReady in ComponentState) then

  begin

  end;

end;

 

All TW3Components have the ComponentState SET, so it will work on all visual elements.

To Check if the document is ready, 

 

Also, when updating content, use beginupdate/endupdate:

 

beginUpdate;

try

  PopulateNewObjects;

finally

  AddToComponentState([csSized]); //tell the system to issue a resize

  EndUpdate;

end;

 

Low-level work:

 

All handle types has helper classes. And TW3ControlHandle has the best:

 

  (* Helpter class for control handles *)
  TControlHandleHelper = strict helper for TControlHandle
    function  Defined:Boolean;
    function  UnDefined:Boolean;
    function  Valid:Boolean;
    function  Equals(const Source:TControlHandle):Boolean;
    function  Ready: Boolean;
    function  HandleParent:TControlHandle;
    function  HandleRoot:TControlHandle;
    procedure ReadyExecute(OnReady:TProcedureRef);
    procedure ReadyExecuteAnimFrame(OnReady:TProcedureRef);
  end;

 

So all the code normal JS coders use to avoid this -- we have also. But it requires you to get into the RTL a bit (just like we all did with VCL) to get to grips with it.

 

Future work

==========

 

The above topics are JS/browser problems, not RTL problems.

This is just how JavaScript and the DOM works. Any Handle/control will never be ready until after the constructor finishes, which is why the 3 initial resize calls are very hard to get rid of (!)

 

But we keep on updating and making fixes, so it will be taken care of at a later stage.

 

 

Hope this explains it :)



#4 ron

ron
  • Members
  • 31 posts

Posted 02 April 2016 - 09:30 PM

Thank you for the detailed explanation, it's clear to me now..

Ron




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users