User:Achursin/Customizing FireMonkey Applications with Styles (old)
Go Up to FireMonkey Application Design
FireMonkey controls are arrangements of a tree composed of subcontrols, primitive shapes, and brushes, decorated with effects. These compositions are defined as styles, stored in a style book. The individual elements of a style are internally called resources; because that term has several other meanings, the term style-resource is used for clarity. Styles provide a great deal of customization without subclassing.
The FireMonkey styles that are provided with the product are located in C:\Program Files (x86)\Embarcadero\Studio\23.0\Redist\styles\Fmx
.
Contents
Default Styles
In FireMonkey, each control class has a default style, hard-coded per platform.
To see the style definitions in the FireMonkey Style Designer:
- Drop a TStyleBook on the form in the Form Designer.
- Double-click the stylebook.
This creates a copy of the internal hard-coded style. For example, the default style of FMX.StdCtrls.TPanel is defined simply as:
- panelstyle: TRectangle
The name of the style-resource that defines the style is "panelstyle". It refers to a TRectangle. The appearance of this rectangle can be changed in the Style Designer, and then every TPanel on the form will have that appearance by default.
But there is no rule that a TPanel must be represented by a TRectangle. A TRoundRect or TEllipse would work. Even simple controls can be a complex composition.
Consider FMX.StdCtrls.TCheckBox, which looks something like:
- checkboxstyle: TLayout (the entire control)
- TLayout (the layout for the box)
- background: TRectangle (the box itself, which is actually a composition of:)
- TGlowEffect (glows when the control has focus)
- TRectangle (the outside rectangle that forms the box)
- TRectangle (the inside rectangle)
- TColorAnimation (color animation when the mouse moves over)
- TColorAnimation (and back out)
- checkmark: TPath (the check inside the box, drawn as a path, which has:)
- TColorAnimation (its own color animation when the check is toggled on or off)
- background: TRectangle (the box itself, which is actually a composition of:)
- text: TText (and back under the top level, the text label)
- TLayout (the layout for the box)
The style is named, so that it can be found and used. In addition, certain subelements are named, so that they can be referenced. When the IsChecked property is toggled, the "checkmark" has its visibility changed (by animating the opacity of its color from solid to transparent). Setting the Text property of the TCheckBox sets the Text property of the underlying TText named "text".
Resource Naming and Referencing
Two properties with similar names form the links between a control, its style, and its subcomponents:
- The StyleName is the name by which a style or style subcomponent is known to others and can be found.
- A control's StyleLookup property is set to the name of the desired style-resource to adopt that style for the specific control. When StyleLookUp is empty, the default style is used.
- Subcomponents can be found by calling FindStyleResource with the desired name.
A control has both properties because it can be styled, and it can be a style (or part of one). Simpler components like shapes cannot be styled, and can only be a style element.
Style Resource Storage: TStyleBook
A collection of styles for a form is represented by a TStyleBook object. One of these objects is automatically created if necessary when the FireMonkey Style Designer is opened.
To open the FireMonkey Style Designer:
- Drop a TStyleBook on the form in the Form Designer.
- Double-click the stylebook.
The newly created object is set as the form's StyleBook property, so that it takes effect for the form.
A form may have more than one TStyleBook object. The form's StyleBook property may reference any of them, one at a time; or it can be set to nil
, which causes the form to revert to hard-coded default styles only.
The FireMonkey Style Designer edits the styles for a single TStyleBook at a time. Double-clicking a TStyleBook on a form opens the Style Designer with those styles. The Style Designer can save the TStyleBook in a text format to a .style
file, and can load such a file. The entire set of hard-coded default styles can also be loaded into the Style Designer.
Custom Styles
New styles can be created by modifying default styles, or starting from scratch with a single component.
- To modify a default style, right-click a control on the Form Designer and select Edit Custom Style. The generated style name is derived from the control's name, so you can save a step by choosing a good name for the control first. The generated name is assigned as the control's StyleLookup property, so that it takes effect for that control. The new style is a copy of the control's current style.
- Completely new styles can be created by modifying a
.style
file and loading it, even using components that are not available in the Tool Palette. For example, after saving the current set of styles, edit the file to add before the finalend
:
object TBrushObject
StyleName = 'somebrush'
end
Nested Styles
Styles may refer to other styled components. As always, styles are found by their top-level names in the TStyleBook. For example, to use the same gradient:
- In the FireMonkey Style Designer, save the existing styles in a
.style
file. - Edit the file with a text editor to create a TBrushObject. Use an appropriate StyleName.
- Load the
.style
file. - Select the newly defined style so that it appears in the Object Inspector.
- Open the Brush property:
- Edit the Gradient property with the Brush Designer (choose Edit from the property value's drop-down menu).
- Set the Kind property to
Gradient
.
- For each component using the gradient, for example, with a TRectangle's Fill property:
- Set the Kind property to
Resource
. - Open the Resource property (a TBrushResource) and set the StyleLookup to the name of the gradient in Step 2.
- Set the Kind property to
Style-Resource Search Sequence
To find its style, a control goes through the following approximate sequence, stopping at the first match:
- If the form's StyleBook property is set, that TStyleBook is searched using two names:
- The control's StyleLookup property, if set.
- A default name constructed from the control's class name:
- Drop the first letter (presumed to be the
'T'
prefix of the standard class naming scheme). - Add
'style'
.
- Drop the first letter (presumed to be the
- The hard-coded default styles are searched using three names:
- The control's StyleLookup property, if set.
- The default name constructed from the control's class name.
- A default name constructed from the control's parent class name, using the same steps.
For example, the default names for TPanel are "Panelstyle" and "Controlstyle". For TCalloutPanel, the default names are "CalloutPanelstyle" and "Panelstyle".
Name matching is not case-sensitive. If no match is found, the control has no content and is effectively invisible. The code that depends on finding subcomponents will fail. (That should only happen for incomplete or improperly bundled custom controls, since all built-in controls have corresponding hard-coded styles. Direct descendants of built-in classes would have their base class content; second-generation descendants would be empty.)
Form Style
Although TForm is not a control or subclass of TStyledControl, TForm is styled. Its StyleLookup property defaults to "backgroundstyle". The default style-resource with that StyleName is a grey TRectangle.
When loaded, the Align property of the resource is set to Contents to fill the form as the background. It is the first object painted, before the form's other children.
- Note: If you call the TStyleManager.SetStyle function in the initialization section of a unit on the main project file, before
Application.Initialize
, then the style is applied to all forms.
See Also
- FireMonkey Style Designer
- Bitmap Style Designer (both VCL and FMX)
- Applying FireMonkey Styles
- Editing a FireMonkey Style
- Working with Native and Custom FireMonkey Styles
- Using Styles for iOS: Multi-Resolution Styles, and the Black and Transparent Styles
- Arranging FireMonkey Controls
- Using Menus in a FireMonkey Application
- FireMonkey Primitive Controls and Styled Controls
- Creating a Styled FireMonkey Component by Extending an Existing Component