How to Create Custom Shape Changing Dialogs Form - delphi

How I can create a custom shape changing dialog form in Firemonkey using Delphi XE3.
I want create two layout with some components(buttons,edits) inside any one of them, and one button in the first layout with name "SHOW/HIDE MORE DETAILS ",
So this button will do:
layout2.visible:=false
With this layout2 component hide but not auto align and auto size form.
How i can doit?
Here image example about what i want to do

Look at the following code:
procedure TForm1.Button1Click(Sender: TObject);
begin
Form1.Height:=40;
end;
Using this, when you click More (in this case the button is called Button1) the form changes its height. I set 40, but of course you can use another integer value.

Simply control the Forms Height Property to expand or contract the form. Any control that is not being painted in the client area still remains in the same position regardless.
Make sure that you disable your none-visible components when contracting the form, despite not being drawn they can still receive focus.

Related

Auto layout of vertical panels in Delphi

I have been away from Delphi for a few years, doing web apps.
I have gotten used, in HTML of just declaring successive <div> ... </div> and having them placed below each other, with spacing provided by CSS.
I want to do a Delphi app where I have a collection of data, let's say it's data about movies. Initially, I would have a panel for each , showing only the title. If you click one, it will expand to show actors, director, plot summary, etc. Click another and the first will shrink & the new one expand (max one expanded; click that one again to shrnkk it).
So, I have two layout problems: 1) to calculate the initial .top of each panel and 2) to re-calculate as different panels are clicked.
I am quite capable, of course, of coding all of this manually, but it seems tedious and error prone.
Is there an accepted way to do this? A VCL component that comes with Delphi? Should I be asking on https://softwarerecs.stackexchange.com/ for a 3rd party VCL component?
The closest VCL control is probably TCategoryPanelGroup, which is composed of vertically aligned expandable panels (TCategoryPanel).
The control does not have an 'autocollapsepanels' or 'maxexpandedpanelcount' property, but you can use some simple code to achieve the required behavior.
E.g. the below OnExpand event handler, if attached to all category panels in the group, will cause an expanded panel to close others.
procedure TForm1.CategoryPanelExpand(Sender: TObject);
var
I: Integer;
begin
if Sender is TCategoryPanel then
for I := 0 to CategoryPanelGroup1.Panels.Count - 1 do
if CategoryPanelGroup1.Panels[i] <> Sender then
TCategoryPanel(CategoryPanelGroup1.Panels[i]).Collapse;
end;
You can set AlignWithMargins property of your panels to true, then adjust spacing by using the Margins properties of the panels.

How to cope with the bug with style lookup in controls nested in FMX Frames

I have met a bug in applying of StyleLookup in TTabControl nested in FMX Frame. The appearance of the control does not accept the style if the frame with the control is nested in a HorzScrollBox and at form creation the position of the frame is outside the visible area of the form. In other words if the control is visible when the form is shown the control is painted with necessary style appearance otherwise - not.
To reproduce the bug:
Create a new grid metropolis application.
Create a Frame and put a TTabControl on it. Set Align of the TabControl to alClient. Add, say, 4 TTabItems.
Open detail form, and set its width to a value > your Screen.Width (for me 2500 was enough).
Copy-paste any of the Columns (Layouts), say, 2 times and use the most right layout to nest a frame in it. You will see normal presentation of tabitems at designtime. Set style settings. You will get the following picture:
Done. Run the project. You will get the bug.
At runtime the appearance of TabItem is like this:
If you set the StyleLookup manually at runtime the appearance might either not change either be set to every other item (for example 1st, 3rd and not set to 2nd and 4th though you assign the same StyleLookup to all TabItems). The other interesting finding. If you have other forms containing TabControls with TabItems (nested without frames and closer to left border of the form) for example Form2, you get the following. If you show the faulty Form1 at runtime first you will see the bug, but if you close this form and show Form2 you see proper TabControl. Closing Form2 and showing Form1 (faulty) afterwards will give you a proper appearance of TabControl in a faulty form.
It has something in common with the bug reported by me earlier: Incorrect selection of items in an FMX TListbox (Grid Metropolis UI). It is still not fully solved.
There was also a question yesterday but it is about an exact problem with VCL Frames and the solution is not suitable for FMX.
Appended.
The way is to partially set the style is to set OnPainting event handler for TTabControl in the parent form unit (it does not work being set in frame unit) and write something like this:
procedure TPatientsScrollF.HMDiagnosisFr1TabControl2Painting(Sender: TObject;
Canvas: TCanvas; const ARect: TRectF);
var
i: byte;
begin
(Sender as TTabControl).StyleLookup := 'tabcontrolstyle';
for i := 0 to (Sender as TTabControl).TabCount-1 do
(Sender as TTabControl).Tabs[i].StyleLookup := 'tabitemstyle';
end;
But than you still get a problem - the Tabs are not drawn properly - see the lower edge of inactive Tabs.
Or even like this:
Appended 2
I have just met the bug appearing even at design-time after placing a frame in a form and assigning style to TabItems. The TabControl looks like in fig. 3.

