2

How can I retrieve the height and width of the browser area?

I want to show one form always in landscape mode, regardless whether the mobile phone has rotated the browser view.

if the browser is in portrait postion I want to rotate the form (TForm.Angel := 90). In order to force landscape mode.

Update:
Here is a picture, how the result should look like: enter image description here

I found a solution, but I am not so really happy with it. It's easy to rotate the view, but the origin is not in the center, so I have to manually correct it, and I don't understand why this transformation is neccessary.
Here is the code:

procedure TForm1.ForceLandscape(aEnabled: Boolean);
var
  browserWidth, browserHeight: Integer;
  isLandscapeMode: Boolean;
begin
  browserHeight := Application.Display.ClientHeight;  //BrowserAPI.Window.innerHeight;
  browserWidth := Application.Display.ClientWidth;    //BrowserAPI.Window.innerWidth;

  isLandscapeMode := browserHeight > browserWidth;

  if aEnabled and isLandscapeMode then
  begin
    Angle := 90;

    Height := browserWidth;
    Width := browserHeight;
  end
  else
  begin
    Angle := 0;

    Height := browserHeight;
    Width := browserWidth;
  end;
end;

procedure TForm1.InitializeForm;
begin
  inherited;
  // this is a good place to initialize components

  //Need to put a transform.orign for form rotation (Angle)
  var x := trunc(Application.Display.ClientWidth / 2);
  var myStyle := TInteger.ToPxStr(x) + ' ' + TInteger.ToPxStr(x);
  w3_setStyle(Handle, w3_CSSPrefix('TransformOrigin'), myStyle);

end;
markus_ja
  • 2,931
  • 2
  • 28
  • 36
  • You should have a look at the "Layout manager" in Smart. There are a couple of demos included in the demos folder. A tutorial was written a wile ago: [Part-1](http://www.thedelphigeek.com/2012/05/laying-out-smart-applications-with.html), [Part-2](http://www.thedelphigeek.com/2012/05/laying-out-smart-applications-with_17.html), [Part-3](http://www.thedelphigeek.com/2012/05/laying-out-smart-applications-with_18.html) and [Part-4](http://www.thedelphigeek.com/2012/05/laying-out-smart-applications-with_19.html). – Jørn E. Angeltveit Jul 24 '14 at 13:54
  • There are also [a few examples at the forum](http://smartmobilestudio.com/forums/topic/tlayou-questions/). – Jørn E. Angeltveit Jul 24 '14 at 13:57
  • I think you missunderstood me. I don't want to reorganize the layout. I want to rotate the layout. For rotating, I didn't see any examples. – markus_ja Jul 30 '14 at 13:16
  • OK. Perhaps I misunderstood (and still do :-P)... If you rotate a real device, only the screen ratio is changed. You don't need to rotate the form itself to support (ordinary) landscape mode. The Smart application will detect the rotation of the device in the Resize method. If you open one of the Layout manager demos and toggle between "Vertical" and "Horizontal" in the combobox - that's the way the application will behave when a user flips the device around... IIUC, you want to manually rotate the application as if the device didn't have support for "rotate" detection? – Jørn E. Angeltveit Jul 30 '14 at 15:08
  • What I want to do is: I have a form (e.g. grid or chart), where it only makes sence to show the form in "landscape" mode. Thus, when the device is in "portrait" mode, the form should still be displayed in "landscape", in order to force the user to rotate the device. – markus_ja Aug 01 '14 at 06:22

1 Answers1

1

The simplest way would be to use the main form's With and Height.

Create a new "Visual project" and add an EditBox to the form.
Put this code into the "Resize" method:

Edit1.Text := Format('%d x %d', [Self.Width, Self.Height]);

If you, however, want to keep the main-form at a fixed size, you would need to read some other properties.

Self.Width := 250;
Self.Height := 250;

There are several ways to get these dimensions. Both the "window" and "document" DOM-element have some properties you can use:

  • window.innerWidth
  • document.documentElement.clientWidth
  • document.body.clientWidth

In Smart you can access these from the Application object:
(Add two more edit-boxes...)

W3EditBox2.Text := Format('%d x %d', [Application.Document.ClientWidth, Application.Document.ClientHeight]);
W3EditBox3.Text := Format('%d x %d', [Application.Display.ClientWidth, Application.Display.ClientHeight]);

It seems to be a bug in Application.Document.ClientHeight as it always returns 0...


Remember that the running code is JavaScript. You can find lots of useful information on the web.
It's very easy to transform these JS-snippets into Smart Pascal via an asm section.

Eg:

var
  w,h: Integer;
begin

  //Pure JavaScript below.
  //The @-prefix maps the variable to a SmartPascal declared variable

  asm 
    @w = window.innerWidth;
    @h = window.innerHeight;
  end;

  W3EditBox4.Text := Format('%d x %d', [w, h]);

end; 

Another trick would be to declare a Variant variable.
A Variant variable can hold a whole JavaScript object, and enable "late binding"-ish access to the members of the object:

var  
  v: Variant;
begin

  //Grab the whole "document" element from the DOM
  asm
    @v = document;
  end;

  //Access all "document" members directly via the "v"-variable 
  W3EditBox5.Text := Format('%d x %d', [v.documentElement.clientWidth, v.documentElement.clientHeight]);

end;

Screenshot of the code-snippets above:

enter image description here

Community
  • 1
  • 1
Jørn E. Angeltveit
  • 3,029
  • 3
  • 22
  • 53