Jump to content
ron

Resize event

Recommended Posts

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

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 :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×