What control should I use to create this UI in Delphi Firemonkey - delphi

I am developing an application for mobile (android and ios) by Delphi xe5.
I am willing to create this UI:
I tried TListBox but image on left and right cant be set.
I tried TListView but same problem as TListBox
I tried TGrid with custom column, The problem of texts and images is solved but I can't create headers of each rows (it hasn't something like colspan)
What I need is to create a custom control and repeat it.
What is the best solution?
Any solution or guide line will be appreciated.
Solution
Thanks #Mike Sutton for answer, this is the result

The style here is so different from a standard TListBoxItem style that is probably makes sense to start from scratch, in which case the issues with accessing the default styles become immaterial.
Add a TStyleBook to your form.
Set the StyleBook property of the form to point to it.
Double click the icon to open the editor.
Drag a TLayout to the structure panel and drop it on the only item which will be there.
Set the StyleName property of the TLayout (e.g. ScoreListBoxItemStyle).
Drag/drop other components to build up the layout you want (remember TLayouts for 'hidden' positioning).
Set the StyleName property of any components you want reference from your code.
Subclass TLIstBoxItem to TScoreListBoxItem (if using the StyleName suggested above).
Add properties for your text, images etc.
In the setter methods for each of these, cache the data and call a method such as:
procedure SetFlag1;
var O: TFMXObject;
begin
O := FindStyleResource('flag1'); //StyleName of the item
if O is TImage then
TImage(O).Bitmap.Assign(FFlag1);
end;
Override the ApplyStyle method and call all of your methods that set the data in the style.
Now create your items in code:
Item := TScoreListBoxItem.Create(Self);
ListBox1.AddObject(Item);
Item.Flag1.LoadFromReource ...
...

Here's an idea that I don't have time to test:
Create a descendant of a TListBoxItem and in that add you two images as normal TImages. I'm pretty sure that a TListBoxItem can parent an object. You'll have to place the images on the listbox item where you want them. Then whenever you add an item to the listbox item just pass in your own descendant.
(If this doesn't work someone let me know and I'll delete this.)

Related

How to let Parent component get click events of child components?

I have a FireMonkey application with multiple buttons on it (actually, rectangles). I want to have one procedure called on any click on the Form, besides the specific action of each button.
Since the HitTest of each child component is set to True, the parent's HitTest is automatically false.
So what is the right way to deal with this?
A silly workaround would be to assign this procedure to each button's OnClick event, but this will not make any sense when I have a Form with hundreds of buttons on it.
I found solution for vcl.
you can find component base of mouse position by this code:
var
ctrl : TWinControl;
begin
ctrl := FindVCLWindow(Mouse.CursorPos);
if ctrl.Name = '' then
ShowMessage(ctrl.Owner.Name);
For FireMonkey no result founded but You can get mouse position on form and analyze component base on result of that point and find name of it then proceed to your event base of that component.
A Simple Interceptor/Interposer Class of TRectangle did the job!
Thanks to everyone for their input.

What is the ideal way to modify sub control styles in a custom firemonkey control?

I am attempting to develop my first proper custom control for the Firemonkey framework and have ran into what may possibly be an obvious (or not) solution.
Inside my Firemonkey control I have declared FPanel: TPanel; which is then created in the constructor and freed in the destructor. The panel is created along with my control when I add it to a new Multi-Device Form without any problems.
By default the TPanel has borders around the sides of the control which I do not need in my control.
So my question is, what is the ideal way to remove the borders of a TPanel which is child to my custom control? I could not see an obvious property to change, unless I am mistaking I believe we must modify the style of the panel which I assume would be done via a TStyleBook.
Am I right then in thinking that I need to add a TStyleBook to my control, and from there add the panel to the Style book and modify it this way? Unless I am missing something this seems like a lot of extra work for what should be a very quick and simple change.
Assuming this is the correct way, is there an example of modifying a TStyleBook through code?
Thanks.
Because all Firemonkey controls can be parents, one way is to not use TPanel at all and instead replace it with another Firemonkey control such as the TRectangle shape.
The TRectangle shape can then be customised directly through its properties to remove the border which can be achieved by setting the Corners and Sides to False.
Additionally if you don't require any borders whatsoever then the TLayout control behaves just like a TPanel but without the borders.

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.

Firemonkey style inheritance?

I've just started with Firemonkey, and still have a lot to learn with regards to the usage of styles, but there is something I can't get figure out.
I've learned how to simulate a TListView using styles. So I've made a style which adds a progress bar to a list item, let's call this ListItemStyleProgressBar.
Now I'd like two ListView instances on my form, one where the font of the TListItem is red, and one where the font is blue. How to achieve this? Can I make an style which 'inherits' from ListItemStyleProgressBar (ListItemStyleProgressBarRed)?
Next to that, I'd like to be able to 'style' these two listview instances, so have a style which shows a light back and a style which shows a dark back.
What confuses me is it seems the styling is needed to add functionality (add a TProgressBar to a TListItem) as well as to do styling for this added functionality.
Can anyone tell me what I'm missing here?
No. There is no inheritance mechanism for styles. There are two ways to solve your problem:
1) Create two (or more) very similar styles to represent each 'look'.
2) Make the changes at run-time either with the OnApplyStyleLookup method or, if you have a custom control, by overriding the ApplyStyle method.
In the latter case you'll need something like this:
procedure TMyClass.ApplyStyle;
var O: TFMXObject;
begin
O := FindStyleResource('background');
if O is TRectangle then
TRectangle(O).Fill.Color := claRed;
end;

How can I create a context menu for a Delphi component?

I want to create a context menu for Delphi components like TDBGrid, TTreeView or similar. How can I do that?
Place a TPopupMenu onto your form and design your menu with it. Then select the component the popupmenu is meant for (DbGrid, TreeView, ...) and set it's PopupMenu property to the PopupMenu you just designed.
You can have different PopupMenus for different components.
After placing a TPopupmenu control and linking it to the desired control, if you want to change the available items in the popup menu according to the selected cell or node in a treeview use the OnContextPopup event of the control, that gives you a chance to alter the default behaivor of the Popupmenu

Resources