Firemonkey style inheritance? - delphi

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;

Related

Delphi TComboBox with fulltext search and bitmap (owner draw)

I use this code: How to make a combo box with fulltext search autocomplete support? to create custom TComboBox control with searching.
Everything was working fine but I decided to add bitmaps (pictures) into it using this method: ComboBox Simple with Bitmap
But when I added the second code I lost the searching functionality. To enable Owner drawing I added csOwnerDrawFixed style to control in constructor
constructor TComboBox.Create(AOwner: TComponent);
begin
...
Style := csOwnerDrawFixed; ; << Added to enable owner draw
end;
How can I combine these two codes? The strange thing is when I run the project I can see the control redrawing correctly first time but then all data are lost and no drawing is done.
#Rohit Gupta: Actually it is pretty easy to merge that 2 codes: simply place 2nd code into 1st one and rename class :)
I did this but the code is not working - painting the control causes freezing of software and I could not solve this issue that is why I asked for help.
#Warren P: you are right, the better is to create custom control which handles everything.
I created my own control which is basically TEdit with owner draw and TListBox with owner draw and TSpeedButton which works fine:
I need to do some tweaking now and finished control will be available on my blog.
If someone is interested then grab it later on http://unsigned.sk/blog/ (I will post comment here once finished).
Thanks to all for ideas!

How do I write a TDBCtrlGrid VCL Style custom class?

There are lots of questions here about XE2 VCL Styles and custom colors for Buttons, Panels, edits, etc, and VCL Styles. As much as I wish the existing questions covered it, they don't... So DB Control Grids appear to be Yet Another Special Case.
In the DB Control Grid VCL sources, it registers a style hook thusly: TCustomStyleEngine.RegisterStyleHook( TDBCtrlGrid, TScrollingStyleHook);
However, that's not what you would descend from if you want to write your own DB Control Grid VCL style hook. If you do, you get the whole control painted like a very large scrollbar.
So how do you custom-theme a DB Control grid? When you disable the themes completely, it seems to still not allow the active row to be custom painted. So I think that one must have to write a custom subclass and override the Paint method, plus write a VCL style hook class, for this purpose.
It appears that one should probably mostly just customizing using the regular owner draw events OnPaintPanel, and that adding that event, if you didn't, fixes the biggest VCL Styles glitch that I see for TDBCtrlGrid, which is that it doesn't ever use the SelectedColor and just paints everything in flat gray or whatever else is the base color. If anyone can confirm that, or tell me otherwise, it would be appreciated.

Firemonkey: Styling the tGrid or alternative Grid/List components (Virtual)

I'm trying to create my first app based on FireMonkey, and I hit a wall.
The only virtual list control I can find is tGrid.
This component is pretty good, but I can not figure out how to extend or customize it.
I get that there is tCheckbox column, tImage column etc, but what if I need a ButtonColumn or something like this?
Also I would like to style a row, based on the state of the data it represents.
An Example: if the data that is represented in the row has "Error=True" it should be displayed in red.
Has anyone got a similar problem? Or found alternate virtual list/grid components? Or even just some tips on use of the tGrid component.
These components are pretty essential in all database apps so it should be a pretty common request.
Also just as a note, I don't think the TGrid supports Drag & Drop of rows?
I have looked at
Firemonkey version of VirtualTreeView
and
Firemonkey and large amounts of data
If you look at the sources, TCheckColumn is only 15 code lines. If you need to create your own column descendant class it's quite straightforward.
This is one solution, otherwise you can dynamically create some components in your cells and then cast the children when checking the props (TColumn.CellControlByRow() return a TControl and the children would be what you have put in there).
As you want to 'style' your row I would suggest you to write your own TColumn class, even if you can do painting in the OnPaint Event.

Caption for TTabControl

I'm looking for a way of implementing a sort of inset caption before a set of tabs, something like this:
The tab set is not supposed to be multi-line, will only be horizontal and laid out at the top. However it should be correctly scrollable when there are too many tabs.
I fear I'm going to be restricted here with regard to using third-party controls, but I could use subclassing on the standard TTabControl to add the necessary changes to the standard looks and behaviour. (I don't need it to be TPageControl, because it's only the specific arrangement of the tabs that I am interested in.)
Maybe there's some way of implementing this with craftily arranged combination of standard controls, which, despite my endevours, has escaped me.
Basically, any ideas or pointers are welcome.
Oh, and additional requirement is, it should blend well with desktop themes.
Granted some time has passed, but I recently needed this style and found you can do it with the TMS Software TAdvOfficePager. It has a property FixedTabs, which I set to 1 in this case. It also has an OnChanging event where you can prevent access to a tab, in this case I used AllowChange := (ToPage > 0); Lastly, I set the first tab to disabled.
Then just style the first tab different than the rest and you can have something like this:
Have you tried to make the first tab to be the caption you want.
With some additional logic you can restrict the selection of this tab.
I don't know if you can control the style of each tab individually to make the first one look as it is not the tab.
Here is crafty arrangement of controls that will work. I have done this sort of thing in the past. Best of all it automatically handles scrolling of tabs.

Frame behavior in Delphi application issue

I have an application that uses a frame extensively and needs to hide/show certain buttons depending on which form is active at the time. In order to keep the buttons neat and organized appropriately, I have put them on panels and show or hide the panels as needed for each form. My problem is when each form is initially created, the panels on the frame are out of order even though I am explicitly telling them which order to put themselves into. After I hide and re-show the form, the panels are in the correct order. Any suggestions on how to keep them in the proper order from the very beginning?
Instead of giving the panels explicit positions, try giving them alignments. They tend to stick better than way, and they do a better job of resizing if you resize the form.
You can also try using a stackpanel (or was it flowpanel?) as parent for the panels. Then you will have a order instead of a position to manipulate.
Maybe you can have a look at the DevExpress LAyoutControl? It helps us creating interfaces that always look good, no matter if we show or hide certain groups / panels. It even allows for run-time customization of the interface, if you want that!
You may try to organize them by coordinates i.e.: setting Top and Left. Unless your panels are aligned, this will always work (but it takes bit lot of work).
I had this problem and I found that the solution was to do this in FormCreate (or in a CMShowingChanged method of your frame):
MyPanel1.Align := alNone;
MyPanel2.Align := alNone;
MyPanel1.Align := alBottom;
MyPanel2.Align := alBottom;
Restore in the order that you need - this seemed to sort out the order visually.

Resources