Saturday, May 19, 2012

Laying out Smart applications with Layout Manager [4]

Last time you’ve seen how to make different layouts for portrait and layout orientations. This time I’ll show you how to dynamically set layout parameters in Resize.

The task is almost the same as before except that this time we want the big panel to have equal width and height.

image

This time we’ll need four form fields.

FLayoutLandscape: TLayout;
FLayoutRight: TLayout;
FLayoutPortrait: TLayout;
FLayoutBottom: TLayout;

Layout definitions are the same as in the previous case except that now we are storing internal part of both layout in two separate fields (FLayoutRight, FLayoutBottom). I have also removed Layout.Width(140) and Layout.Height(140) as width and height will be set in the Resize method.

FLayoutRight :=
  Layout.Right(
    Layout.Top(Layout.Stretch, [Panel2, Panel3, Panel4]));
FLayoutLandscape :=
  Layout.Client([
    FLayoutRight,
    Layout.Client(Panel1)
  ]);
FLayoutBottom :=
  Layout.Bottom(
    Layout.Left(Layout.Stretch, [Panel2, Panel3, Panel4]));
FLayoutPortrait :=
  Layout.Client([
    FLayoutBottom,
    Layout.Client(Panel1)
  ]);

In Resize, we are again comparing Width and Height but before we resize the outer layout we have to set the Width or Height for the inner one.

procedure TForm1.Resize;
begin
  inherited;
  if ClientWidth > ClientHeight then begin
    FLayoutRight.Config.Width(ClientWidth - ClientHeight);
    FLayoutLandscape.Resize(Self);
  end
  else begin
    FLayoutBottom.Config.Height(ClientHeight - ClientWidth);
    FLayoutPortrait.Resize(Self);
  end;
end;

The logic behind the Config.Width call in the landscape path is as follows.

  • We set the FLayoutRight width to ClientWidth – ClientHeight (those are form properties).
  • That will leave ClientWidth – (FLayoutRight width) = ClientWidth – (ClientWidth – ClientHeight) = ClientHeight pixels for the Client.Top layout.
  • As the Client.Top will be ClientHeight pixels high by default, it will be square.

The logic for the second (portrait) code path follows the same pattern.

5 comments:

  1. Ok, here is a challenge. How does one use the layout manager to center a fixed size panel over the entire surface?

    ReplyDelete
    Replies
    1. Good one. I don't think this is supported (yet). This is actually hard to do with alignment alone - you need anchors, which are not implemented in the Layout Manager. I'll think about this but no promises.

      Delete
    2. Agree! Centered panel is commonly used good layout for web page)

      Delete
    3. Perhaps this is most easily solved with a Center option besides Client/Top/Bottom/Right/Left?
      It wouldn't adjust width and height, but padding. It might not easily support two components put in one layout though.. depending on implementation.

      Delete
    4. Center option is implemented in Smart 1.1.

      Delete