Positioning of custom list box item components in Delphi XE5, Firemonkey

I've customised the style of a Firmeonkey list box item in such a way that now it can consist of 4 TLables in it. Each of the lable has Alignment as alNone.
I'm setting position of each of them in my code whenever i need to add any item. I've observed that when my list has scroll bar and if first component is not visible (i.e. i've scrolled down enough) at that time if i re-add all the items again in list box, then the position of TLabels in first items (or items which are not shown) get distorted.
For setting positions I am using below code :
(tmpListBoxItem.FindStyleResource('txtCol2') As TLabel).Position.X :=
(tmpListBoxItem.FindStyleResource('txtCol2') As TLabel).Position.X + (tmpListBoxItem.FindStyleResource('txtCol2') As TLabel).Width;
Any suggesstions, how can i overcome this issue.
Regards,
Padam Jain
Firemonkey styles are repeatedly 'applied' and 'freed' as components appear and disappear from screen.
It is not enough to simply set properties of style objects once and expect those values to be remembered. What you need to do is either listen to the OnApplyStyleLookup event or override the ApplyStyle method of a custom component and use the same you have above to set the properties again.
This means you'll need somewhere to store the values you are going to set.
I would suggest for your situation that you subclass TListBoxItem so you can add suitable properties or fields and put your code in ApplyStyle.

Delphi - child forms have frame of parent

I have a delphi application with multiple forms. Initially I had tried a setup where each newly opened form was a frame and the "parent" of this form (whichever called to open the form) was hidden as the child was shown with the child being resized and relocated to give a seamless effect of having one window, when the child is closed the parent is relocated and again made visible. All forms have a bsSingle border style for the Windows title block.
This approach worked well for positioning however the issue I have is a noticeable flicker as the parent form is closed and the child opened, and as there is a small time period where no form is opened the icon/tray on the start bar would shift around and itself become hidden and visible.
Does anybody have any advice on solving this problem? I thought perhaps if I only had one form with the border within the application and opened each new form within this border it would work better - though I am unsure how exactly to do this.
Any help is much appreciated.
It is easy to make one form appear as a child inside another. Create a new form which will contain and create your other forms:
procedure TMainForm.FormCreate(Sender: TObject);
var
F : TForm;
begin
F := TOneOfYourChildForms.Create(Self);
F.Parent := Self;
F.Show();
end;
Create both your child forms similar to this, then just do Show on the one you want to display and Hide on the other. Set BorderStyle to bsNone on the child forms to remove the caption. Turn off Auto-Create on your forms in project settings if you create them yourself like this instead.
I've had success with this design, and I think it helped to have the contents of the "main form" within a TFrame as well. When you want to show the main form, you would just perform a frame swap.

How to check if form is maximized?

I'm having a problem with a component I use.Its aligned to bottom ,and ,when form is maximized,the control is placed at the correct position,but when I attempt to minimize the form,the control stays at the position where it is.
I tried using a timer that always sets the align to bottom,but I'm sure a timer is the worst solution to my issue.
Please suggest a way to set the align to Bottom when the form is restored from maximize.(maximize->restore only).
My current idea is to check if form is maximized at FormResize event,but that won't work,because I need to do it when its restored,not maximized.
You can check if a form is maximised by using
Self.WindowState = wsMaximized
Other states are
wsNormal
wsMinimized
wsMaximized
Depending on what you are doing, you could also place the control on a panel and align the panel to the bottom of the form, if you turn the borders off and use the parent colour, you cant see the panel, that way it will stay at the bottom of the form without additional code.

Resources