Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 6 of 6 total
Thread Layout for complex applications
Thu, Oct 1 2015 9:10 AMPermanent Link

Christian Kaufmann

I read the thread startet by Matthew Jones a few weeks ago. Coming from Delphi I often group UI
functionality on a panel on a form and at runtime I create a form and move the panel to a container
in my mainform.

I made some tests with EWB 2 and it seems to work. But just before I start do use it I would like
to know:
- Is this a way to go or should I use a different approach?
- Can I add my own base class for a form? I tried to add a component inherited from TFormControl,
but this was not added in the library. In fact I need a TBasicPanel only.


Something similar I would like to do is building a a list with complex items (several labels/icons,
visible depending on width of the panel) in a mobile application. Again I would like to design the
single item on one TForm (TPanel) and then build the list by creating such a container for each
item.


cu Christian


Here is my code:


type
  TFMain = class(TForm)
    ....
  private
    FView : TForm;
    procedure ChangeView(AView: TFormControlClass);
  end;

var
  FMain: TFMain;

implementation

uses
 view1, view2;

procedure TFMain.BViewFirstClick(Sender: TObject);
begin
 ChangeView(TFView1);
end;


procedure TFMain.BViewSecondClick(Sender: TObject);
begin           
 ChangeView(TFView2);
end;

procedure TFMain.ChangeView(AView: TFormControlClass);
begin
 if Assigned(FView)
   then FView.Free;
//  FView := AView.Create(nil);  << Doesn't compile; I think a known bug.
 AView.Create(Self);
 FView := TForm(Component[ComponentCount - 1]);

 FView.Layout.Position := lpTopLeft;
 FView.Layout.Stretch  := lsBottomRight;
 FView.Parent := PgView;
end;

procedure TFMain.Button1Click(Sender: TObject);
var
 l : TFListItem;
begin            
 // Adding a form as list item in a scrollable panel.
 l := TFListItem.Create(Self);
 l.Layout.Position := lpTopLeft;
 l.Layout.Stretch  := lsRight;
 l.Layout.Consumption := lcBottom;
 l.Parent := ScrollPanel1;
 l.LNumber.Caption := IntToStr(ComponentCount);
end;
Thu, Oct 1 2015 10:03 AMPermanent Link

Matthew Jones

Christian Kaufmann wrote:

> Again I would like to design the
> single item on one TForm (TPanel) and then build the list by creating
> such a container for each item.

This is very possible. I shall be doing this in my next conversion,
having used BasicPanel copying in my shop, and not finding it too good.
Tim has suggested that it makes sense in some situations to use a
custom component - depends on the situation of course.

You can already "parent" a form on another panel, something I do a lot
for my web shop. Parenting the form on a scroll panel and setting the
layout options will give a nice list.

   frmLogin := TfrmLogin.Create(pnlParent);

--

Matthew Jones
Thu, Oct 1 2015 10:28 AMPermanent Link

Christian Kaufmann

Matthew Jones wrote:

> Tim has suggested that it makes sense in some situations to use a
> custom component - depends on the situation of course.

I think custom component makes since when you can reuse it in different places.

But I group my application in "modules/views" and for each one I have customized UI elements in the
client area of my application. The main form only contains header, sidepanels and statusbar.

I tested it and it works. I was just thinking about the overhead of a TForm compared to a
TBasicPanel. Not sure if this is important or not.

cu Christian
Thu, Oct 1 2015 11:45 AMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Christian,

<< - Is this a way to go or should I use a different approach? >>

My recommendations are usually in this order:

1) Custom control
2) Custom form
3) Winging it by creating new instances on the fly dynamically (this is usually not as bad as it sounds with the layout management)

<< - Can I add my own base class for a form? I tried to add a component inherited from TFormControl,
but this was not added in the library. >>

You can, but unfortunately there's no "register a new form class" capability yet in the IDE (this just missed the 2.01 deadline, but it will be in the Environment/Options dialog), so you have to do a little bit of "dancing around" to make it work, namely:

1) Create a simple, throwaway descendant control of any current control (TControl will work), and make sure that it references the unit in which your TFormControl-descendant is declared, or simply includes it.

2) Add the control to the component library:

http://www.elevatesoft.com/manual?action=viewtopic&id=ewb2&topic=Adding_Component

Voila, you can now use your custom form class for new forms at design-time, and anything you add to it in code will automatically show up in any existing forms when you rebuild the component library.

You can also parent forms into other containers, so you don't really need to use a panel in most cases.

Tim Young
Elevate Software
www.elevatesoft.com
Mon, Oct 5 2015 10:11 AMPermanent Link

Christian Kaufmann

Tim Young [Elevate Software] wrote:

> Voila, you can now use your custom form class for new forms at design-time, and anything you add
> to it in code will automatically show up in any existing forms when you rebuild the component
> library.

Thanks. Finally I solved all details, especially with the interfaces. For me it is still not 100%
clear, what happens when and where:

Is this some default code I really need? I didn't much in the help about these two methods.
Couldn't the GetInterfaceClassName method just return "ClassName" by default?


{$INTERFACE TBSViewPanel}

 TBSViewPanel = class(TFormControl)
 protected
   procedure InitializeProperties; override;
   function GetInterfaceClassName: String; override;
 published
   property Height;
   property Layout;
   property Width;
 end;

implementation

procedure TBSViewPanel.InitializeProperties;
begin
 inherited InitializeProperties;
 LoadFromResource;
end;

function TBSViewPanel.GetInterfaceClassName: String;
begin
 Result := TBSViewPanel.ClassName;
end;




Just one question regarding the interface editor:
- TElement.ApplyProperties: This is only important for interfaces with more than one state?

cu Christian
Mon, Oct 5 2015 11:04 AMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Christian,

<< Is this some default code I really need? >>

You don't actually need either of those methods (see below), but for 2.01 you'll need to at least include the GetInterfaceClassName override.

<< I didn't much in the help about these two methods.  Couldn't the GetInterfaceClassName method just return "ClassName" by default? >>

Yes. I'm not sure why that method was handled like that, but there may have been a different setup with the class names/inheritance that has since been removed/modified.  I'll see if I can remove that requirement for 2.02 - it's a quick fix and only a few classes actually need to override the GetInterfaceClassName method.

<< Just one question regarding the interface editor:
- TElement.ApplyProperties: This is only important for interfaces with more than one state? >>

Yes.

Tim Young
Elevate Software
www.elevatesoft.com
Image