<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">

	<title type="text">Blog</title>
	<subtitle type="text">Blog:MonkeyStyler blog</subtitle>
	<link rel="alternate" type="text/html" href="/blog" />
	<link rel="self" type="application/atom+xml" href="http://monkeystyler.com/{atom_feed_location}" />
	<updated>2012-05-18T12:59:29Z</updated>
	<rights>Copyright (c) 2012, Mike Sutton</rights>
	<generator uri="http://expressionengine.com/" version="2.3.1">ExpressionEngine</generator>
	<id>tag:,2012:03:25</id>


	<entry>
	  <title>10 Things Every FireMonkey Developer Should Know About Styles</title>
	  <link rel="alternate" type="text/html" href="http://monkeystyler.com/blog/entry/10-things-every-firemonkey-developer-should-know-about-styles" />
	  <id>tag:,2012:/blog/6.27</id>
	  <published>2012-05-06T13:11:18Z</published>
	  <updated>2012-05-06T09:17:19Z</updated>
	  <author>
			<name>Mike Sutton</name>
			<email>mike@solentsoftware.com</email>
				  </author>

	  <category term="Styles"
		scheme="http://monkeystyler.com/news/category/styles"
		label="Styles" />
	  <content type="html"><![CDATA[
		<p>A recent <a href="http://blogs.embarcadero.com/vsevolodleonov/2012/03/12/firemonkey-styles-with-eugene-kryukov-webinar-recording/">Embarcadero webinar video</a> by Eugene Kryukov (FireMonkey designer) and Vsevolod Leonov (FireMonkey evangelist) gives a really good, in depth look at FireMonkey styles and how they work. Here are some tips I distilled down from that video along with a few things I&#8217;ve learn myself.</p>

<p><b>1. How a style name is constructed</b></p>

<p>You&#8217;ll want to know this if you&#8217;re creating custom controls. If you don&#8217;t explicitly state a style name for your control (and you probably don&#8217;t want to) FireMonkey will search for a style based on te class name of your control - it removes the preceding &#8216;T&#8217; and appends &#8216;Style&#8217; to the end.</p>

<p>So, a TButton uses a style &#8216;ButtonStyle&#8217;. A TEdit, &#8216;EditStyle&#8217;, a TCalender &#8216;CalendarStyle&#8217; and so on.</p>

<p><b>2. Style names can also be inherited</b></p>

<p>But if you&#8217;re subclassing a component you may not want to have to create a style for it if you haven&#8217;t modified anything which alters the styling. And if that&#8217;s the case you don&#8217;t need to.</p>

<p>If you create a component:</p><div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">type&nbsp;TEditChild&nbsp;</span><span style="color: #007700">=&nbsp;class(</span><span style="color: #0000BB">TEdit</span><span style="color: #007700">);&nbsp;</span>
</span>
</code></div>
<p>FireMonkey will first look for the style &#8216;EditChildStyle&#8217; (as we saw above). If that doesn&#8217;t exist it will look for the style for the parent class, i.e, it will look for &#8216;EditStyle&#8217; and apply that.</p>

<p><i>But,</i> this doesn&#8217;t apply to grandchildren. If you then create:</p><div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">type&nbsp;TEditGrandchild&nbsp;</span><span style="color: #007700">=&nbsp;class(</span><span style="color: #0000BB">TEditChild</span><span style="color: #007700">);&nbsp;</span>
</span>
</code></div>
<p>FireMonkey will look for &#8216;EditGrandchildStyle&#8217;, then &#8216;EditChildStyle&#8217;, but it will stop there and not go any further up the component tree to &#8216;EditStyle&#8217;.</p>

<p><b>3. Loading default styles</b></p>

<p>The basic look of your application comes from the default style. If you want to change this you need to set the StyleFileName property of your forms Application object (in the FMX.Forms unit):</p><div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">Application</span><span style="color: #007700">.</span><span style="color: #0000BB">StyleFileName&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #DD0000">'C:\Styles\MyStyle.style'</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p>This is best done in your project file, before the line to Application.Initialize.</p>

<p>Ideally there should be some way to set the default style from within your applications project options, or to load it from a resource. Sadly, after much experimentation, I can&#8217;t find a way to do this. If you know better, please comment.</p>

<p><b>4. Where your application gets it&#8217;s styling info</b></p>

<p>As you know you can pop a StyleBook on a form to customise your style. But adding a separate stylebook to each and every form: duplicates data; increases redistributable sizes; is a mainainance nightmare (update every form when you change a style?); just isn&#8217;t DRY.</p>

<p>Much better to create a single master StyleBook on your main form, then link each child&#8217;s stylebook to that on the main form. You can do that with the following in each forms OnCreate event handler:[1]</p><div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">StyleBook&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TForm</span><span style="color: #007700">(</span><span style="color: #0000BB">Application</span><span style="color: #007700">.</span><span style="color: #0000BB">MainForm</span><span style="color: #007700">).</span><span style="color: #0000BB">StyleBook1</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p>Note, however that this doesn&#8217;t work within the form editor. Create a custom control, add it to your child form and it won&#8217;t show the style you have loaded in your main forms StyleBook. I really hope Embarcadero find some kind of workaround for this. Or better yet, improve the style book handling within FireMonkey.</p>

<p><b>5. Set your StyleBook property</b></p>

<p>This gotcha has caught me a few times: You add a StyleBook to your form, change the style within it, set your components StyleLookup property and run your application. And you get the default style.</p>

<p>You should have set the forms StyleBook property to point to the StyleBook. Ouch.</p>

<p>Note that if you right click a control and edit it&#8217;s style, a StyleBook will be created and the StyleBook property will be set, but only if there isn&#8217;t already a StyleBook present. If you create the StyleBook manually, you need to set the StyleBook property yourself.</p>

<p><b>6. You can have multiple StyleBook objects</b></p>

<p>Your form can have multiple StyleBook objects. I figure that explains the behaviour in the above item - FireMonkey doesn&#8217;t want to assume whcih StyleBook to use. Why would you want multiple StyleBooks? I&#8217;m not really sure. The form and the components on it can only use one at a time.</p>

<p><b>7. Styles don&#8217;t have to come from style files</b></p>

<p>So, you know a style can come from the default style, or from a StyleBook, but it can also come from a control on a from. Simply set the StyleName property of a control and set the StyleLookup of another control to match.</p>

<p><b>8. Keep your StyleBooks light</b></p>

<p>The resources in a StyleBook take time up at form create time. For this reason you should keep your StyleBooks to a reasonable size. Instead you should put styling information in your default style (and load it with Application.StyleFileName - see above).</p>

<p>Sadly at the moment there&#8217;s no easy way to merge style files - so you&#8217;ll have to add your custom styling to the (probably Embarcadero supplied) default style and keep the merge up to date.</p>

<p><b>9. Beware the HitTest</b></p>

<p>Add a TImage to a button and you&#8217;ll notice that when the mouse is over the image the functionality of the button will be lost. I.e. mouseovers, clicks etc will be ignored. This is because the TImage is absorbing them. To fix this you needs to set the TImage&#8217;s HitTest property to False. This applies whether you&#8217;re adding controls on a form or in a style file.</p>

<p><b>10. If all else fails, set Locked := True</b></p>

<p>Every FireMonkey control has a Locked property. I&#8217;m not sure what this does. The Embarcadero doesn&#8217;t seem to know what it does either, the <a href="http://docwiki.embarcadero.com/Libraries/en/FMX.Types.TControl.Locked">property reference</a> simply says it locks controls at design time, but <a href="http://docwiki.embarcadero.com/RADStudio/en/FireMonkey_Component_Design">this page</a> says &#8220;Enabling Locked changes the way hit testing works and triggers fire, so that the subcomponent is part of the larger whole.&#8221;. My experience (although somewhat limited in this area) is that if I&#8217;m having problems with mouse clicks going missing fiddling with Locked in association with HitTest (see above) is the best way to resolve things.</p>

<p>[1] An even better way to handle this is to create a custom form class, and set the StyleBook property in an overridden Create constructor. This is left as an exercise for the ready.</p>

<p>&nbsp;</p>
	  ]]></content>
	</entry>

	<entry>
	  <title>MonkeyStyler Build 4 beta</title>
	  <link rel="alternate" type="text/html" href="http://monkeystyler.com/blog/entry/monkeystyler-build-4-beta" />
	  <id>tag:,2012:/blog/6.26</id>
	  <published>2012-05-05T21:12:43Z</published>
	  <updated>2012-05-05T17:13:44Z</updated>
	  <author>
			<name>Mike Sutton</name>
			<email>mike@solentsoftware.com</email>
				  </author>

	  <category term="MonkeyStyler"
		scheme="http://monkeystyler.com/news/category/styler"
		label="MonkeyStyler" />
	  <content type="html"><![CDATA[
		<p>Build 4 beta is now available. Chief changes are improvements to property editors and property editor styling.</p>

<p>Full change list:<br />
Fixed: GradientPointsEditor text values update when gradient points are selected (Update 4 bug? ColorPanel.OnChange is no longer called when value is set programmatically).<br />
Fixed: Added editor for TControl.Position.*<br />
Fixed: R and B values where swapped in text fields of GradientPointsEditor.<br />
Added: Text entry for ColorEditor.<br />
Fixed: GradientPointsEditor gradient updates when changing text fields.<br />
Fixed: Files other than current one not being saved on SaveAll or Close.<br />
Fixed: Alpha value (text edit) updates properly when selecting gradient points (FMX bug workaround).<br />
Added: Property editor styling is slightly better.</p>
	  ]]></content>
	</entry>

	<entry>
	  <title>MonkeyStyler Build 3 Beta</title>
	  <link rel="alternate" type="text/html" href="http://monkeystyler.com/blog/entry/monkeystyler-build-3-beta" />
	  <id>tag:,2012:/blog/6.25</id>
	  <published>2012-04-27T21:15:48Z</published>
	  <updated>2012-04-27T17:15:49Z</updated>
	  <author>
			<name>Mike Sutton</name>
			<email>mike@solentsoftware.com</email>
				  </author>

	  <category term="MonkeyStyler"
		scheme="http://monkeystyler.com/news/category/styler"
		label="MonkeyStyler" />
	  <content type="html"><![CDATA[
		<p>This build adds the ability to create a link to your application and have the styles within it updated with a single click. Read more about this in the <a href="http://monkeystyler.com/wiki/Apply-Styles">wiki</a>.</p>

<p>The full list of changes for this update:<br />
Added: &#8216;Apply&#8217; styles: One click to modify the style of a running FireMonkey application<br />
Added EurekaLog error handling (some bugs with EL and FMX).</p>
	  ]]></content>
	</entry>

	<entry>
	  <title>FireMonkey ListBox With In Place Editing</title>
	  <link rel="alternate" type="text/html" href="http://monkeystyler.com/blog/entry/firemonkey-listbox-with-in-place-editing" />
	  <id>tag:,2012:/blog/6.24</id>
	  <published>2012-04-17T15:25:18Z</published>
	  <updated>2012-04-17T11:26:19Z</updated>
	  <author>
			<name>Mike Sutton</name>
			<email>mike@solentsoftware.com</email>
				  </author>

	  <category term="Coding"
		scheme="http://monkeystyler.com/news/category/coding"
		label="Coding" />
	  <content type="html"><![CDATA[
		<p>I&#8217;ll admit to having a personal bias against modal dialog boxes. They interrupt my workflow and thought process. So, I rather like the way Windows Explorer works when editing a filename - the text changes to an edit box and I can type in the new filename, or simply hit escape and move on.</p>

<p>I saw no reason why I shouldn&#8217;t be able to do the same thing in FireMonkey. A FireMonkey list box is simply a container for other controls, so I reasoned I could simply replace the existing text control with an edit control when the user began an edit, and swap back to the text control when the edit was finished. We&#8217;ll start editing when the user hits F2, finish on pressing the enter key and let users back out by hitting escape.</p>

<p>Here&#8217;s a screenshot of what I came up with:<br />
<img src="http://monkeystyler.com/blogresources/InPlaceEdit1.png" alt=""  /></p>

<p><b>EditListBoxItem</b></p>

<p>A listbox is a container for other controls, but only children of TListBoxItem will actually show up within the list, so first we need to create such a child, we&#8217;ll call it TEditListBoxItem:</p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">type&nbsp;TEditListBoxItem&nbsp;</span><span style="color: #007700">=&nbsp;class(</span><span style="color: #0000BB">TListBoxItem</span><span style="color: #007700">)<br />&nbsp;&nbsp;private<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FEditControl</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TStyledControl</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;SetEditControl</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TStyledControl</span><span style="color: #007700">);<br />&nbsp;&nbsp;protected<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;SetFocus</span><span style="color: #007700">;</span><span style="color: #0000BB">reintroduce</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;SetText</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">String</span><span style="color: #007700">);</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;</span><span style="color: #0000BB">GetText</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">String</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;EVKeyDown</span><span style="color: #007700">(</span><span style="color: #0000BB">Sender</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TObject</span><span style="color: #007700">;&nbsp;var&nbsp;</span><span style="color: #0000BB">Key</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Word</span><span style="color: #007700">;&nbsp;var&nbsp;</span><span style="color: #0000BB">KeyChar</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">WideChar</span><span style="color: #007700">;&nbsp;</span><span style="color: #0000BB">Shift</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TShiftState</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;</span><span style="color: #0000BB">GetData</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Variant</span><span style="color: #007700">;</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;SetData</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Variant</span><span style="color: #007700">);</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;public<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">constructor&nbsp;Create</span><span style="color: #007700">(</span><span style="color: #0000BB">AOwner</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TComponent</span><span style="color: #007700">);</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">destructor&nbsp;Destroy</span><span style="color: #007700">;</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">property&nbsp;Text</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">String&nbsp;read&nbsp;GetText&nbsp;write&nbsp;SetText</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">property&nbsp;EditControl</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TStyledControl&nbsp;read&nbsp;FEditControl&nbsp;write&nbsp;SetEditControl</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>
<p>	<br />
EditControl is the control which will do the editing. I could have explicitly made this a TEdit, but if we use a TSyledControl then users of our code can substitute any suitable control. They could use some kind of date or filtered editor, or one with <a href="http://monkeystyler.com/blog/entry/triggering-effects-and-animations-in-firemonkey-components">validation</a>. Or they could use something completely unrelated to text and text editing.</p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">procedure&nbsp;TEditListBoxItem</span><span style="color: #007700">.</span><span style="color: #0000BB">SetEditControl</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TStyledControl</span><span style="color: #007700">);<br />var&nbsp;</span><span style="color: #0000BB">Data</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Variant</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;</span><span style="color: #0000BB">EditControl&nbsp;</span><span style="color: #007700">&lt;&gt;&nbsp;</span><span style="color: #0000BB">nil&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;Data&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">GetData<br />&nbsp;&nbsp;</span><span style="color: #007700">else<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Data&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">varNull</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FreeAndNil</span><span style="color: #007700">(</span><span style="color: #0000BB">FEditControl</span><span style="color: #007700">);<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FEditControl&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FEditControl</span><span style="color: #007700">.</span><span style="color: #0000BB">Align&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TAlignLayout</span><span style="color: #007700">.</span><span style="color: #0000BB">alClient</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FEditControl</span><span style="color: #007700">.</span><span style="color: #0000BB">Data&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Data</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FEditControl</span><span style="color: #007700">.</span><span style="color: #0000BB">Parent&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Self</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FEditControl</span><span style="color: #007700">.</span><span style="color: #0000BB">OnKeyDown&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">EVKeyDown</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p>We&#8217;re relying on the creator of the list box item to create and assign the edit control. When they do we need to do some setting of properties, as shown above. We need to monitor the OnKeyDown event so we can intercept the Enter and Escape keys to finish editing.</p>

<p>Because we don&#8217;t know that our edit control will be an edit box we can&#8217;t simply read and write the Text property. Fortunately FireMonkey gives us a more generic way of getting and setting content using the Data property. This is a Variant and can read or write any data type as used by the control.</p>

<p>Note in the SetEditControl method above that we took care to preserve the value of any control already in existence by getting the old Data and assigning it to the new Control.</p>

<p>And refer back to the class definition above to see that we override the GetData and SetData methods to get and set data. We also add our own Text property since GetText and SetText aren&#8217;t virtual. Our GetText and SetText simply pass values to and from the edit controls Data property. It&#8217;s a bit redundant in our usage, but adding this functionality should help prevent obscure errors somewhere down the line.</p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #007700">function&nbsp;</span><span style="color: #0000BB">TEditListBoxItem</span><span style="color: #007700">.</span><span style="color: #0000BB">GetData</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Variant</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;</span><span style="color: #0000BB">EditControl&nbsp;</span><span style="color: #007700">&lt;&gt;&nbsp;</span><span style="color: #0000BB">nil&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;Result&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">EditControl</span><span style="color: #007700">.</span><span style="color: #0000BB">Data<br />&nbsp;&nbsp;</span><span style="color: #007700">else<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Result&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">varNull</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br />function&nbsp;</span><span style="color: #0000BB">TEditListBoxItem</span><span style="color: #007700">.</span><span style="color: #0000BB">GetText</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">String</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;Result&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">GetData</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">procedure&nbsp;TEditListBoxItem</span><span style="color: #007700">.</span><span style="color: #0000BB">SetData</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Variant</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;inherited</span><span style="color: #007700">;<br />&nbsp;&nbsp;if&nbsp;</span><span style="color: #0000BB">EditControl&nbsp;</span><span style="color: #007700">&lt;&gt;&nbsp;</span><span style="color: #0000BB">nil&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;EditControl</span><span style="color: #007700">.</span><span style="color: #0000BB">Data&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">procedure&nbsp;TEditListBoxItem</span><span style="color: #007700">.</span><span style="color: #0000BB">SetText</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">String</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;inherited</span><span style="color: #007700">;<br />&nbsp;&nbsp;if&nbsp;</span><span style="color: #0000BB">EditControl&nbsp;</span><span style="color: #007700">&lt;&gt;&nbsp;</span><span style="color: #0000BB">nil&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;EditControl</span><span style="color: #007700">.</span><span style="color: #0000BB">Data&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p><b>TInPlaceEditListBox</b></p>

<p>Now we can move on to the list box itself: </p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">type&nbsp;TInPlaceEditListBox&nbsp;</span><span style="color: #007700">=&nbsp;class(</span><span style="color: #0000BB">TListBox</span><span style="color: #007700">)<br />&nbsp;&nbsp;private<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditItem</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TEditListBoxItem</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditedItem</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TListBoxItem</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditUpdate</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Integer</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FOnCreateEditControl</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TCreateControlEvent</span><span style="color: #007700">;<br />&nbsp;&nbsp;protected<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;KeyDown</span><span style="color: #007700">(var&nbsp;</span><span style="color: #0000BB">Key</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Word</span><span style="color: #007700">;&nbsp;var&nbsp;</span><span style="color: #0000BB">KeyChar</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">System</span><span style="color: #007700">.</span><span style="color: #0000BB">WideChar</span><span style="color: #007700">;&nbsp;</span><span style="color: #0000BB">Shift</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TShiftState</span><span style="color: #007700">);&nbsp;</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;EVEditKeyDown</span><span style="color: #007700">(</span><span style="color: #0000BB">Sender</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TObject</span><span style="color: #007700">;&nbsp;var&nbsp;</span><span style="color: #0000BB">Key</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Word</span><span style="color: #007700">;&nbsp;var&nbsp;</span><span style="color: #0000BB">KeyChar</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">WideChar</span><span style="color: #007700">;&nbsp;</span><span style="color: #0000BB">Shift</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TShiftState</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;SetItemIndex</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Integer</span><span style="color: #007700">);</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;InPlaceEdit</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;EndInPlaceEdit</span><span style="color: #007700">(</span><span style="color: #0000BB">Save</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Boolean</span><span style="color: #007700">);<br />&nbsp;&nbsp;public<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">destructor&nbsp;Destroy</span><span style="color: #007700">;</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;</span><span style="color: #0000BB">CreateEditControl</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TStyledControl</span><span style="color: #007700">;</span><span style="color: #0000BB">virtual</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">property&nbsp;OnCreateEditControl</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TCreateControlEvent&nbsp;read&nbsp;FOnCreateEditControl&nbsp;write&nbsp;FOnCreateEditControl</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p>We&#8217;ll start in the overridden KeyDown method, which simply monitors for the F2 key: </p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">procedure&nbsp;TInPlaceEditListBox</span><span style="color: #007700">.</span><span style="color: #0000BB">KeyDown</span><span style="color: #007700">(var&nbsp;</span><span style="color: #0000BB">Key</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Word</span><span style="color: #007700">;<br />&nbsp;&nbsp;var&nbsp;</span><span style="color: #0000BB">KeyChar</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">System</span><span style="color: #007700">.</span><span style="color: #0000BB">WideChar</span><span style="color: #007700">;&nbsp;</span><span style="color: #0000BB">Shift</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TShiftState</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;</span><span style="color: #0000BB">Key&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">vkF2&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;InPlaceEdit<br />&nbsp;&nbsp;</span><span style="color: #007700">else<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">inherited</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;</span><span style="color: #0000BB">&#91;</span><span style="color: #007700">/</span><span style="color: #0000BB">b&#93;<br /><br />Things&nbsp;get&nbsp;interesting&nbsp;in&nbsp;the&nbsp;inPlaceEdit&nbsp;method</span><span style="color: #007700">:<br /><br /></span><span style="color: #0000BB">&#91;code&#93;procedure&nbsp;TInPlaceEditListBox</span><span style="color: #007700">.</span><span style="color: #0000BB">InPlaceEdit</span><span style="color: #007700">;<br />var<br />&nbsp;&nbsp;</span><span style="color: #0000BB">OldY</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Single</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">Control</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TStyledControl</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;(</span><span style="color: #0000BB">ItemIndex&nbsp;</span><span style="color: #007700">&lt;&nbsp;</span><span style="color: #0000BB">0</span><span style="color: #007700">)&nbsp;</span><span style="color: #0000BB">then<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">EXIT;<br /><br />&nbsp;&nbsp;</span><span style="color: #0000BB">EndInPlaceEdit</span><span style="color: #007700">(</span><span style="color: #0000BB">True</span><span style="color: #007700">);<br /><br />&nbsp;&nbsp;</span><span style="color: #0000BB">OldY&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">VScrollBar</span><span style="color: #007700">.</span><span style="color: #0000BB">Value</span><span style="color: #007700">;<br />&nbsp;&nbsp;try<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Inc</span><span style="color: #007700">(</span><span style="color: #0000BB">EditUpdate</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FreeAndNil</span><span style="color: #007700">(</span><span style="color: #0000BB">EditItem</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditItem&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TEditListBoxItem</span><span style="color: #007700">.</span><span style="color: #0000BB">Create</span><span style="color: #007700">(</span><span style="color: #0000BB">Self</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditItem</span><span style="color: #007700">.</span><span style="color: #0000BB">EditControl&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">CreateEditControl</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditItem</span><span style="color: #007700">.</span><span style="color: #0000BB">OnKeyDown&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">EVEditKeyDown</span><span style="color: #007700">;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">BeginUpdate</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditedItem&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">ListItems&#91;ItemIndex&#93;</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">AddObject</span><span style="color: #007700">(</span><span style="color: #0000BB">EditItem</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Exchange</span><span style="color: #007700">(</span><span style="color: #0000BB">EditedItem</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">EditItem</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditedItem</span><span style="color: #007700">.</span><span style="color: #0000BB">Parent&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">nil</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditItem</span><span style="color: #007700">.</span><span style="color: #0000BB">SetData</span><span style="color: #007700">((</span><span style="color: #0000BB">THackListBoxItem</span><span style="color: #007700">(</span><span style="color: #0000BB">EditedItem</span><span style="color: #007700">)).</span><span style="color: #0000BB">GetData</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditItem</span><span style="color: #007700">.</span><span style="color: #0000BB">SetFocus</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditItem</span><span style="color: #007700">.</span><span style="color: #0000BB">IsSelected&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">True</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">VScrollBar</span><span style="color: #007700">.</span><span style="color: #0000BB">Value&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">OldY</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditItem</span><span style="color: #007700">.</span><span style="color: #0000BB">Opacity&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">0</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EndUpdate</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditItem</span><span style="color: #007700">.</span><span style="color: #0000BB">AnimateFloat</span><span style="color: #007700">(</span><span style="color: #DD0000">'Opacity'</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">1</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">0.2</span><span style="color: #007700">);<br />&nbsp;&nbsp;</span><span style="color: #0000BB">finally<br />&nbsp;&nbsp;&nbsp;&nbsp;dec</span><span style="color: #007700">(</span><span style="color: #0000BB">EditUpdate</span><span style="color: #007700">);<br />&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p>Here we,<br />
* Check we have a valid ItemIndex.<br />
* Stop any exising edits.<br />
* Preserve the scollbar value so we can restore it later.<br />
* EditUpdate is used to prevent some icky side effects (see below).<br />
* We free any existing EditItem (our TEditListBoxItem), create a new one and call CreateEditControl to instantiate the control to go inside it.<br />
* We preserve the existing ListBoxItem into EditedItem, so we can restore it once editing is complete.</p>

<p>Now we need to get our TEditListBoxItem (EditItem) into the list. TListBox has an InsertObject method to insert an item anywhere in the list. Unfortunately a bug in FireMonkey (as of XE2 update 4) means this always fails with an exception. The workaround for this is to call AddObject which adds the item to the end of the list (and is a synonym for setting the Parent property), and then call Exchange with the two items we want to swap.</p>

<p>EditItem (Our new item) is now in the correct place in the list, and EditedItem (the old text item) is now at the end. We can simply null EditedItems Parent property to remove it from the list.</p>

<p>Next comes a line lifted from the dark side, and one I&#8217;m not proud of. Recall our discussion on setting a generic data value through the Data property? What I should have been able to write here is</p><div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">EditItem</span><span style="color: #007700">.</span><span style="color: #0000BB">Data&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">EditedItem</span><span style="color: #007700">.</span><span style="color: #0000BB">Data</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p>But the FireMonkey designers borxed things up in TListBoxItem by adding a fresh Data property of type TObject which, as far as I can see, isn&#8217;t actually used anywhere in FireMonkey.</p>

<p>The workaround is to explicitly call the inherited GetData and SetData methods which aren&#8217;t overridden in TListBoxItem, but they are hidden because they&#8217;re protected and out of scope. We can bring them into scope by creating a do nothing descendant of TListBoxItem (</p><div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">type&nbsp;THackListBoxItem&nbsp;</span><span style="color: #007700">=&nbsp;class(</span><span style="color: #0000BB">TListBoxItem</span><span style="color: #007700">);&nbsp;</span>
</span>
</code></div><p>) in our unit and use some typecasting as shown above to get to the methods. Like I say, nasty but necessary.</p>

<p>After that we can return to sunnier climes. We:<br />
* Give the edit control focus.<br />
* Select the new item, to restore the list boxes ItemIndex property.<br />
* Restore the scrollbar to where it was.<br />
* Animate the opacity property for a pretty effect.</p>

<p><b>Tidying up</b></p>

<p>To handle when the user finishes editing we use the EVKeyDown event handler which monitors for Escape and Enter keys and calls EndInPlaceEdit, which is pretty much a reversed copy of InPlaceEdit: swapping out our editor for whatever was there before and saving (or not) the Data. </p>

<p>There&#8217;s only a couple more things of note.</p>

<p>We override the SetItemIndex method to stop editing if another item is selected (e.g. by a mouse click). Here&#8217;s where our EditUpdate field comes in useful: all that inserting and moving list items around plays havoc with the ItemIndex property and we need to protect against accidentally finishing editing before we&#8217;ve even started.</p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">procedure&nbsp;TInPlaceEditListBox</span><span style="color: #007700">.</span><span style="color: #0000BB">SetItemIndex</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Integer</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;</span><span style="color: #0000BB">EditUpdate&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">0&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;EndInPlaceEdit</span><span style="color: #007700">(</span><span style="color: #0000BB">True</span><span style="color: #007700">);<br />&nbsp;&nbsp;</span><span style="color: #0000BB">inherited</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p>In EVKeyDown we add code to move the editor when the user keys up or down:</p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">procedure&nbsp;TInPlaceEditListBox</span><span style="color: #007700">.</span><span style="color: #0000BB">EVEditKeyDown</span><span style="color: #007700">(</span><span style="color: #0000BB">Sender</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TObject</span><span style="color: #007700">;&nbsp;var&nbsp;</span><span style="color: #0000BB">Key</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Word</span><span style="color: #007700">;<br />&nbsp;&nbsp;var&nbsp;</span><span style="color: #0000BB">KeyChar</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">WideChar</span><span style="color: #007700">;&nbsp;</span><span style="color: #0000BB">Shift</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TShiftState</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;</span><span style="color: #0000BB">EditItem&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">nil&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">EXIT;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;</span><span style="color: #0000BB">Key&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">vkUp&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;</span><span style="color: #0000BB">ItemIndex&nbsp;</span><span style="color: #007700">&gt;&nbsp;</span><span style="color: #0000BB">0&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;begin<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;KeyDown</span><span style="color: #007700">(</span><span style="color: #0000BB">Key</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">KeyChar</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">Shift</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">InPlaceEdit</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">end<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">else<br />&nbsp;&nbsp;else&nbsp;if&nbsp;</span><span style="color: #0000BB">Key&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">vkDown&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;</span><span style="color: #0000BB">ItemIndex&nbsp;</span><span style="color: #007700">&lt;&nbsp;</span><span style="color: #0000BB">Count</span><span style="color: #007700">-</span><span style="color: #0000BB">1&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;begin<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;KeyDown</span><span style="color: #007700">(</span><span style="color: #0000BB">Key</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">KeyChar</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">Shift</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">InPlaceEdit</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p>but we double check ItemIndex can be changed. Otherwise moving up from the first item or down from the last would cause the editor to be recreated and look nasty.</p>

<p>Finally we&#8217;ll look at CreateEditControl which lets developers use their own edit control, or defaults to a TEdit:</p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #007700">function&nbsp;</span><span style="color: #0000BB">TInPlaceEditListBox</span><span style="color: #007700">.</span><span style="color: #0000BB">CreateEditControl</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TStyledControl</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;Result&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">nil</span><span style="color: #007700">;<br />&nbsp;&nbsp;if&nbsp;</span><span style="color: #0000BB">Assigned</span><span style="color: #007700">(</span><span style="color: #0000BB">OnCreateEditControl</span><span style="color: #007700">)&nbsp;</span><span style="color: #0000BB">then<br />&nbsp;&nbsp;&nbsp;&nbsp;OnCreateEditControl</span><span style="color: #007700">(</span><span style="color: #0000BB">Self</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">Result</span><span style="color: #007700">)<br />&nbsp;&nbsp;else<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Result&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TEdit</span><span style="color: #007700">.</span><span style="color: #0000BB">Create</span><span style="color: #007700">(</span><span style="color: #0000BB">Self</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p><b>Back to the list box item</b></p>

<p>Before I leave you in peace I&#8217;ve got something else to show you. Look at the constructor of TEditListBoxItem:</p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">constructor&nbsp;TEditListBoxItem</span><span style="color: #007700">.</span><span style="color: #0000BB">Create</span><span style="color: #007700">(</span><span style="color: #0000BB">AOwner</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TComponent</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;inherited</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">CanClip&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">False</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p>We&#8217;re setting the CanClip property to false. This means that the item and it&#8217;s children can show outside the bounds of it&#8217;s owner (the list box). The first effect of this is that the editors glow effect can show outside the list box. IMHO this simply looks better.</p>

<p><img src="http://monkeystyler.com/blogresources/InPlaceEdit1.png" alt=""  /></p>

<p>The second and potentially more exciting effect is that the editor itself can appear outside the listbox. Imagine the list box contained some potentially long strings but you don&#8217;t want a wide form. The user can now have a compact display but with a nice long edit box when necessary.</p>

<p><img src="http://monkeystyler.com/blogresources/InPlaceEdit2.png" alt=""  /></p>

<p>The code to achieve this is simple, in the list items SetEditControl method simply comment out the line that sets the Align property and set a reasonable width for the edit control:</p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">procedure&nbsp;TEditListBoxItem</span><span style="color: #007700">.</span><span style="color: #0000BB">SetEditControl</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TStyledControl</span><span style="color: #007700">);<br />var&nbsp;</span><span style="color: #0000BB">Data</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Variant</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;</span><span style="color: #0000BB">EditControl&nbsp;</span><span style="color: #007700">&lt;&gt;&nbsp;</span><span style="color: #0000BB">nil&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;Data&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">GetData<br />&nbsp;&nbsp;</span><span style="color: #007700">else<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Data&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">varNull</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FreeAndNil</span><span style="color: #007700">(</span><span style="color: #0000BB">FEditControl</span><span style="color: #007700">);<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FEditControl&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">;<br /></span><span style="color: #FF8000">//&nbsp;&nbsp;FEditControl.Align&nbsp;:=&nbsp;TAlignLayout.alClient;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FEditControl</span><span style="color: #007700">.</span><span style="color: #0000BB">Width&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">200</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FEditControl</span><span style="color: #007700">.</span><span style="color: #0000BB">Data&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Data</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FEditControl</span><span style="color: #007700">.</span><span style="color: #0000BB">Parent&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Self</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FEditControl</span><span style="color: #007700">.</span><span style="color: #0000BB">OnKeyDown&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">EVKeyDown</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p>Download the full source: <a href="http://monkeystyler.com/blogresources/InPlaceEdit.zip"><img src="http://monkeystyler.com/images/uploads/DownloadBtn.jpg" alt=""  /></a></p>

<p>Enjoy, Mike.</p>

<p><b>Full Source</b></p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">unit&nbsp;InPlaceEditList</span><span style="color: #007700">;<br /><br />interface<br /></span><span style="color: #0000BB">uses&nbsp;FMX</span><span style="color: #007700">.</span><span style="color: #0000BB">ListBox</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">System</span><span style="color: #007700">.</span><span style="color: #0000BB">Classes</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">FMX</span><span style="color: #007700">.</span><span style="color: #0000BB">Types</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">FMX</span><span style="color: #007700">.</span><span style="color: #0000BB">Edit</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">type&nbsp;TEditListBoxItem&nbsp;</span><span style="color: #007700">=&nbsp;class(</span><span style="color: #0000BB">TListBoxItem</span><span style="color: #007700">)<br />&nbsp;&nbsp;private<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FEditControl</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TStyledControl</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;SetEditControl</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TStyledControl</span><span style="color: #007700">);<br />&nbsp;&nbsp;protected<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;SetFocus</span><span style="color: #007700">;</span><span style="color: #0000BB">reintroduce</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;SetText</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">String</span><span style="color: #007700">);</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;</span><span style="color: #0000BB">GetText</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">String</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;EVKeyDown</span><span style="color: #007700">(</span><span style="color: #0000BB">Sender</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TObject</span><span style="color: #007700">;&nbsp;var&nbsp;</span><span style="color: #0000BB">Key</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Word</span><span style="color: #007700">;&nbsp;var&nbsp;</span><span style="color: #0000BB">KeyChar</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">WideChar</span><span style="color: #007700">;&nbsp;</span><span style="color: #0000BB">Shift</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TShiftState</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;</span><span style="color: #0000BB">GetData</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Variant</span><span style="color: #007700">;</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;SetData</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Variant</span><span style="color: #007700">);</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;public<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">constructor&nbsp;Create</span><span style="color: #007700">(</span><span style="color: #0000BB">AOwner</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TComponent</span><span style="color: #007700">);</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">destructor&nbsp;Destroy</span><span style="color: #007700">;</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">property&nbsp;Text</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">String&nbsp;read&nbsp;GetText&nbsp;write&nbsp;SetText</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">property&nbsp;EditControl</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TStyledControl&nbsp;read&nbsp;FEditControl&nbsp;write&nbsp;SetEditControl</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">type&nbsp;TCreateControlEvent&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">procedure</span><span style="color: #007700">(</span><span style="color: #0000BB">Sender</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TObject</span><span style="color: #007700">;</span><span style="color: #0000BB">out&nbsp;Control</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TStyledControl</span><span style="color: #007700">)&nbsp;</span><span style="color: #0000BB">of&nbsp;object</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">type&nbsp;TInPlaceEditListBox&nbsp;</span><span style="color: #007700">=&nbsp;class(</span><span style="color: #0000BB">TListBox</span><span style="color: #007700">)<br />&nbsp;&nbsp;private<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditItem</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TEditListBoxItem</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditedItem</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TListBoxItem</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditUpdate</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Integer</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FOnCreateEditControl</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TCreateControlEvent</span><span style="color: #007700">;<br />&nbsp;&nbsp;protected<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;KeyDown</span><span style="color: #007700">(var&nbsp;</span><span style="color: #0000BB">Key</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Word</span><span style="color: #007700">;&nbsp;var&nbsp;</span><span style="color: #0000BB">KeyChar</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">System</span><span style="color: #007700">.</span><span style="color: #0000BB">WideChar</span><span style="color: #007700">;&nbsp;</span><span style="color: #0000BB">Shift</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TShiftState</span><span style="color: #007700">);&nbsp;</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;EVEditKeyDown</span><span style="color: #007700">(</span><span style="color: #0000BB">Sender</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TObject</span><span style="color: #007700">;&nbsp;var&nbsp;</span><span style="color: #0000BB">Key</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Word</span><span style="color: #007700">;&nbsp;var&nbsp;</span><span style="color: #0000BB">KeyChar</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">WideChar</span><span style="color: #007700">;&nbsp;</span><span style="color: #0000BB">Shift</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TShiftState</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;SetItemIndex</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Integer</span><span style="color: #007700">);</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;InPlaceEdit</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;EndInPlaceEdit</span><span style="color: #007700">(</span><span style="color: #0000BB">Save</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Boolean</span><span style="color: #007700">);<br />&nbsp;&nbsp;public<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">destructor&nbsp;Destroy</span><span style="color: #007700">;</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;</span><span style="color: #0000BB">CreateEditControl</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TStyledControl</span><span style="color: #007700">;</span><span style="color: #0000BB">virtual</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">property&nbsp;OnCreateEditControl</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TCreateControlEvent&nbsp;read&nbsp;FOnCreateEditControl&nbsp;write&nbsp;FOnCreateEditControl</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">procedure&nbsp;Register</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">implementation<br />uses&nbsp;System</span><span style="color: #007700">.</span><span style="color: #0000BB">UITypes</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">Sysutils</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">procedure&nbsp;Register</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;RegisterComponents</span><span style="color: #007700">(</span><span style="color: #DD0000">'SolentFMX'</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">&#91;TInPlaceEditListBox&#93;</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">&#123;&nbsp;TEditListBoxItem&nbsp;&#125;<br /><br />constructor&nbsp;TEditListBoxItem</span><span style="color: #007700">.</span><span style="color: #0000BB">Create</span><span style="color: #007700">(</span><span style="color: #0000BB">AOwner</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TComponent</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;inherited</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">CanClip&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">False</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">destructor&nbsp;TEditListBoxItem</span><span style="color: #007700">.</span><span style="color: #0000BB">Destroy</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;FreeAndNil</span><span style="color: #007700">(</span><span style="color: #0000BB">FEditControl</span><span style="color: #007700">);<br />&nbsp;&nbsp;</span><span style="color: #0000BB">inherited</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">procedure&nbsp;TEditListBoxItem</span><span style="color: #007700">.</span><span style="color: #0000BB">EVKeyDown</span><span style="color: #007700">(</span><span style="color: #0000BB">Sender</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TObject</span><span style="color: #007700">;&nbsp;var&nbsp;</span><span style="color: #0000BB">Key</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Word</span><span style="color: #007700">;<br />&nbsp;&nbsp;var&nbsp;</span><span style="color: #0000BB">KeyChar</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">WideChar</span><span style="color: #007700">;&nbsp;</span><span style="color: #0000BB">Shift</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TShiftState</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;</span><span style="color: #0000BB">Assigned</span><span style="color: #007700">(</span><span style="color: #0000BB">OnKeyDown</span><span style="color: #007700">)&nbsp;</span><span style="color: #0000BB">then<br />&nbsp;&nbsp;&nbsp;&nbsp;OnKeyDown</span><span style="color: #007700">(</span><span style="color: #0000BB">Self</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">Key</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">KeyChar</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">Shift</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br />function&nbsp;</span><span style="color: #0000BB">TEditListBoxItem</span><span style="color: #007700">.</span><span style="color: #0000BB">GetData</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Variant</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;</span><span style="color: #0000BB">EditControl&nbsp;</span><span style="color: #007700">&lt;&gt;&nbsp;</span><span style="color: #0000BB">nil&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;Result&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">EditControl</span><span style="color: #007700">.</span><span style="color: #0000BB">Data<br />&nbsp;&nbsp;</span><span style="color: #007700">else<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Result&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">varNull</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br />function&nbsp;</span><span style="color: #0000BB">TEditListBoxItem</span><span style="color: #007700">.</span><span style="color: #0000BB">GetText</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">String</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;Result&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">GetData</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">procedure&nbsp;TEditListBoxItem</span><span style="color: #007700">.</span><span style="color: #0000BB">SetData</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Variant</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;inherited</span><span style="color: #007700">;<br />&nbsp;&nbsp;if&nbsp;</span><span style="color: #0000BB">EditControl&nbsp;</span><span style="color: #007700">&lt;&gt;&nbsp;</span><span style="color: #0000BB">nil&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;EditControl</span><span style="color: #007700">.</span><span style="color: #0000BB">Data&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">procedure&nbsp;TEditListBoxItem</span><span style="color: #007700">.</span><span style="color: #0000BB">SetEditControl</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TStyledControl</span><span style="color: #007700">);<br />var&nbsp;</span><span style="color: #0000BB">Data</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Variant</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;</span><span style="color: #0000BB">EditControl&nbsp;</span><span style="color: #007700">&lt;&gt;&nbsp;</span><span style="color: #0000BB">nil&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;Data&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">GetData<br />&nbsp;&nbsp;</span><span style="color: #007700">else<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Data&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">varNull</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FreeAndNil</span><span style="color: #007700">(</span><span style="color: #0000BB">FEditControl</span><span style="color: #007700">);<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FEditControl&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FEditControl</span><span style="color: #007700">.</span><span style="color: #0000BB">Align&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TAlignLayout</span><span style="color: #007700">.</span><span style="color: #0000BB">alClient</span><span style="color: #007700">;<br /></span><span style="color: #FF8000">//&nbsp;&nbsp;FEditControl.Width&nbsp;:=&nbsp;200;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FEditControl</span><span style="color: #007700">.</span><span style="color: #0000BB">Data&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Data</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FEditControl</span><span style="color: #007700">.</span><span style="color: #0000BB">Parent&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Self</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FEditControl</span><span style="color: #007700">.</span><span style="color: #0000BB">OnKeyDown&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">EVKeyDown</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">procedure&nbsp;TEditListBoxItem</span><span style="color: #007700">.</span><span style="color: #0000BB">SetFocus</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;inherited</span><span style="color: #007700">;<br />&nbsp;&nbsp;if&nbsp;</span><span style="color: #0000BB">FEditControl&nbsp;</span><span style="color: #007700">&lt;&gt;&nbsp;</span><span style="color: #0000BB">nil&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;FEditControl</span><span style="color: #007700">.</span><span style="color: #0000BB">SetFocus</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">procedure&nbsp;TEditListBoxItem</span><span style="color: #007700">.</span><span style="color: #0000BB">SetText</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">String</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;inherited</span><span style="color: #007700">;<br />&nbsp;&nbsp;if&nbsp;</span><span style="color: #0000BB">EditControl&nbsp;</span><span style="color: #007700">&lt;&gt;&nbsp;</span><span style="color: #0000BB">nil&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;EditControl</span><span style="color: #007700">.</span><span style="color: #0000BB">Data&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">&#123;&nbsp;TInPlaceEditListBox&nbsp;&#125;<br /><br /></span><span style="color: #007700">function&nbsp;</span><span style="color: #0000BB">TInPlaceEditListBox</span><span style="color: #007700">.</span><span style="color: #0000BB">CreateEditControl</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TStyledControl</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;Result&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">nil</span><span style="color: #007700">;<br />&nbsp;&nbsp;if&nbsp;</span><span style="color: #0000BB">Assigned</span><span style="color: #007700">(</span><span style="color: #0000BB">OnCreateEditControl</span><span style="color: #007700">)&nbsp;</span><span style="color: #0000BB">then<br />&nbsp;&nbsp;&nbsp;&nbsp;OnCreateEditControl</span><span style="color: #007700">(</span><span style="color: #0000BB">Self</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">Result</span><span style="color: #007700">)<br />&nbsp;&nbsp;else<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Result&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TEdit</span><span style="color: #007700">.</span><span style="color: #0000BB">Create</span><span style="color: #007700">(</span><span style="color: #0000BB">Self</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">destructor&nbsp;TInPlaceEditListBox</span><span style="color: #007700">.</span><span style="color: #0000BB">Destroy</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;FreeAndNil</span><span style="color: #007700">(</span><span style="color: #0000BB">EditItem</span><span style="color: #007700">);<br />&nbsp;&nbsp;</span><span style="color: #0000BB">inherited</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">type&nbsp;THackListBoxItem&nbsp;</span><span style="color: #007700">=&nbsp;class(</span><span style="color: #0000BB">TListBoxItem</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">procedure&nbsp;TInPlaceEditListBox</span><span style="color: #007700">.</span><span style="color: #0000BB">EndInPlaceEdit</span><span style="color: #007700">(</span><span style="color: #0000BB">Save</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Boolean</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;(</span><span style="color: #0000BB">EditItem&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">nil</span><span style="color: #007700">)&nbsp;or&nbsp;(</span><span style="color: #0000BB">EditedItem&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">nil</span><span style="color: #007700">)&nbsp;</span><span style="color: #0000BB">then<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">EXIT;<br /><br />&nbsp;&nbsp;try<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Inc</span><span style="color: #007700">(</span><span style="color: #0000BB">EditUpdate</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">BeginUpdate</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;</span><span style="color: #0000BB">Save&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;THackListBoxItem</span><span style="color: #007700">(</span><span style="color: #0000BB">EditedItem</span><span style="color: #007700">).</span><span style="color: #0000BB">SetData</span><span style="color: #007700">((</span><span style="color: #0000BB">EditItem</span><span style="color: #007700">).</span><span style="color: #0000BB">GetData</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">AddObject</span><span style="color: #007700">(</span><span style="color: #0000BB">EditedItem</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Exchange</span><span style="color: #007700">(</span><span style="color: #0000BB">EditItem</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">EditedItem</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditedItem</span><span style="color: #007700">.</span><span style="color: #0000BB">IsSelected&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">True</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FreeAndNil</span><span style="color: #007700">(</span><span style="color: #0000BB">EditItem</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">SetFocus</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditedItem</span><span style="color: #007700">.</span><span style="color: #0000BB">Opacity&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">0</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EndUpdate</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditedItem</span><span style="color: #007700">.</span><span style="color: #0000BB">AnimateFloat</span><span style="color: #007700">(</span><span style="color: #DD0000">'Opacity'</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">1</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">0.2</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditedItem&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">nil</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">finally<br />&nbsp;&nbsp;&nbsp;&nbsp;dec</span><span style="color: #007700">(</span><span style="color: #0000BB">EditUpdate</span><span style="color: #007700">);<br />&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">procedure&nbsp;TInPlaceEditListBox</span><span style="color: #007700">.</span><span style="color: #0000BB">EVEditKeyDown</span><span style="color: #007700">(</span><span style="color: #0000BB">Sender</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TObject</span><span style="color: #007700">;&nbsp;var&nbsp;</span><span style="color: #0000BB">Key</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Word</span><span style="color: #007700">;<br />&nbsp;&nbsp;var&nbsp;</span><span style="color: #0000BB">KeyChar</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">WideChar</span><span style="color: #007700">;&nbsp;</span><span style="color: #0000BB">Shift</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TShiftState</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;</span><span style="color: #0000BB">EditItem&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">nil&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">EXIT;<br /><br />&nbsp;&nbsp;if&nbsp;</span><span style="color: #0000BB">Key&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">vkReturn&nbsp;then<br />&nbsp;&nbsp;begin<br />&nbsp;&nbsp;&nbsp;&nbsp;EndInPlaceEdit</span><span style="color: #007700">(</span><span style="color: #0000BB">True</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Key&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">0</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">end<br />&nbsp;&nbsp;</span><span style="color: #007700">else&nbsp;if&nbsp;</span><span style="color: #0000BB">Key&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">vkEscape&nbsp;then<br />&nbsp;&nbsp;begin<br />&nbsp;&nbsp;&nbsp;&nbsp;EndInPlaceEdit</span><span style="color: #007700">(</span><span style="color: #0000BB">False</span><span style="color: #007700">);<br />&nbsp;&nbsp;</span><span style="color: #0000BB">end<br />&nbsp;&nbsp;</span><span style="color: #007700">else&nbsp;if&nbsp;</span><span style="color: #0000BB">Key&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">vkUp&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;</span><span style="color: #0000BB">ItemIndex&nbsp;</span><span style="color: #007700">&gt;&nbsp;</span><span style="color: #0000BB">0&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;begin<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;KeyDown</span><span style="color: #007700">(</span><span style="color: #0000BB">Key</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">KeyChar</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">Shift</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">InPlaceEdit</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">end<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">else<br />&nbsp;&nbsp;else&nbsp;if&nbsp;</span><span style="color: #0000BB">Key&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">vkDown&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;</span><span style="color: #0000BB">ItemIndex&nbsp;</span><span style="color: #007700">&lt;&nbsp;</span><span style="color: #0000BB">Count</span><span style="color: #007700">-</span><span style="color: #0000BB">1&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;begin<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;KeyDown</span><span style="color: #007700">(</span><span style="color: #0000BB">Key</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">KeyChar</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">Shift</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">InPlaceEdit</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">procedure&nbsp;TInPlaceEditListBox</span><span style="color: #007700">.</span><span style="color: #0000BB">InPlaceEdit</span><span style="color: #007700">;<br />var<br />&nbsp;&nbsp;</span><span style="color: #0000BB">OldY</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Single</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">Control</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TStyledControl</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;(</span><span style="color: #0000BB">ItemIndex&nbsp;</span><span style="color: #007700">&lt;&nbsp;</span><span style="color: #0000BB">0</span><span style="color: #007700">)&nbsp;</span><span style="color: #0000BB">then<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">EXIT;<br /><br />&nbsp;&nbsp;</span><span style="color: #0000BB">EndInPlaceEdit</span><span style="color: #007700">(</span><span style="color: #0000BB">True</span><span style="color: #007700">);<br /><br />&nbsp;&nbsp;</span><span style="color: #0000BB">OldY&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">VScrollBar</span><span style="color: #007700">.</span><span style="color: #0000BB">Value</span><span style="color: #007700">;<br />&nbsp;&nbsp;try<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Inc</span><span style="color: #007700">(</span><span style="color: #0000BB">EditUpdate</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FreeAndNil</span><span style="color: #007700">(</span><span style="color: #0000BB">EditItem</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditItem&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TEditListBoxItem</span><span style="color: #007700">.</span><span style="color: #0000BB">Create</span><span style="color: #007700">(</span><span style="color: #0000BB">Self</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditItem</span><span style="color: #007700">.</span><span style="color: #0000BB">EditControl&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">CreateEditControl</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditItem</span><span style="color: #007700">.</span><span style="color: #0000BB">OnKeyDown&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">EVEditKeyDown</span><span style="color: #007700">;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">BeginUpdate</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">AddObject</span><span style="color: #007700">(</span><span style="color: #0000BB">EditItem</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditedItem&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">ListItems&#91;ItemIndex&#93;</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Exchange</span><span style="color: #007700">(</span><span style="color: #0000BB">EditedItem</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">EditItem</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditedItem</span><span style="color: #007700">.</span><span style="color: #0000BB">Parent&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">nil</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditItem</span><span style="color: #007700">.</span><span style="color: #0000BB">SetData</span><span style="color: #007700">((</span><span style="color: #0000BB">THackListBoxItem</span><span style="color: #007700">(</span><span style="color: #0000BB">EditedItem</span><span style="color: #007700">)).</span><span style="color: #0000BB">GetData</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditItem</span><span style="color: #007700">.</span><span style="color: #0000BB">SetFocus</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditItem</span><span style="color: #007700">.</span><span style="color: #0000BB">IsSelected&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">True</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">VScrollBar</span><span style="color: #007700">.</span><span style="color: #0000BB">Value&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">OldY</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditItem</span><span style="color: #007700">.</span><span style="color: #0000BB">Opacity&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">0</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EndUpdate</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">EditItem</span><span style="color: #007700">.</span><span style="color: #0000BB">AnimateFloat</span><span style="color: #007700">(</span><span style="color: #DD0000">'Opacity'</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">1</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">0.2</span><span style="color: #007700">);<br />&nbsp;&nbsp;</span><span style="color: #0000BB">finally<br />&nbsp;&nbsp;&nbsp;&nbsp;dec</span><span style="color: #007700">(</span><span style="color: #0000BB">EditUpdate</span><span style="color: #007700">);<br />&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">procedure&nbsp;TInPlaceEditListBox</span><span style="color: #007700">.</span><span style="color: #0000BB">KeyDown</span><span style="color: #007700">(var&nbsp;</span><span style="color: #0000BB">Key</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Word</span><span style="color: #007700">;<br />&nbsp;&nbsp;var&nbsp;</span><span style="color: #0000BB">KeyChar</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">System</span><span style="color: #007700">.</span><span style="color: #0000BB">WideChar</span><span style="color: #007700">;&nbsp;</span><span style="color: #0000BB">Shift</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TShiftState</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;</span><span style="color: #0000BB">Key&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">vkF2&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;InPlaceEdit<br />&nbsp;&nbsp;</span><span style="color: #007700">else<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">inherited</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">procedure&nbsp;TInPlaceEditListBox</span><span style="color: #007700">.</span><span style="color: #0000BB">SetItemIndex</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Integer</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;</span><span style="color: #0000BB">EditUpdate&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">0&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;EndInPlaceEdit</span><span style="color: #007700">(</span><span style="color: #0000BB">True</span><span style="color: #007700">);<br />&nbsp;&nbsp;</span><span style="color: #0000BB">inherited</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">initialization<br />&nbsp;&nbsp;RegisterFMXClasses</span><span style="color: #007700">(</span><span style="color: #0000BB">&#91;TInPlaceEditListBox</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">TEditListBoxItem&#93;</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">.&nbsp;</span>
</span>
</code></div>
	  ]]></content>
	</entry>

	<entry>
	  <title>MonkeyStyler build 2 beta</title>
	  <link rel="alternate" type="text/html" href="http://monkeystyler.com/blog/entry/monkeystyler-build-2-beta" />
	  <id>tag:,2012:/blog/6.23</id>
	  <published>2012-04-16T20:39:44Z</published>
	  <updated>2012-04-16T16:41:45Z</updated>
	  <author>
			<name>Mike Sutton</name>
			<email>mike@solentsoftware.com</email>
				  </author>

	  <content type="html"><![CDATA[
		<p>MonkeyStyler build 2 beta is now available. If you&#8217;re on the beta programme, use the link you already have to download.</p>

<p><b>Changes list</b></p>

<p>Added: Tooltips for toolbar buttons.<br />
Fix: Error message popups now size properly on first showing.<br />
Fix: Warnings for duplicate element names are no longer case sensitive.<br />
Improved: validation of element names when adding, renaming or copying elements.<br />
Added: Pasting a component switches the property editor to the pasted component.<br />
Fix: Stepping of values now works for TAngleEditor (ie values in steps of 3 etc.)<br />
Added: Copy To dialog remembers it&#8217;s settings between shows (not between sessions).<br />
Added: Property grid scrolls up if necessary when expanding items.</p>
	  ]]></content>
	</entry>

	<entry>
	  <title>Call for Beta Testers</title>
	  <link rel="alternate" type="text/html" href="http://monkeystyler.com/blog/entry/call-for-beta-testers" />
	  <id>tag:,2012:/blog/6.22</id>
	  <published>2012-03-27T21:07:46Z</published>
	  <updated>2012-03-27T17:08:47Z</updated>
	  <author>
			<name>Mike Sutton</name>
			<email>mike@solentsoftware.com</email>
				  </author>

	  <category term="MonkeyStyler"
		scheme="http://monkeystyler.com/news/category/styler"
		label="MonkeyStyler" />
	  <content type="html"><![CDATA[
		<p>MonkeyStyler is almost ready ... or at least almost ready for it&#8217;s debut. There&#8217;s still to do: fleshing out some areas of the product (i.e. property editors); one or two features still to be added; A few minor touches which really need to be added; And a whole load of wonderful time saving features to be added after public release.</p>

<p>But MonkeyStyler is feature complete enough to have a beta release. I&#8217;m now working on the installer and those other little bits needed by a public product.</p>

<p>If you want to be among the first to try MonkeyStyler out you need to act now. I need a small number of volunteers for the beta test. If you&#8217;re interested, drop me an email to <a href="mailto:monkey@solentsoftware.com">monkey@solentsoftware.com</a>. Remember places are limited.</p>

<p>Enjoy.</p>

<p>Mike</p>
	  ]]></content>
	</entry>

	<entry>
	  <title>Triggering Effects and Animations in FireMonkey Components</title>
	  <link rel="alternate" type="text/html" href="http://monkeystyler.com/blog/entry/triggering-effects-and-animations-in-firemonkey-components" />
	  <id>tag:,2012:/blog/6.21</id>
	  <published>2012-03-25T12:06:28Z</published>
	  <updated>2012-05-18T12:59:29Z</updated>
	  <author>
			<name>Mike Sutton</name>
			<email>mike@solentsoftware.com</email>
				  </author>

	  <category term="Coding"
		scheme="http://monkeystyler.com/news/category/coding"
		label="Coding" />
	  <category term="Styles"
		scheme="http://monkeystyler.com/news/category/styles"
		label="Styles" />
	  <content type="html"><![CDATA[
		<p>If you&#8217;ve used FireMonkey styles, you&#8217;ve probably got used to using triggers to initiate animations and effects. I.e. setting a TColorAnamation when IsMouseOver = True and triggering a TGlowEffect when IsFocused = True. But if you&#8217;re creating your own components, how do you create triggers which you and others can use to style your component? That&#8217;s what we&#8217;re going to look at today.</p>

<p>Below is a form with two TEdit controls. I&#8217;ve coded them to show basic password validation. The first box shows a red background if the password is not secure enough (less that six characters here), the second shows a TInnerGlowEffect under the same conditions. Both boxes show clear when the password is adequate (see the second screenshot).</p>

<p><img src="http://monkeystyler.com/blogresources/ValidateEdit1.png" alt=""  /></p>

<p><img src="http://monkeystyler.com/blogresources/ValidateEdit2.png" alt=""  /></p>

<p><b>TValidateEdit</b></p>

<p>I started by subclassing TEdit as follows to create a generic edit box with validation. Validation is done by calling the OnValidate event:</p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">type&nbsp;TValidateEvent&nbsp;</span><span style="color: #007700">=&nbsp;function(</span><span style="color: #0000BB">Sender</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TObject</span><span style="color: #007700">;const&nbsp;</span><span style="color: #0000BB">Text</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">String</span><span style="color: #007700">):&nbsp;</span><span style="color: #0000BB">Boolean&nbsp;of&nbsp;object</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">type&nbsp;TValidateEdit&nbsp;</span><span style="color: #007700">=&nbsp;class(</span><span style="color: #0000BB">TEdit</span><span style="color: #007700">)<br />&nbsp;&nbsp;private<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FIsInvalid</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Boolean</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FOnValidate</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TValidateEvent</span><span style="color: #007700">;<br />&nbsp;&nbsp;protected<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;ApplyStyle</span><span style="color: #007700">;</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;KeyDown</span><span style="color: #007700">(var&nbsp;</span><span style="color: #0000BB">Key</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Word</span><span style="color: #007700">;&nbsp;var&nbsp;</span><span style="color: #0000BB">KeyChar</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">System</span><span style="color: #007700">.</span><span style="color: #0000BB">WideChar</span><span style="color: #007700">;&nbsp;</span><span style="color: #0000BB">Shift</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TShiftState</span><span style="color: #007700">);&nbsp;</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;DoIsValid</span><span style="color: #007700">;</span><span style="color: #0000BB">virtual</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">published<br />&nbsp;&nbsp;&nbsp;&nbsp;property&nbsp;IsInvalid</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Boolean&nbsp;read&nbsp;FIsInvalid</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">property&nbsp;OnValidate</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TValidateEvent&nbsp;read&nbsp;FOnValidate&nbsp;write&nbsp;FOnValidate</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>
<p>	<br />
	The first thing to notice is our trigger property, IsInvalid. As with the triggers you&#8217;ve already seen it starts with &#8216;Is&#8217;. This is <i>not</i> a requirement, but it <i>is</i> a convention, and one you would do well to keep to, just like you start your types with a T. Following the convention means that you and others will instantly know which propetries can be used as triggers. This is important since controls with trigger properties have special code to enable the property to be used as a trigger. Other than the naming convention there is nothing special about the declaration of trigger properties.</p>

<p>Now, lets take a run through the code and see how things work. First up is our overridden KeyDown method.</p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">procedure&nbsp;TValidateEdit</span><span style="color: #007700">.</span><span style="color: #0000BB">KeyDown</span><span style="color: #007700">(var&nbsp;</span><span style="color: #0000BB">Key</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Word</span><span style="color: #007700">;&nbsp;var&nbsp;</span><span style="color: #0000BB">KeyChar</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">System</span><span style="color: #007700">.</span><span style="color: #0000BB">WideChar</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">Shift</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TShiftState</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;inherited</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">DoIsValid</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p>All we do here is call DoIsValid to check whether the new content is valid.</p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">procedure&nbsp;TValidateEdit</span><span style="color: #007700">.</span><span style="color: #0000BB">ApplyStyle</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;inherited</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">DoIsValid</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p>We need to override ApplyStyle and call DoIsValid so that IsInvalid will be set properly at startup and if the style is ever reloaded. In our case this means that when the password editor is created, and therefore empty, it will show as invalid.</p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">procedure&nbsp;TValidateEdit</span><span style="color: #007700">.</span><span style="color: #0000BB">DoIsValid</span><span style="color: #007700">;<br />var&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Boolean</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;</span><span style="color: #0000BB">Assigned</span><span style="color: #007700">(</span><span style="color: #0000BB">OnValidate</span><span style="color: #007700">)&nbsp;</span><span style="color: #0000BB">then<br />&nbsp;&nbsp;begin<br />&nbsp;&nbsp;&nbsp;&nbsp;Value&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">not&nbsp;OnValidate</span><span style="color: #007700">(</span><span style="color: #0000BB">Self</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">Text</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FIsInvalid&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">StartTriggerAnimation</span><span style="color: #007700">(</span><span style="color: #0000BB">Self</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">'IsInvalid'</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">ApplyTriggerEffect</span><span style="color: #007700">(</span><span style="color: #0000BB">Self</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">'IsInvalid'</span><span style="color: #007700">);<br />&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p>And finally on to the meat of our code, DoIsValid. First we call the onIsValidate event handler and set FIsInvalid. All bog standard stuff.</p>

<p>Following that are the two lines which do the work:</p><div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">StartTriggerAnimation</span><span style="color: #007700">(</span><span style="color: #0000BB">Self</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">'IsInvalid'</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">ApplyTriggerEffect</span><span style="color: #007700">(</span><span style="color: #0000BB">Self</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">'IsInvalid'</span><span style="color: #007700">);&nbsp;</span>
</span>
</code></div>
<p>		<br />
These are two standard methods of TFMXObject (a parent of all FireMonkey objects). StartTriggerAnimation starts any appropriate animations. ApplyTriggerEffect shows or hides any appropriate effects.</p>

<p>Both methods look through the child objects for effects and animations to trigger. These can be animations and effects in the control&#8217;s style, or those added directly to the control either at deisgn time or run time.</p>

<p>The first parameter is AInstance (of type TFMXObject). This is the object which contains the trigger property. Here we&#8217;re passing Self, but you could just as easily pass in another control with a trigger property. For example you could change a property of another control, and then trigger an animation in your own style based on that controls state.</p>

<p>Finally we have the trigger property itself. This takes the name of a property as a string. The property must be a boolean. Refer to the discussion above about naming conventions, but also keep in mind the previous paragraph: you could start an animation based on any boolean property on any object. But if you do this, note that the animation will <i>not</i> get updated when that property is changed unless you explicitly do it yourself. Caveat emptor.</p>

<p><b>Styling</b></p>

<p>Here is the style using animations, a straight copy of the EditStyle to which I added two animations, one to initiate the animation, the second to clear it:</p>

<p><img src="http://monkeystyler.com/blogresources/ValidateEdit3.png" alt=""  /></p>

<p>And the properties for the first animation:</p>

<p><img src="http://monkeystyler.com/blogresources/ValidateEdit4.png" alt=""  /></p>

<p>Here we have the StartValue and StopValue and the Trigger (IsInvalid=True). The second animation is simply the reverse. Note however that we also have StartFromCurrent=True. If this is not set then each time we call the StartTriggerAnimation function the animation will change to the StartValue and animate to the StopValue. In our case that means that each time we type a character the background would turn white, then fade to red. Not what we want. Starting from the current value stops this (It starts at red and stays there).</p>

<p>Prior to XE2 Update 4 I noticed a bug with this behaviour. Under some circumstances the animation would switch immediately to the StopValue, rather than animating. To get around this I changed DoIsValid so that the animations would only run if the trigger property had actually changed:</p><div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">procedure&nbsp;TValidateEdit</span><span style="color: #007700">.</span><span style="color: #0000BB">DoIsValid</span><span style="color: #007700">;<br />var&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Boolean</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;</span><span style="color: #0000BB">Assigned</span><span style="color: #007700">(</span><span style="color: #0000BB">OnValidate</span><span style="color: #007700">)&nbsp;</span><span style="color: #0000BB">then<br />&nbsp;&nbsp;begin<br />&nbsp;&nbsp;&nbsp;&nbsp;Value&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">not&nbsp;OnValidate</span><span style="color: #007700">(</span><span style="color: #0000BB">Self</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">Text</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;</span><span style="color: #0000BB">Value&nbsp;</span><span style="color: #007700">&lt;&gt;&nbsp;</span><span style="color: #0000BB">FIsInvalid&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;begin<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FIsInvalid&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">StartTriggerAnimation</span><span style="color: #007700">(</span><span style="color: #0000BB">Self</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">'IsInvalid'</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">ApplyTriggerEffect</span><span style="color: #007700">(</span><span style="color: #0000BB">Self</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">'IsInvalid'</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p>Now that this is fixed with Update 4, you have a choice of using either technique.</p>

<p><b>Styling for effects</b></p>

<p>Here is the style for the version which uses an effect, with the newly added TInnerGlowEffect highlighted:</p>

<p><img src="http://monkeystyler.com/blogresources/ValidateEdit5.png" alt=""  /></p>

<p>The only thing to note here is that the effect must be added as a child of the object in which we want the effect to appear, the background rectangle here. I first created this code under XE2 Update 3 and added the effect as a child of the main TLayout and it worked fine. This no longer applied under Update 4: hence it&#8217;s current placement.</p>

<p><b>Round up</b></p>

<p>And that&#8217;s all there is to it. Just remember that you can be incredibly creative with FireMonkey styles. Instead of changing the background of the TEdit I could have added an image and had it change from a cross to a tick. I could have added some text (&#8216;Password too short&#8217;) either below or beside the edit box and changed it&#8217;s opacity. The beauty with FireMonkey is that once I&#8217;ve added the trigger property you (or your designer) are free to be really creative with how that trigger affects the styling.</p>

<p><a href="http://monkeystyler.com/blogresources/ValidateEdit.zip">Download sources</a></p>

<p>Full source of ValidateEdit unit: </p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">unit&nbsp;uValidateEdit</span><span style="color: #007700">;<br /><br />interface<br /></span><span style="color: #0000BB">uses&nbsp;FMX</span><span style="color: #007700">.</span><span style="color: #0000BB">Edit</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">System</span><span style="color: #007700">.</span><span style="color: #0000BB">Classes</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">type&nbsp;TValidateEvent&nbsp;</span><span style="color: #007700">=&nbsp;function(</span><span style="color: #0000BB">Sender</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TObject</span><span style="color: #007700">;const&nbsp;</span><span style="color: #0000BB">Text</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">String</span><span style="color: #007700">):&nbsp;</span><span style="color: #0000BB">Boolean&nbsp;of&nbsp;object</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">type&nbsp;TValidateEdit&nbsp;</span><span style="color: #007700">=&nbsp;class(</span><span style="color: #0000BB">TEdit</span><span style="color: #007700">)<br />&nbsp;&nbsp;private<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FIsInvalid</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Boolean</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FOnValidate</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TValidateEvent</span><span style="color: #007700">;<br />&nbsp;&nbsp;protected<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;ApplyStyle</span><span style="color: #007700">;</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;KeyDown</span><span style="color: #007700">(var&nbsp;</span><span style="color: #0000BB">Key</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Word</span><span style="color: #007700">;&nbsp;var&nbsp;</span><span style="color: #0000BB">KeyChar</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">System</span><span style="color: #007700">.</span><span style="color: #0000BB">WideChar</span><span style="color: #007700">;&nbsp;</span><span style="color: #0000BB">Shift</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TShiftState</span><span style="color: #007700">);&nbsp;</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;DoIsValid</span><span style="color: #007700">;</span><span style="color: #0000BB">virtual</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">published<br />&nbsp;&nbsp;&nbsp;&nbsp;property&nbsp;IsInvalid</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Boolean&nbsp;read&nbsp;FIsInvalid</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">property&nbsp;OnValidate</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TValidateEvent&nbsp;read&nbsp;FOnValidate&nbsp;write&nbsp;FOnValidate</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">implementation<br />uses&nbsp;System</span><span style="color: #007700">.</span><span style="color: #0000BB">UITypes</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">&#123;&nbsp;TValidateEdit&nbsp;&#125;<br /><br />procedure&nbsp;TValidateEdit</span><span style="color: #007700">.</span><span style="color: #0000BB">ApplyStyle</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;inherited</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">DoIsValid</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">procedure&nbsp;TValidateEdit</span><span style="color: #007700">.</span><span style="color: #0000BB">DoIsValid</span><span style="color: #007700">;<br />var&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Boolean</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;</span><span style="color: #0000BB">Assigned</span><span style="color: #007700">(</span><span style="color: #0000BB">OnValidate</span><span style="color: #007700">)&nbsp;</span><span style="color: #0000BB">then<br />&nbsp;&nbsp;begin<br />&nbsp;&nbsp;&nbsp;&nbsp;Value&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">not&nbsp;OnValidate</span><span style="color: #007700">(</span><span style="color: #0000BB">Self</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">Text</span><span style="color: #007700">);<br /></span><span style="color: #FF8000">//&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;Value&nbsp;&lt;&gt;&nbsp;FIsInvalid&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FIsInvalid&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">StartTriggerAnimation</span><span style="color: #007700">(</span><span style="color: #0000BB">Self</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">'IsInvalid'</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">ApplyTriggerEffect</span><span style="color: #007700">(</span><span style="color: #0000BB">Self</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">'IsInvalid'</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">procedure&nbsp;TValidateEdit</span><span style="color: #007700">.</span><span style="color: #0000BB">KeyDown</span><span style="color: #007700">(var&nbsp;</span><span style="color: #0000BB">Key</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Word</span><span style="color: #007700">;&nbsp;var&nbsp;</span><span style="color: #0000BB">KeyChar</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">System</span><span style="color: #007700">.</span><span style="color: #0000BB">WideChar</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">Shift</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TShiftState</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;inherited</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">DoIsValid</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">end</span><span style="color: #007700">.&nbsp;</span>
</span>
</code></div>
<p>s opacity. The beauty with FireMonkey is that once I</p>
	  ]]></content>
	</entry>

	<entry>
	  <title>Anatomy of a FireMonkey Style</title>
	  <link rel="alternate" type="text/html" href="http://monkeystyler.com/blog/entry/anatomy-of-a-firemonkey-style" />
	  <id>tag:,2012:/blog/6.20</id>
	  <published>2012-03-18T12:54:50Z</published>
	  <updated>2012-03-18T08:57:51Z</updated>
	  <author>
			<name>Mike Sutton</name>
			<email>mike@solentsoftware.com</email>
				  </author>

	  <category term="Styles"
		scheme="http://monkeystyler.com/news/category/styles"
		label="Styles" />
	  <content type="html"><![CDATA[
		<p>FireMonkey styles have a similar relationship to controls as CSS styles have to tags in a HTML file. The control handles the functionality of the application. The style tells FireMonkey how the control should look. Styles not only specify colors, border styles and fonts, but they can specify everything about the appearance. For example a style could move the button of a TComboBox from right to left and make it&#8217;s text right-aligned.</p>

<p>Style elements are made up of <em>components</em> in the same way that your application is also made up of components. Indeed, the same components that are available in the component palette are also available in styles, although most of the components you will use are made up from the more &#8216;primitive&#8217; components - shapes (TRectangle, TCircle, TPath) etc., animations and effects as well as TLayout and TText.</p>

<p><b>A typical style</b></p>

<p>Lets take a look at a typical FireMonkey style. The following is the component tree for a TButton in the windows 7 style:</p><div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">buttonstyle</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TLayout<br />&nbsp;&nbsp;background</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TRectangle<br />&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;TRectangle<br />&nbsp;&nbsp;&nbsp;&nbsp;four&nbsp;TColorAnimations<br />&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;TInnerGlowEffect<br />&nbsp;&nbsp;&nbsp;&nbsp;another&nbsp;TRectangle<br />&nbsp;&nbsp;text</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TText<br />&nbsp;&nbsp;a&nbsp;TGlowEffect&nbsp;</span>
</span>
</code></div>
<p>(Note from the indentation above that certain components are children of other components.)</p>

<p>So, we start with a TLayout. This is a useful container component. It is similar to a TPanel, but has no &#8216;styling&#8217; itself - ie. it has no way to specify it&#8217;s appearance (because it has no appearance).</p>

<p>The TLayout has three children, a TRectangle for the background, a TText for the text and a TGlowEffect to show selected state. Both of these are &#8216;styled&#8217; components - ie that have an appearance which can be modified. A TRectangle, for instance, has stroke and fill &#8216;brushes&#8217; for the outline and infill respectively, as well as properties for stroke thickness, corner type, which sides to show and much more besides.</p>

<p>The background rectangle contains another two rectangles, which add extra subtlely to the style, four animations and an effect.</p>

<p>Animations modify a property of their parent component. For example, when you hover your mouse over a button the background changes color due to an animation modifying the Fill.Color property. However, animations are not (necessarily) instant flips from one value to another. In the example just stated the fill color &#8216;animates&#8217; gently from the original color to the target color over a fraction of a second.</p>

<p>In styles animations are usually activated by a boolean Trigger property, which is linked to the name of property on the parent component. When the trigger property changes state, the animation fires. There are a number of properties which can be used to trigger an animation including mouse overs and clicks.</p>

<p>Different animation components modify different types of property. A TFloatAnimation modifies a numeric property, a TColorAnimation modifies a color property, and so on.</p>

<p>Effects are similar to animations, in that the are tied to a trigger property and modify the appearance of the control when the trigger property is True. Effects can do things like display a glowing border (TGlowEffect), a drop shadow (TGlowEffect) or blur a control (TBlurEffect).</p>

<p><b>Styles and Components</b></p>

<p>So, above we have the component tree for a TButton in the Windows 7 style, but the tree is not fixed across styles: we could create a style with components added or removed, with components rearranged, even with components of different types. It is entirely up to the style designer to decide how a style element is made up.</p>

<p>However, there do need to be links between the developers code and the designers style. For example, when the developer sets the text of a TButton, he searches the buttonstyle for a component called &#8216;text&#8217;, expects that it is of type TText and sets it&#8217;s Text property. So, in this case the style must have a TText component called &#8216;text&#8217; somewhere within it in order to provide the full functionality of the control. When designing styles (and the code to go with it) it is important that the designer and developer communicate and document any such links.</p>

<p><b>Other components</b></p>

<p>A style may also contain any component available on the Delphi/C++Builder component palette. For example, a TScrollBox contains two TScrollBar components, for the vertical and horizontal scroll bars. In such a case the component in the style file can be used to specify things such as the width and height of the component.</p>

<p>However, the styling for these control will be picked up from the usual style elements for that class of component (ie. &#8216;scrollbarstyle&#8217; for a TScrollBar). You can, however, override the components default styling by setting it&#8217;s StyleLookup property and creating the appropriate style element.</p>


	  ]]></content>
	</entry>

	<entry>
	  <title>FireMonkey Grids: Basics, Custom Cells and Columns</title>
	  <link rel="alternate" type="text/html" href="http://monkeystyler.com/blog/entry/firemonkey-grid-basics-custom-cells-and-columns" />
	  <id>tag:,2012:/blog/6.19</id>
	  <published>2012-02-13T20:30:55Z</published>
	  <updated>2012-05-18T12:52:57Z</updated>
	  <author>
			<name>Mike Sutton</name>
			<email>mike@solentsoftware.com</email>
				  </author>

	  <category term="Coding"
		scheme="http://monkeystyler.com/news/category/coding"
		label="Coding" />
	  <content type="html"><![CDATA[
		<p><a href="http://monkeystyler.com/styler">MonkeyStyler</a> uses a couple of heavily customised grid columns. I spent some of last week finishing off the styling for them. The whole process has taught me a lot about FireMonkey grids. Prompted by <a href="http://stackoverflow.com/questions/8883214/delphi-xe2-firemonkey-setting-the-grid-display-colour-and-alignment">this question</a> on StackOverflow I though now would be a good time to share some of what I have learnt.</p>

<p>So, in this post I&#8217;m going to cover the following:</p><ul><li>How FireMonkey grids work;</li>
<li>How to create a custom cell class;</li>
<li>How to create a custom column class;</li></ul>

<p>Our StackOverflow poster wanted to know how to set the alignment and color of a grid cell, so I&#8217;ll concentrate on those issues in this post. We&#8217;ll create an app which has a grid showing two columns. The first will display the row index, the second financial figures, which are right aligned and with a background which changes to red when the figure is negative. I&#8217;ll cover most of that today with the styling issues in a future post.</p>

<p><b>FireMonkey Grids</b></p>

<p>Grids in FireMonkey are much more flexible than those in the VCL. But, of course with flexibility comes complexity. Fortunately, once you&#8217;ve learnt a few basics the rest comes fairly easy.</p>

<p>A FireMonkey TGrid is simply a container, adapted to contain children of type TColumn. A column is simply a container for a series of cells. We&#8217;ll get to the cells later.</p>

<p>To start with we&#8217;ll create an app which contains a TGrid. In the Delphi form designer, right click on the empty grid and select the Element Editor. Here, add a TColumn and back out. This will be a basic column in which we&#8217;ll display the row index.</p>

<p>On to the code, here&#8217;s the interface:</p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">type<br />&nbsp;&nbsp;TForm1&nbsp;</span><span style="color: #007700">=&nbsp;class(</span><span style="color: #0000BB">TForm</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Grid1</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TGrid</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Column1</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TColumn</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;FormCreate</span><span style="color: #007700">(</span><span style="color: #0000BB">Sender</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TObject</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;FormDestroy</span><span style="color: #007700">(</span><span style="color: #0000BB">Sender</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TObject</span><span style="color: #007700">);<br />&nbsp;&nbsp;private<br />&nbsp;&nbsp;protected<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">ValueColumn</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TColumn</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Data</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TList</span><span style="color: #007700">&lt;</span><span style="color: #0000BB">Single</span><span style="color: #007700">&gt;;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;PopulateData</span><span style="color: #007700">;<br />&nbsp;&nbsp;public<br />&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>
<p>	<br />
Data is a list which we populate with random values in PopulateData.</p>

<p>FormCreate sets up our Data values, and also creates and adds another TColumn to the grid. We&#8217;ll create this in code so it&#8217;s easier to play around with. Note that, as always in FireMonkey, we simply assign it&#8217;s Parent property to the grid to assign it to the appropriate container.</p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">procedure&nbsp;TForm1</span><span style="color: #007700">.</span><span style="color: #0000BB">FormCreate</span><span style="color: #007700">(</span><span style="color: #0000BB">Sender</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TObject</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;Data&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TList</span><span style="color: #007700">&lt;</span><span style="color: #0000BB">Single</span><span style="color: #007700">&gt;.</span><span style="color: #0000BB">Create</span><span style="color: #007700">;<br /><br />&nbsp;&nbsp;</span><span style="color: #0000BB">PopulateData</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">Grid1</span><span style="color: #007700">.</span><span style="color: #0000BB">RowCount&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">RowCount</span><span style="color: #007700">;<br /><br />&nbsp;&nbsp;</span><span style="color: #0000BB">ValueColumn&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TColumn</span><span style="color: #007700">.</span><span style="color: #0000BB">Create</span><span style="color: #007700">(</span><span style="color: #0000BB">Grid1</span><span style="color: #007700">);<br />&nbsp;&nbsp;</span><span style="color: #0000BB">ValueColumn</span><span style="color: #007700">.</span><span style="color: #0000BB">Parent&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Grid1</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p>Go back to the form editor and create a method for the grids OnGetValue event:</p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">procedure&nbsp;TForm1</span><span style="color: #007700">.</span><span style="color: #0000BB">Grid1GetValue</span><span style="color: #007700">(</span><span style="color: #0000BB">Sender</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TObject</span><span style="color: #007700">;&nbsp;const&nbsp;</span><span style="color: #0000BB">Col</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">Row</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Integer</span><span style="color: #007700">;<br />&nbsp;&nbsp;var&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Variant</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;</span><span style="color: #0000BB">Col&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">0&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;Value&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Row<br />&nbsp;&nbsp;</span><span style="color: #007700">else&nbsp;if&nbsp;</span><span style="color: #0000BB">Col&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">1&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;Value&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Data&#91;Row&#93;</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p>What happens here? The TColumn has a number of cells to display data but it only creates as many cells as it has visible rows. I.e. if a grid has a RowCount of 100, but only 20 cells are visible then only 20 cells are created. Whenever you scroll the grid each cell gets recycled. Because of this a grid cell cannot store any data between refreshes. (Or, more accurately, it should not store data because if it does it will be displaying the wrong data).</p>

<p>So, every time a cell is displayed the grid calls the OnGetValue event for that cell. OnGetValue passes the column and row indexes for the cell (the virtual column and row indexes) and our event handler needs to return the value to display in the Value variant parameter.</p>

<p>Run the above and you&#8217;ll see something like:</p>

<p><img src="http://monkeystyler.com/blogresources/gridbasics1.png" alt=""  /></p>

<p>(Aside: the grid appears to have a few display issues if you don&#8217;t show headers, hence why I&#8217;ve kept the headers here).</p>

<p><b>Custom Columns</b></p>

<p>Ignoring the rounding issues (we&#8217;re using Singles for simplicity here), you can see that the column of supposedly financial figures really needs to be right aligned (we&#8217;ll come to rounding and formating later).</p>

<p>We&#8217;re using a TColumn for the figures, which is a container for TTextCell. The definition for TTextCell is: </p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">TTextCell&nbsp;</span><span style="color: #007700">=&nbsp;class(</span><span style="color: #0000BB">TEdit</span><span style="color: #007700">)<br />&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>
<p>	<br />
So, it&#8217;s just an edit control with the parent set to the column. Haha. Easy. To get our control right aligned we just need to set the TEdit&#8217;s TextAlign property, which we can assign when the cell is created.</p>

<p>Each cell is created in the columns CreateCellControl virtual method. Look for the method in TColumn and we see:</p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #007700">function&nbsp;</span><span style="color: #0000BB">TColumn</span><span style="color: #007700">.</span><span style="color: #0000BB">CreateCellControl</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TStyledControl</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;Result&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TTextCell</span><span style="color: #007700">.</span><span style="color: #0000BB">Create</span><span style="color: #007700">(</span><span style="color: #0000BB">Self</span><span style="color: #007700">);<br />&nbsp;&nbsp;</span><span style="color: #0000BB">TTextCell</span><span style="color: #007700">(</span><span style="color: #0000BB">Result</span><span style="color: #007700">).</span><span style="color: #0000BB">OnTyping&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">DoTextChanged</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">TTextCell</span><span style="color: #007700">(</span><span style="color: #0000BB">Result</span><span style="color: #007700">).</span><span style="color: #0000BB">OnExit&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">DoTextExit</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p>So, we&#8217;ll create our own custom column and override the CreateCellControl to do our work for us:</p><div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">type&nbsp;TFinancialColumn&nbsp;</span><span style="color: #007700">=&nbsp;class(</span><span style="color: #0000BB">TColumn</span><span style="color: #007700">)<br />&nbsp;&nbsp;protected<br />&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;</span><span style="color: #0000BB">CreateCellControl</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TStyledControl</span><span style="color: #007700">;</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;...<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />function&nbsp;</span><span style="color: #0000BB">TFinancialColumn</span><span style="color: #007700">.</span><span style="color: #0000BB">CreateCellControl</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TStyledControl</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;Result&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">inherited</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">TEdit</span><span style="color: #007700">(</span><span style="color: #0000BB">Result</span><span style="color: #007700">).</span><span style="color: #0000BB">TextAlign&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TTextAlign</span><span style="color: #007700">.</span><span style="color: #0000BB">taTrailing</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p>Update the FormCreate to create TFinancialColumn and we see:</p>

<p><img src="http://monkeystyler.com/blogresources/gridbasics2.png" alt=""  /></p>

<p><b>Custom Cells</b></p>

<p>But we&#8217;ve now taken things as far as they can go with the built in TTextCell. It&#8217;s time to create our own cell class so we can really get things looking how we want.</p>

<p>Look again at the definition of TColumn.CreateCellControl. Note that it returns an object descending from TStyledControl. A TStyledControl is the parent of any control which can have styling applied. In other words, any visual control in FireMonkey. FireMonkey already does that with TCheckCell, TProgressCell and TImageCell for check boxes, progress bars and images.</p>

<p>And you can extend this to create custom cells using any control you like. You could go really freaky and use a list box or tree view within a cell. You probably wouldn&#8217;t want to, but FireMonkey is flexible enough to do it if you want. And all FireMonkey controls can own - be containers for - other controls. So you can create a cell which is made up of multiple controls.</p>

<p>Take a look at the property editor grid for MonkeyStyler in the screenshot below from the  <a href="http://monkeystyler.com/blog/entry/monkeystyler-preview-screenshots">the preview images blog post</a> and you&#8217;ll see that the values column contains:
<ul><li>A TColorBox for color previews (the Fill.Color property);</li>
<li>A TEdit (editable properties);</li>
<li>A TCheckBox (boolean properties);</li>
<li>A TButton (for the animation menu button and image)</li></ul>
<p>with code to set each item&#8217;s Visible property depending on the data type.</p>

<p><img src="http://monkeystyler.com/blogresources/propertyeditorpreview.png" alt=""  /></p>

<p><b>TFinancialCell</b></p>

<p>But, enough showing off, lets get back to our financial column. The TTextCell is just a TEdit. Not much customisation we can do there. What we&#8217;ll do is create our cell as a TStyledControl which will contain an alClient aligned TEdit.</p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">type&nbsp;TFinancialCell&nbsp;</span><span style="color: #007700">=&nbsp;class(</span><span style="color: #0000BB">TStyledControl</span><span style="color: #007700">)<br />&nbsp;&nbsp;protected<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FEdit</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TEdit</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;SetData</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Variant</span><span style="color: #007700">);&nbsp;</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;public<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">constructor&nbsp;Create</span><span style="color: #007700">(</span><span style="color: #0000BB">AOwner</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TComponent</span><span style="color: #007700">);&nbsp;</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br />...<br /><br /></span><span style="color: #0000BB">constructor&nbsp;TFinancialCell</span><span style="color: #007700">.</span><span style="color: #0000BB">Create</span><span style="color: #007700">(</span><span style="color: #0000BB">AOwner</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TComponent</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;inherited</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FEdit&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TEdit</span><span style="color: #007700">.</span><span style="color: #0000BB">Create</span><span style="color: #007700">(</span><span style="color: #0000BB">Self</span><span style="color: #007700">);<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FEdit</span><span style="color: #007700">.</span><span style="color: #0000BB">Parent&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Self</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FEdit</span><span style="color: #007700">.</span><span style="color: #0000BB">Align&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TAlignLayout</span><span style="color: #007700">.</span><span style="color: #0000BB">alClient</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FEdit</span><span style="color: #007700">.</span><span style="color: #0000BB">TextAlign&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TTextAlign</span><span style="color: #007700">.</span><span style="color: #0000BB">taTrailing</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p>Now, look at the SetData method, which is the Setter for the Data property. Data is defined in TFMXObject, the parent of all FireMonkey objects. Earlier we saw how the grid fetches data for each cell by called the OnGetValue event, well after it&#8217;s fetched the data it passes it on to the cell objects Data property. So, we override the SetData method to get the data we need to display.</p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">procedure&nbsp;TFinancialCell</span><span style="color: #007700">.</span><span style="color: #0000BB">SetData</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Variant</span><span style="color: #007700">);<br />var&nbsp;</span><span style="color: #0000BB">F</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Single</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;inherited</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">F&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FEdit</span><span style="color: #007700">.</span><span style="color: #0000BB">Data&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Format</span><span style="color: #007700">(</span><span style="color: #DD0000">'%m'</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">&#91;F&#93;</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p>Before we can run things we need to update the columns CreateCellControl to reflect our new cell class:</p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #007700">function&nbsp;</span><span style="color: #0000BB">TFinancialColumn</span><span style="color: #007700">.</span><span style="color: #0000BB">CreateCellControl</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TStyledControl</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;Result&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TFinancialCell</span><span style="color: #007700">.</span><span style="color: #0000BB">Create</span><span style="color: #007700">(</span><span style="color: #0000BB">Self</span><span style="color: #007700">);<br />&nbsp;&nbsp;</span><span style="color: #0000BB">TTextCell</span><span style="color: #007700">(</span><span style="color: #0000BB">Result</span><span style="color: #007700">).</span><span style="color: #0000BB">OnTyping&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">DoTextChanged</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">TTextCell</span><span style="color: #007700">(</span><span style="color: #0000BB">Result</span><span style="color: #007700">).</span><span style="color: #0000BB">OnExit&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">DoTextExit</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p>Now things are looking much better:</p>

<p><img src="http://monkeystyler.com/blogresources/gridbasics3.png" alt=""  /></p>

<p><b>Round up</b></p>

<p>So, we have a grid column which is formatting the data how we want. This article is already long enough, so I won&#8217;t bore you any longer, other than to say that I will return at some future point to show you how you can use styles to format the grid cells we created today.</p>

<p>Enjoy.</p>

<p><a href="http://monkeystyler.com/blogresources/GridBasics.zip">GridBasics.zip</a> - Download the project sources.</p>

<p>Full source:</p><div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">unit&nbsp;Main</span><span style="color: #007700">;<br /><br />interface<br /><br /></span><span style="color: #0000BB">uses<br />&nbsp;&nbsp;System</span><span style="color: #007700">.</span><span style="color: #0000BB">SysUtils</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">System</span><span style="color: #007700">.</span><span style="color: #0000BB">Types</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">System</span><span style="color: #007700">.</span><span style="color: #0000BB">UITypes</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">System</span><span style="color: #007700">.</span><span style="color: #0000BB">Classes</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">System</span><span style="color: #007700">.</span><span style="color: #0000BB">Variants</span><span style="color: #007700">,<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FMX</span><span style="color: #007700">.</span><span style="color: #0000BB">Types</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">FMX</span><span style="color: #007700">.</span><span style="color: #0000BB">Controls</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">FMX</span><span style="color: #007700">.</span><span style="color: #0000BB">Forms</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">FMX</span><span style="color: #007700">.</span><span style="color: #0000BB">Dialogs</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">Generics</span><span style="color: #007700">.</span><span style="color: #0000BB">Collections</span><span style="color: #007700">,<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FMX</span><span style="color: #007700">.</span><span style="color: #0000BB">Grid</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">FMX</span><span style="color: #007700">.</span><span style="color: #0000BB">Layouts</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">FMX</span><span style="color: #007700">.</span><span style="color: #0000BB">Edit</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">FMX</span><span style="color: #007700">.</span><span style="color: #0000BB">ListBox</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">type&nbsp;TFinancialCell&nbsp;</span><span style="color: #007700">=&nbsp;class(</span><span style="color: #0000BB">TStyledControl</span><span style="color: #007700">)<br />&nbsp;&nbsp;protected<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FEdit</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TEdit</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;SetData</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Variant</span><span style="color: #007700">);&nbsp;</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;public<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">constructor&nbsp;Create</span><span style="color: #007700">(</span><span style="color: #0000BB">AOwner</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TComponent</span><span style="color: #007700">);&nbsp;</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">type&nbsp;TFinancialColumn&nbsp;</span><span style="color: #007700">=&nbsp;class(</span><span style="color: #0000BB">TColumn</span><span style="color: #007700">)<br />&nbsp;&nbsp;protected<br />&nbsp;&nbsp;&nbsp;&nbsp;function&nbsp;</span><span style="color: #0000BB">CreateCellControl</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TStyledControl</span><span style="color: #007700">;</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">type<br />&nbsp;&nbsp;TForm1&nbsp;</span><span style="color: #007700">=&nbsp;class(</span><span style="color: #0000BB">TForm</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Grid1</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TGrid</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Column1</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TColumn</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;FormCreate</span><span style="color: #007700">(</span><span style="color: #0000BB">Sender</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TObject</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;FormDestroy</span><span style="color: #007700">(</span><span style="color: #0000BB">Sender</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TObject</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;Grid1GetValue</span><span style="color: #007700">(</span><span style="color: #0000BB">Sender</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TObject</span><span style="color: #007700">;&nbsp;const&nbsp;</span><span style="color: #0000BB">Col</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">Row</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Integer</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Variant</span><span style="color: #007700">);<br />&nbsp;&nbsp;private<br />&nbsp;&nbsp;protected<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">ValueColumn</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TFinancialColumn</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Data</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TList</span><span style="color: #007700">&lt;</span><span style="color: #0000BB">Single</span><span style="color: #007700">&gt;;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;PopulateData</span><span style="color: #007700">;<br />&nbsp;&nbsp;public<br />&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br />var<br />&nbsp;&nbsp;</span><span style="color: #0000BB">Form1</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TForm1</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">implementation<br /><br />&#123;$R&nbsp;</span><span style="color: #007700">*.</span><span style="color: #0000BB">fmx&#125;<br /><br /></span><span style="color: #007700">const&nbsp;</span><span style="color: #0000BB">RowCount&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">20</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">&#123;&nbsp;TForm1&nbsp;&#125;<br /><br />procedure&nbsp;TForm1</span><span style="color: #007700">.</span><span style="color: #0000BB">FormCreate</span><span style="color: #007700">(</span><span style="color: #0000BB">Sender</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TObject</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;Data&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TList</span><span style="color: #007700">&lt;</span><span style="color: #0000BB">Single</span><span style="color: #007700">&gt;.</span><span style="color: #0000BB">Create</span><span style="color: #007700">;<br /><br />&nbsp;&nbsp;</span><span style="color: #0000BB">PopulateData</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">Grid1</span><span style="color: #007700">.</span><span style="color: #0000BB">RowCount&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">RowCount</span><span style="color: #007700">;<br /><br />&nbsp;&nbsp;</span><span style="color: #0000BB">ValueColumn&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TFinancialColumn</span><span style="color: #007700">.</span><span style="color: #0000BB">Create</span><span style="color: #007700">(</span><span style="color: #0000BB">Grid1</span><span style="color: #007700">);<br />&nbsp;&nbsp;</span><span style="color: #0000BB">ValueColumn</span><span style="color: #007700">.</span><span style="color: #0000BB">Parent&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Grid1</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">procedure&nbsp;TForm1</span><span style="color: #007700">.</span><span style="color: #0000BB">FormDestroy</span><span style="color: #007700">(</span><span style="color: #0000BB">Sender</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TObject</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;Data</span><span style="color: #007700">.</span><span style="color: #0000BB">Free</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">procedure&nbsp;TForm1</span><span style="color: #007700">.</span><span style="color: #0000BB">Grid1GetValue</span><span style="color: #007700">(</span><span style="color: #0000BB">Sender</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TObject</span><span style="color: #007700">;&nbsp;const&nbsp;</span><span style="color: #0000BB">Col</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">Row</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Integer</span><span style="color: #007700">;<br />&nbsp;&nbsp;var&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Variant</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;</span><span style="color: #0000BB">Col&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">0&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;Value&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Row<br />&nbsp;&nbsp;</span><span style="color: #007700">else&nbsp;if&nbsp;</span><span style="color: #0000BB">Col&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">1&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;Value&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Data&#91;Row&#93;</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">procedure&nbsp;TForm1</span><span style="color: #007700">.</span><span style="color: #0000BB">PopulateData</span><span style="color: #007700">;<br />var&nbsp;</span><span style="color: #0000BB">I</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Integer</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;</span><span style="color: #007700">for&nbsp;</span><span style="color: #0000BB">I&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">1&nbsp;to&nbsp;RowCount&nbsp;</span><span style="color: #007700">do<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Data</span><span style="color: #007700">.</span><span style="color: #0000BB">Add</span><span style="color: #007700">((</span><span style="color: #0000BB">Random</span><span style="color: #007700">(</span><span style="color: #0000BB">10000</span><span style="color: #007700">)-</span><span style="color: #0000BB">1000</span><span style="color: #007700">)/</span><span style="color: #0000BB">100</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">&#123;&nbsp;TFinancialColumn&nbsp;&#125;<br /><br /></span><span style="color: #007700">function&nbsp;</span><span style="color: #0000BB">TFinancialColumn</span><span style="color: #007700">.</span><span style="color: #0000BB">CreateCellControl</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TStyledControl</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;Result&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TFinancialCell</span><span style="color: #007700">.</span><span style="color: #0000BB">Create</span><span style="color: #007700">(</span><span style="color: #0000BB">Self</span><span style="color: #007700">);<br />&nbsp;&nbsp;</span><span style="color: #0000BB">TTextCell</span><span style="color: #007700">(</span><span style="color: #0000BB">Result</span><span style="color: #007700">).</span><span style="color: #0000BB">OnTyping&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">DoTextChanged</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">TTextCell</span><span style="color: #007700">(</span><span style="color: #0000BB">Result</span><span style="color: #007700">).</span><span style="color: #0000BB">OnExit&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">DoTextExit</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">&#123;&nbsp;TFinancialCell&nbsp;&#125;<br /><br />constructor&nbsp;TFinancialCell</span><span style="color: #007700">.</span><span style="color: #0000BB">Create</span><span style="color: #007700">(</span><span style="color: #0000BB">AOwner</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TComponent</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;inherited</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FEdit&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TEdit</span><span style="color: #007700">.</span><span style="color: #0000BB">Create</span><span style="color: #007700">(</span><span style="color: #0000BB">Self</span><span style="color: #007700">);<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FEdit</span><span style="color: #007700">.</span><span style="color: #0000BB">Parent&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Self</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FEdit</span><span style="color: #007700">.</span><span style="color: #0000BB">Align&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TAlignLayout</span><span style="color: #007700">.</span><span style="color: #0000BB">alClient</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FEdit</span><span style="color: #007700">.</span><span style="color: #0000BB">TextAlign&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TTextAlign</span><span style="color: #007700">.</span><span style="color: #0000BB">taTrailing</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">procedure&nbsp;TFinancialCell</span><span style="color: #007700">.</span><span style="color: #0000BB">SetData</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Variant</span><span style="color: #007700">);<br />var&nbsp;</span><span style="color: #0000BB">F</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Single</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;inherited</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">F&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FEdit</span><span style="color: #007700">.</span><span style="color: #0000BB">Data&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Format</span><span style="color: #007700">(</span><span style="color: #DD0000">'%m'</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">&#91;F&#93;</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">end</span><span style="color: #007700">.&nbsp;</span>
</span>
</code></div>
	  ]]></content>
	</entry>

	<entry>
	  <title>TBitmapSpeedButton: Loading Images from the Style</title>
	  <link rel="alternate" type="text/html" href="http://monkeystyler.com/blog/entry/tbitmapspeedbutton-loading-images-from-the-style" />
	  <id>tag:,2012:/blog/6.18</id>
	  <published>2012-01-26T09:09:39Z</published>
	  <updated>2012-01-26T04:10:47Z</updated>
	  <author>
			<name>Mike Sutton</name>
			<email>mike@solentsoftware.com</email>
				  </author>

	  <category term="Coding"
		scheme="http://monkeystyler.com/news/category/coding"
		label="Coding" />
	  <category term="Styles"
		scheme="http://monkeystyler.com/news/category/styles"
		label="Styles" />
	  <content type="html"><![CDATA[
		<p>Recently recently blogged about creating a <a href="http://monkeystyler.com/blog/entry/my-first-firemonkey-custom-control-tbitmapspeedbutton">TBitmapSpeedButton</a> - a button which could show a bitmap image. When I came to use it I realised an ideological flaw. I was using the old VCL style model of loading a bitmap at design time to use in the application.</p>

<p>That works fine for VCL, but in FireMonkey it&#8217;s good practice to offload the visuals to the style. What would be ideal is if, in the form designer, I can specify a style resource for the image to be used. Now I, or my visual designer, can choose an image to use without needing access to my source code. If the look of the software needs updating I can just update the style file with new images and the app will look different without having to edit the source code (or at least the FMX file, which as far as I&#8217;m concerned is the same thing.</p>

<p>So, I&#8217;ve updated my component with two new properties:</p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">property&nbsp;ImageType</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TImageType&nbsp;read&nbsp;FImageType&nbsp;write&nbsp;SetImageType</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">property&nbsp;ImageStyleLookup</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">String&nbsp;read&nbsp;FImageStyleLookup&nbsp;write&nbsp;SetImageStyleLookup</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p>TImageType is either itBitmap or itStyleLookup and tells the component where to get the bitmap data from.</p>

<p>The only interesting bit of new code is the new UpdateImage method:</p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">procedure&nbsp;TBitmapSpeedButton</span><span style="color: #007700">.</span><span style="color: #0000BB">UpdateImage</span><span style="color: #007700">;<br />var&nbsp;</span><span style="color: #0000BB">Obj</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TFMXObject</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;</span><span style="color: #0000BB">FImageType&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">itBitmap&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;</span><span style="color: #0000BB">FImage&nbsp;</span><span style="color: #007700">&lt;&gt;&nbsp;</span><span style="color: #0000BB">nil&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FImage</span><span style="color: #007700">.</span><span style="color: #0000BB">Bitmap</span><span style="color: #007700">.</span><span style="color: #0000BB">Assign</span><span style="color: #007700">(</span><span style="color: #0000BB">FBitmap</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;else<br />&nbsp;&nbsp;else&nbsp;</span><span style="color: #FF8000">//itResource<br />&nbsp;&nbsp;</span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;&nbsp;&nbsp;Obj&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">nil</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(</span><span style="color: #0000BB">FScene&nbsp;</span><span style="color: #007700">&lt;&gt;&nbsp;</span><span style="color: #0000BB">nil</span><span style="color: #007700">)&nbsp;and&nbsp;(</span><span style="color: #0000BB">FScene</span><span style="color: #007700">.</span><span style="color: #0000BB">GetStyleBook&nbsp;</span><span style="color: #007700">&lt;&gt;&nbsp;</span><span style="color: #0000BB">nil</span><span style="color: #007700">)&nbsp;and&nbsp;(</span><span style="color: #0000BB">FScene</span><span style="color: #007700">.</span><span style="color: #0000BB">GetStyleBook</span><span style="color: #007700">.</span><span style="color: #0000BB">Root&nbsp;</span><span style="color: #007700">&lt;&gt;&nbsp;</span><span style="color: #0000BB">nil</span><span style="color: #007700">)&nbsp;</span><span style="color: #0000BB">then<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Obj&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TControl</span><span style="color: #007700">(</span><span style="color: #0000BB">FScene</span><span style="color: #007700">.</span><span style="color: #0000BB">GetStyleBook</span><span style="color: #007700">.</span><span style="color: #0000BB">Root</span><span style="color: #007700">.</span><span style="color: #0000BB">FindStyleResource</span><span style="color: #007700">(</span><span style="color: #0000BB">FImageStyleLookup</span><span style="color: #007700">));<br />&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;</span><span style="color: #0000BB">Obj&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">nil&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;</span><span style="color: #0000BB">Application</span><span style="color: #007700">.</span><span style="color: #0000BB">DefaultStyles&nbsp;</span><span style="color: #007700">&lt;&gt;&nbsp;</span><span style="color: #0000BB">nil&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Obj&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TControl</span><span style="color: #007700">(</span><span style="color: #0000BB">Application</span><span style="color: #007700">.</span><span style="color: #0000BB">DefaultStyles</span><span style="color: #007700">.</span><span style="color: #0000BB">FindStyleResource</span><span style="color: #007700">(</span><span style="color: #0000BB">FImageStyleLookup</span><span style="color: #007700">));<br />&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(</span><span style="color: #0000BB">Obj&nbsp;</span><span style="color: #007700">&lt;&gt;&nbsp;</span><span style="color: #0000BB">nil</span><span style="color: #007700">)&nbsp;and&nbsp;(</span><span style="color: #0000BB">Obj&nbsp;is&nbsp;TImage</span><span style="color: #007700">)&nbsp;and&nbsp;(</span><span style="color: #0000BB">FImage&nbsp;</span><span style="color: #007700">&lt;&gt;&nbsp;</span><span style="color: #0000BB">nil</span><span style="color: #007700">)&nbsp;</span><span style="color: #0000BB">then<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FImage</span><span style="color: #007700">.</span><span style="color: #0000BB">Bitmap</span><span style="color: #007700">.</span><span style="color: #0000BB">Assign</span><span style="color: #007700">(</span><span style="color: #0000BB">TImage</span><span style="color: #007700">(</span><span style="color: #0000BB">Obj</span><span style="color: #007700">).</span><span style="color: #0000BB">Bitmap</span><span style="color: #007700">);<br />&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p>which shows how to find a style resource either from the current stylebook, or if that isn&#8217;t found, from the applications default style.</p>

<p><a href="http://monkeystyler.com/blogresources/BitmapSpeedButton.zip">Download updated sources</a></p>

<p>&nbsp;</p>
	  ]]></content>
	</entry>

	<entry>
	  <title>MonkeyStyler Preview Screenshots</title>
	  <link rel="alternate" type="text/html" href="http://monkeystyler.com/blog/entry/monkeystyler-preview-screenshots" />
	  <id>tag:,2012:/blog/6.17</id>
	  <published>2012-01-22T13:17:31Z</published>
	  <updated>2012-01-22T18:19:33Z</updated>
	  <author>
			<name>Mike Sutton</name>
			<email>mike@solentsoftware.com</email>
				  </author>

	  <category term="MonkeyStyler"
		scheme="http://monkeystyler.com/news/category/styler"
		label="MonkeyStyler" />
	  <content type="html"><![CDATA[
		<p><a href="http://monkeystyler.com/styler">MonkeyStyler</a> is my stand alone FireMonkey style designer. I&#8217;ve spent the last week or so making it look presentable, and here are the first screenshots. Please note that this is still &#8216;alpha&#8217; software and much is planned to change, in terms of visuals, usabality and functionality.</p>

<p>So, here&#8217;s the complete screenshot.</p>

<p><img src="http://monkeystyler/blogresources/screenshotpreview.png" alt=""  /></p>

<p><b>File and Element Manager</b><br />
Lets deal with each area individually. First the file and element manager.</p>

<p><img src="http://monkeystyler/blogresources/fileelementeditorpreview.png" alt=""  /></p>

<p>You can load a number of files at once, create new files, close and save open ones, and switch between files. The ability to have multiple files open means you can easily copy style elements between them (or indeed copy a style element within a file to create a duplicate).</p>

<p>(Note that I refer to individual elements within a style file as style elements or just elements. Hence the &#8216;buttonstyle&#8217; for a TButton is one element, &#8216;checkboxstyle&#8217; another and so on).</p>

<p>The element manager lists all available elements within the currently selected file and enables you to copy elements within and between files (as described above), create, delete and rename elements.</p>

<p>And, of course select elements, which shows the selected element in the control viewer:</p>

<p><b>Control Viewer</b></p>

<p><img src="http://monkeystyler.com/blogresources/controlviewerpreview.png" alt=""  /></p>

<p>The control viewer shows a live preview of your style. Note here that you&#8217;re not actually looking at a TButton. You&#8217;re seeing the components which make up the style for one. You can&#8217;t actually interact with it (eg. mouseovers, clicks etc. do nothing), but the Components button shows the drop down shown in the screenshot.</p>

<p>With this components drop-down you can see which components make up a style. You can also show and hide individual components by checking or clearing the relevant check box. This is a great way to see how a style is actually made up.</p>

<p>A neat feature is that the check boxes for animations and effects run the animation or effect. Have an animation which takes a second to run and you will see it running for a second in the preview. In other words, while the preview may not be an actual control, all the components (and animations and effects) which make it up are &#8216;live&#8217; and working. An animation which is set to loop will be constantly running and looping in the preview.</p>

<p><b>Property Editor</b></p>

<p><img src="http://monkeystyler.com/blogresources/propertyeditorpreview.png" alt=""  /></p>

<p>And finally, we come to the property editor. This should all look pretty familiar from Delphi/C++ Builder. Use the drop down to select which component within the element to edit and it&#8217;s properties will be displayed. Sub-properties can be expanded and edited as you would expect.</p>

<p>As for editing properties there is one feature you&#8217;ll notice immediately: all edits are live. Start typing into a &#8216;Text&#8217; property and the text on the control preview will change live as you type. Adjust the width, alignment or cornerstyle (or anything else) and the preview will update immediately, and without the need to hit enter, or otherwise tab away from the editor.</p>

<p>Another useful feature is the drop-down property editors. Edit a numeric property and you&#8217;ll see a slider appear, for a color or gradient property you&#8217;ll get a drop down color or gradient editor and so on. And these are also live: you&#8217;ll see preview control change live as you drag the slider, adjust colors or edit the gradient. There&#8217;s no modal dialog. No need to hit enter. You get instant feedback and quickly get the values you want. (And even if you have a drop down editor, you are still free to type in/cut and paste values if you want).</p>

<p>You also get: <br />
A button which brings down a menu for adding/editing animations;<br />
No nasty modal error messages. Set an illegal value and you&#8217;ll get a drop-down error message which simply clears as you keep typing;<br />
Buttons to add and delete components.</p>

<p>And, like I said, much will change, much will improve and much will be added.</p>

<p>Enjoy.</p>
	  ]]></content>
	</entry>

	<entry>
	  <title>My First FireMonkey Custom Control: TBitmapSpeedButton</title>
	  <link rel="alternate" type="text/html" href="http://monkeystyler.com/blog/entry/my-first-firemonkey-custom-control-tbitmapspeedbutton" />
	  <id>tag:,2012:/blog/6.16</id>
	  <published>2012-01-14T11:54:21Z</published>
	  <updated>2012-01-26T04:18:22Z</updated>
	  <author>
			<name>Mike Sutton</name>
			<email>mike@solentsoftware.com</email>
				  </author>

	  <category term="Coding"
		scheme="http://monkeystyler.com/news/category/coding"
		label="Coding" />
	  <category term="Styles"
		scheme="http://monkeystyler.com/news/category/styles"
		label="Styles" />
	  <content type="html"><![CDATA[
		<p><img src="http;//monkeystyler.com/blogresources/bitmapspeedbutton.png" alt=""  /></p>

<p>One thing which surprises me about the FireMonkey library is that the TSpeedButton has no option to display an image (indeed, none of the button controls do). Since I&#8217;m at the stage where I need such a control for the interface for <a href="http://monkeystyler.com/styler">MonkeyStyler</a> I decided this would be the perfect opportunity to create my first FireMonkey custom control.</p>

<p>So, lets look at what we want: We want to descend from TSpeedButton, so we can easily add the control to a tool bar (actually a FireMonkey toolbar can accept any control, but the styling for a speed button is closest to what I want). We want a bitmap image, and we want the option to have the image to the left, right, top or bottom of the text, or to have the image centered with no text.</p>

<p>I started by creating the style. This gets the basics of styling out of the way for when we create the code to interact with it. Of course, at this stage styling can be quite basic, simply adding the controls we need and setting basic properties.</p>

<p><b>The Style</b></p>

<p>Copy the styling for SpeedButtonStyle to a new style file (bitmapspeedbutton.style) from Windows7.style (Note: I did this with a couple of clicks in <a href="http://monkeystyler.com//styler">MonkeyStyler</a> but at the time of writing you&#8217;ll have to make do with cutting and pasting from the source files).</p>

<p>Here is the style for a TSpeedButton:</p>

<p><img src="http://monkeystyler.com/blogresources/bitmapspeedbuttonstylebefore.png" alt=""  /></p>

<p>We want to add our image at the highest level below the root TLayout. At this position it can interact with the TText as we adjust it&#8217;s position. We could just add the TImage directly, but if we did, adjusting the Align property would change it&#8217;s size. And unless we get messy with the padding we would get undesired stretching of the image.</p>

<p>So, what we&#8217;ll do is add a TLayout, and add the TImage as a child:</p>

<p><img src="http://monkeystyler.com/blogresources/bitmapspeedbuttonstyleafter.png" alt=""  /></p>

<p>Set the TImage&#8217;s properties:</p><div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">Height&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">24&nbsp;</span><span style="color: #007700">(</span><span style="color: #0000BB">our&nbsp;</span><span style="color: #007700">default&nbsp;</span><span style="color: #0000BB">image&nbsp;size</span><span style="color: #007700">)<br /></span><span style="color: #0000BB">Width&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">24<br />Align&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">alCenter&nbsp;</span><span style="color: #007700">(</span><span style="color: #0000BB">so&nbsp;it&nbsp;will&nbsp;be&nbsp;centered&nbsp;in&nbsp;the&nbsp;TLayout</span><span style="color: #007700">)<br /></span><span style="color: #0000BB">StyleName&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">image&nbsp;</span><span style="color: #007700">(</span><span style="color: #0000BB">so&nbsp;we&nbsp;can&nbsp;access&nbsp;it&nbsp;from&nbsp;code</span><span style="color: #007700">)<br /></span><span style="color: #0000BB">HitTest&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">False&nbsp;</span><span style="color: #007700">(</span><span style="color: #0000BB">to&nbsp;let&nbsp;mouse&nbsp;data&nbsp;pass&nbsp;through&nbsp;to&nbsp;the&nbsp;underlying&nbsp;components</span><span style="color: #007700">)<br /></span><span style="color: #0000BB">WrapMode&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">iwFit&nbsp;</span><span style="color: #007700">(</span><span style="color: #0000BB">Should&nbsp;be&nbsp;set&nbsp;already</span><span style="color: #007700">.&nbsp;</span><span style="color: #0000BB">Images&nbsp;will&nbsp;be&nbsp;enlarged</span><span style="color: #007700">/</span><span style="color: #0000BB">reduced&nbsp;to&nbsp;the&nbsp;correct&nbsp;size</span><span style="color: #007700">)&nbsp;</span>
</span>
</code></div>

<p>For the parent TLayout:</p><div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">StyleName&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">imagelayout&nbsp;</span><span style="color: #007700">(</span><span style="color: #0000BB">so&nbsp;we&nbsp;can&nbsp;access&nbsp;it&nbsp;from&nbsp;code</span><span style="color: #007700">)&nbsp;</span>
</span>
</code></div>

<p>and for the root TLayout:</p><div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">StyleName&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">speedbuttonbitmapstyle&nbsp;</span><span style="color: #007700">(</span><span style="color: #0000BB">the&nbsp;component&nbsp;name&nbsp;minus&nbsp;the&nbsp;leading&nbsp;T&nbsp;</span><span style="color: #007700">and&nbsp;</span><span style="color: #0000BB">with&nbsp;style&nbsp;appended&nbsp;</span><span style="color: #007700">-&nbsp;</span><span style="color: #0000BB">see&nbsp;below</span><span style="color: #007700">)&nbsp;</span>
</span>
</code></div><p>.</p>

<p>Save the file, and load it into the StyleBook for your test project (also, point your form&#8217;s StyleBook property to the StyleBook).</p>

<p><b>The code</b></p>

<p>Start by creating the code for the class:</p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">type&nbsp;TBitmapSpeedButton&nbsp;</span><span style="color: #007700">=&nbsp;class(</span><span style="color: #0000BB">TSpeedButton</span><span style="color: #007700">)<br />...&nbsp;</span>
</span>
</code></div>

<p>and add the Create method:</p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">constructor&nbsp;TBitmapSpeedButton</span><span style="color: #007700">.</span><span style="color: #0000BB">Create</span><span style="color: #007700">(</span><span style="color: #0000BB">AOwner</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TComponent</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;inherited</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">Height&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">28</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">Width&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">28</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p>Add some code to your test project to create a TSpeedButton in code:</p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">BSB&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TBitmapSpeedButton</span><span style="color: #007700">.</span><span style="color: #0000BB">Create</span><span style="color: #007700">(</span><span style="color: #0000BB">Self</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">BSB</span><span style="color: #007700">.</span><span style="color: #0000BB">Parent&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Self</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">BSB</span><span style="color: #007700">.</span><span style="color: #0000BB">Align&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TAlignLayout</span><span style="color: #007700">.</span><span style="color: #0000BB">alCenter</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p>Run it and you&#8217;ll see ... nothing. Okay, so the default style for a speed button is invisible unless you hover over it (perhaps not the best choice for a custom component, but we&#8217;re here now, so we&#8217;ll have to live with it). Actually you can see it by hovering your mouse over, you&#8217;ll just need to be good at finding where we centered it to.</p>

<p>What happened here? If you listen to some descriptions of FireMonkey custom control, they&#8217;ll give you lots of code to load a style into a FireMonkey control. But if you read such stuff ignore it. FireMonkey actually does all that stuff for you. If you dig into the FMX.Types unit and look at the source to TStyledControl.GetStyleObject you&#8217;ll see (amongst a lot of other stuff):</p><div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">StyleName&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">ClassName&nbsp;</span><span style="color: #007700">+&nbsp;</span><span style="color: #DD0000">'style'</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">Delete</span><span style="color: #007700">(</span><span style="color: #0000BB">StyleName</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">1</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">1</span><span style="color: #007700">);&nbsp;</span><span style="color: #FF8000">//&nbsp;just&nbsp;remove&nbsp;T&nbsp;</span>
</span>
</code></div>

<p>So, FireMonkey takes the ClassName of you control (TSpeedButton), appends &#8216;style&#8217; and removes the preceding &#8216;T&#8217;, giving us &#8216;SpeedButtonstyle&#8217; and automatically loads the appropriately named style (unless you, or your users, set the StyleLookup property, in which case it automatically loads that one instead).<br />
 <br />
(Aside: TStyledControl is the parent of all controls which can have styling applied).</p>

<p><b>Functionality</b></p>

<p>So, we have a control which looks like a TBitmapSpeedButton, we just need to add some code so it behaves like one.</p>

<p>Lets flesh out the interface section:</p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">type&nbsp;TImageAlign&nbsp;</span><span style="color: #007700">=&nbsp;(</span><span style="color: #0000BB">iaTop</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">iaLeft</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">iaRight</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">iaBottom</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">iaCenter</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">type<br />&nbsp;&nbsp;&#91;ComponentPlatformsAttribute</span><span style="color: #007700">(</span><span style="color: #0000BB">pidWin32&nbsp;</span><span style="color: #007700">or&nbsp;</span><span style="color: #0000BB">pidWin64&nbsp;</span><span style="color: #007700">or&nbsp;</span><span style="color: #0000BB">pidOSX32</span><span style="color: #007700">)</span><span style="color: #0000BB">&#93;<br />&nbsp;&nbsp;TBitmapSpeedButton&nbsp;</span><span style="color: #007700">=&nbsp;class(</span><span style="color: #0000BB">TSpeedButton</span><span style="color: #007700">)<br />&nbsp;&nbsp;private<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FImageAlign</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TImageAlign</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FTextVisible</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Boolean</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;SetImageAlign</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TImageAlign</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;SetTextVisible</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Boolean</span><span style="color: #007700">);<br />&nbsp;&nbsp;protected<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FImageLayout</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TLayout</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FImage</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TImage</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FBitmap</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TBitmap</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;ApplyStyle</span><span style="color: #007700">;</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;EVBitmapChange</span><span style="color: #007700">(</span><span style="color: #0000BB">Sender</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TObject</span><span style="color: #007700">);<br />&nbsp;&nbsp;public<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">constructor&nbsp;Create</span><span style="color: #007700">(</span><span style="color: #0000BB">AOwner</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TComponent</span><span style="color: #007700">);</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">destructor&nbsp;Destroy</span><span style="color: #007700">;</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">published<br />&nbsp;&nbsp;&nbsp;&nbsp;property&nbsp;ImageAlign</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TImageAlign&nbsp;read&nbsp;FImageAlign&nbsp;write&nbsp;SetImageAlign&nbsp;</span><span style="color: #007700">default&nbsp;</span><span style="color: #0000BB">iaCenter</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">property&nbsp;TextVisible</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Boolean&nbsp;read&nbsp;FTextVisible&nbsp;write&nbsp;SetTextVisible</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">property&nbsp;Bitmap</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TBitmap&nbsp;read&nbsp;FBitmap&nbsp;write&nbsp;FBitmap</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p>The first bit of interesting code is the ApplyStyle method:</p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">procedure&nbsp;TBitmapSpeedButton</span><span style="color: #007700">.</span><span style="color: #0000BB">ApplyStyle</span><span style="color: #007700">;<br />var&nbsp;</span><span style="color: #0000BB">T</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TFMXObject</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;inherited</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">T&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">FindStyleResource</span><span style="color: #007700">(</span><span style="color: #DD0000">'imagelayout'</span><span style="color: #007700">);<br />&nbsp;&nbsp;if&nbsp;(</span><span style="color: #0000BB">T&nbsp;</span><span style="color: #007700">&lt;&gt;&nbsp;</span><span style="color: #0000BB">nil</span><span style="color: #007700">)&nbsp;and&nbsp;(</span><span style="color: #0000BB">T&nbsp;is&nbsp;TLayout</span><span style="color: #007700">)&nbsp;</span><span style="color: #0000BB">then<br />&nbsp;&nbsp;&nbsp;&nbsp;FImageLayout&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TLayout</span><span style="color: #007700">(</span><span style="color: #0000BB">T</span><span style="color: #007700">);<br />&nbsp;&nbsp;</span><span style="color: #0000BB">T&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">FindStyleResource</span><span style="color: #007700">(</span><span style="color: #DD0000">'image'</span><span style="color: #007700">);<br />&nbsp;&nbsp;if&nbsp;(</span><span style="color: #0000BB">T&nbsp;</span><span style="color: #007700">&lt;&gt;&nbsp;</span><span style="color: #0000BB">nil</span><span style="color: #007700">)&nbsp;and&nbsp;(</span><span style="color: #0000BB">T&nbsp;is&nbsp;TImage</span><span style="color: #007700">)&nbsp;</span><span style="color: #0000BB">then<br />&nbsp;&nbsp;begin<br />&nbsp;&nbsp;&nbsp;&nbsp;FImage&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TImage</span><span style="color: #007700">(</span><span style="color: #0000BB">T</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FImage</span><span style="color: #007700">.</span><span style="color: #0000BB">Bitmap</span><span style="color: #007700">.</span><span style="color: #0000BB">Assign</span><span style="color: #007700">(</span><span style="color: #0000BB">FBitmap</span><span style="color: #007700">);<br />&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">SetTextVisible</span><span style="color: #007700">(</span><span style="color: #0000BB">FTextVisible</span><span style="color: #007700">);<br />&nbsp;&nbsp;</span><span style="color: #0000BB">UpdateImageLayout</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p>Most custom controls will need to override this virtual procedure. It is called whenever a style is loaded or modified, and it is here where we need to grab any objects which we will be manipulating, in our case the TImage (image) and it&#8217;s parent TLayout (imagelayout) objects.</p>

<p>Go back to our interface section and look at the Bitmap property. A naive implementation might use a getter and setter to fetch/modify the bitmap object contained within the styles TImage object. There&#8217;s two problems here: first the style isn&#8217;t applied at the time the object is created, but slightly later (I presume on some kind of OnIdle event). So, anyone instantiating your object:</p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">BSB&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TBitmapSpeedButton</span><span style="color: #007700">.</span><span style="color: #0000BB">Create</span><span style="color: #007700">(</span><span style="color: #0000BB">Self</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">BSB</span><span style="color: #007700">.</span><span style="color: #0000BB">Parent&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Self</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">BSB</span><span style="color: #007700">.</span><span style="color: #0000BB">Bitmap</span><span style="color: #007700">.</span><span style="color: #0000BB">LoadFromFile</span><span style="color: #007700">(</span><span style="color: #DD0000">'MyImage.png'</span><span style="color: #007700">);&nbsp;</span>
</span>
</code></div>

<p>Will at best get ignored, or at worst get an access violation, depending on whether you tested the validity of your FImage field.</p>

<p>The second issue is that if you style ever gets updated the bitmap data saved in the styles TImage will get deleted and you&#8217;ll get a new, empty, TImage object.</p>

<p>So, what we need to do is &#8216;cache&#8217; any data which will be sent to styling objects. In our case, that&#8217;s the TextVisible and ImageAlign property data in addition to that for Bitmap.</p>

<p>Look back at the ApplyStyle code above and you&#8217;ll see that I&#8217;m reloading the Bitmap and TextVisible data and calling UpdateImageLayout which will apply the ImageAlign and a few other features still to be added. Thus if a new style gets loaded the display will be updated to reflect the components state.</p>

<p>But, this code only operates when the style is applied, we also need to update the styles properties when a user sets our properties. So, we also have setters for ImageAlign and TextVisible, e.g.:</p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">procedure&nbsp;TBitmapSpeedButton</span><span style="color: #007700">.</span><span style="color: #0000BB">SetTextVisible</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Boolean</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;FTextVisible&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">;<br />&nbsp;&nbsp;if&nbsp;(</span><span style="color: #0000BB">FTextObject&nbsp;</span><span style="color: #007700">&lt;&gt;&nbsp;</span><span style="color: #0000BB">nil</span><span style="color: #007700">)&nbsp;and&nbsp;(</span><span style="color: #0000BB">FTextObject&nbsp;is&nbsp;TText</span><span style="color: #007700">)&nbsp;</span><span style="color: #0000BB">then<br />&nbsp;&nbsp;&nbsp;&nbsp;TText</span><span style="color: #007700">(</span><span style="color: #0000BB">FTextObject</span><span style="color: #007700">).</span><span style="color: #0000BB">Visible&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p>(FTextObject is inherited from our TSpeedButton parent (though, oddly, it isn&#8217;t declared as a TText, even though the TSpeedButton pretty much ignores it if it isn&#8217;t one).</p>

<p>For FBitmap we key into it&#8217;s OnChange event, with our EVBitmapChange handler (by convention I prefix event handlers with EV):</p>

<div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">procedure&nbsp;TBitmapSpeedButton</span><span style="color: #007700">.</span><span style="color: #0000BB">EVBitmapChange</span><span style="color: #007700">(</span><span style="color: #0000BB">Sender</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TObject</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;</span><span style="color: #0000BB">FImage&nbsp;</span><span style="color: #007700">&lt;&gt;&nbsp;</span><span style="color: #0000BB">nil&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;FImage</span><span style="color: #007700">.</span><span style="color: #0000BB">Bitmap</span><span style="color: #007700">.</span><span style="color: #0000BB">Assign</span><span style="color: #007700">(</span><span style="color: #0000BB">FBitmap</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;&nbsp;</span>
</span>
</code></div>

<p><b>Conclusion</b></p>

<p>So, that wraps up the interesting stuff. I&#8217;ve added a few more properties, which you can see in the full source below. And I&#8217;ll sum up that I&#8217;m rather pleased with what I can achieve in FireMonkey in only 152 lines of code (plus the style).</p>

<p>Links:<br />
<a href="http://monkeystyler.com/blogresources/BitmapSpeedButton.zip">Full source zip</a> (.pas and .style files).<br />
<a href="http://monkeystyler.com/wiki/TBitmapSpeedButton">Documentation</a> for the completed component.</p>

<p>Debugging tips:<br />
Check you have the style loaded into the forms StyleBook component.<br />
Check that the forms StyleBook property points to the StyleBook component (it&#8217;s not set by default).</p>

<p>Enjoy, Mike.</p>

<p>Update: <a href="http://monkeystyler.com/blog/entry/tbitmapspeedbutton-loading-images-from-the-style">TBitmapSpeedButton: Loading Images from the Style</a></p>

<p>Full .pas source:</p><div class="codeblock"><code><span style="color: #000000">
<span style="color: #0000BB">unit&nbsp;Solent</span><span style="color: #007700">.</span><span style="color: #0000BB">BitmapSpeedButton</span><span style="color: #007700">;<br /><br />interface<br /></span><span style="color: #0000BB">uses&nbsp;FMX</span><span style="color: #007700">.</span><span style="color: #0000BB">Controls</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">FMX</span><span style="color: #007700">.</span><span style="color: #0000BB">Layouts</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">FMX</span><span style="color: #007700">.</span><span style="color: #0000BB">Objects</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">FMX</span><span style="color: #007700">.</span><span style="color: #0000BB">Types</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">Classes</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">type&nbsp;TImageAlign&nbsp;</span><span style="color: #007700">=&nbsp;(</span><span style="color: #0000BB">iaTop</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">iaLeft</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">iaRight</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">iaBottom</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">iaCenter</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">type<br />&nbsp;&nbsp;&#91;ComponentPlatformsAttribute</span><span style="color: #007700">(</span><span style="color: #0000BB">pidWin32&nbsp;</span><span style="color: #007700">or&nbsp;</span><span style="color: #0000BB">pidWin64&nbsp;</span><span style="color: #007700">or&nbsp;</span><span style="color: #0000BB">pidOSX32</span><span style="color: #007700">)</span><span style="color: #0000BB">&#93;<br />&nbsp;&nbsp;TBitmapSpeedButton&nbsp;</span><span style="color: #007700">=&nbsp;class(</span><span style="color: #0000BB">TSpeedButton</span><span style="color: #007700">)<br />&nbsp;&nbsp;private<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FImageAlign</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TImageAlign</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FTextVisible</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Boolean</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FImageHeight</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Single</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FImageWidth</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Single</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FImagePadding</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Single</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;SetImageAlign</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TImageAlign</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;SetTextVisible</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Boolean</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;SetImageHeight</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Single</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;SetImagePadding</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Single</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;SetImageWidth</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Single</span><span style="color: #007700">);<br />&nbsp;&nbsp;protected<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FImageLayout</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TLayout</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FImage</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TImage</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FBitmap</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TBitmap</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;ApplyStyle</span><span style="color: #007700">;</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;EVBitmapChange</span><span style="color: #007700">(</span><span style="color: #0000BB">Sender</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TObject</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">procedure&nbsp;UpdateImageLayout</span><span style="color: #007700">;<br />&nbsp;&nbsp;public<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">constructor&nbsp;Create</span><span style="color: #007700">(</span><span style="color: #0000BB">AOwner</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TComponent</span><span style="color: #007700">);</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">destructor&nbsp;Destroy</span><span style="color: #007700">;</span><span style="color: #0000BB">override</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">published<br />&nbsp;&nbsp;&nbsp;&nbsp;property&nbsp;ImageAlign</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TImageAlign&nbsp;read&nbsp;FImageAlign&nbsp;write&nbsp;SetImageAlign&nbsp;</span><span style="color: #007700">default&nbsp;</span><span style="color: #0000BB">iaCenter</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">property&nbsp;TextVisible</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Boolean&nbsp;read&nbsp;FTextVisible&nbsp;write&nbsp;SetTextVisible</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">property&nbsp;Bitmap</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TBitmap&nbsp;read&nbsp;FBitmap&nbsp;write&nbsp;FBitmap</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">property&nbsp;ImageWidth</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Single&nbsp;read&nbsp;FImageWidth&nbsp;write&nbsp;SetImageWidth</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">property&nbsp;ImageHeight</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Single&nbsp;read&nbsp;FImageHeight&nbsp;write&nbsp;SetImageHeight</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">property&nbsp;ImagePadding</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Single&nbsp;read&nbsp;FImagePadding&nbsp;write&nbsp;SetImagePadding</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">procedure&nbsp;Register</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">implementation<br /><br />procedure&nbsp;Register</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;RegisterComponents</span><span style="color: #007700">(</span><span style="color: #DD0000">'SolentFMX'</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">&#91;TBitmapSpeedButton&#93;</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">&#123;&nbsp;TBitmapSpeedButton&nbsp;&#125;<br /><br />procedure&nbsp;TBitmapSpeedButton</span><span style="color: #007700">.</span><span style="color: #0000BB">ApplyStyle</span><span style="color: #007700">;<br />var&nbsp;</span><span style="color: #0000BB">T</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TFMXObject</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;inherited</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">T&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">FindStyleResource</span><span style="color: #007700">(</span><span style="color: #DD0000">'imagelayout'</span><span style="color: #007700">);<br />&nbsp;&nbsp;if&nbsp;(</span><span style="color: #0000BB">T&nbsp;</span><span style="color: #007700">&lt;&gt;&nbsp;</span><span style="color: #0000BB">nil</span><span style="color: #007700">)&nbsp;and&nbsp;(</span><span style="color: #0000BB">T&nbsp;is&nbsp;TLayout</span><span style="color: #007700">)&nbsp;</span><span style="color: #0000BB">then<br />&nbsp;&nbsp;&nbsp;&nbsp;FImageLayout&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TLayout</span><span style="color: #007700">(</span><span style="color: #0000BB">T</span><span style="color: #007700">);<br />&nbsp;&nbsp;</span><span style="color: #0000BB">T&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">FindStyleResource</span><span style="color: #007700">(</span><span style="color: #DD0000">'image'</span><span style="color: #007700">);<br />&nbsp;&nbsp;if&nbsp;(</span><span style="color: #0000BB">T&nbsp;</span><span style="color: #007700">&lt;&gt;&nbsp;</span><span style="color: #0000BB">nil</span><span style="color: #007700">)&nbsp;and&nbsp;(</span><span style="color: #0000BB">T&nbsp;is&nbsp;TImage</span><span style="color: #007700">)&nbsp;</span><span style="color: #0000BB">then<br />&nbsp;&nbsp;begin<br />&nbsp;&nbsp;&nbsp;&nbsp;FImage&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TImage</span><span style="color: #007700">(</span><span style="color: #0000BB">T</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FImage</span><span style="color: #007700">.</span><span style="color: #0000BB">Bitmap</span><span style="color: #007700">.</span><span style="color: #0000BB">Assign</span><span style="color: #007700">(</span><span style="color: #0000BB">FBitmap</span><span style="color: #007700">);<br />&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">SetTextVisible</span><span style="color: #007700">(</span><span style="color: #0000BB">FTextVisible</span><span style="color: #007700">);<br />&nbsp;&nbsp;</span><span style="color: #0000BB">UpdateImageLayout</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">constructor&nbsp;TBitmapSpeedButton</span><span style="color: #007700">.</span><span style="color: #0000BB">Create</span><span style="color: #007700">(</span><span style="color: #0000BB">AOwner</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TComponent</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;inherited</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FBitmap&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TBitmap</span><span style="color: #007700">.</span><span style="color: #0000BB">Create</span><span style="color: #007700">(</span><span style="color: #0000BB">0</span><span style="color: #007700">,</span><span style="color: #0000BB">0</span><span style="color: #007700">);<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FBitmap</span><span style="color: #007700">.</span><span style="color: #0000BB">OnChange&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">EVBitmapChange</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">FImageAlign&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">iaCenter</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">Height&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">28</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">Width&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">28</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">ImageWidth&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">24</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">ImageHeight&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">24</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">ImagePadding&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">2</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">destructor&nbsp;TBitmapSpeedButton</span><span style="color: #007700">.</span><span style="color: #0000BB">Destroy</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;FBitmap</span><span style="color: #007700">.</span><span style="color: #0000BB">Free</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">inherited</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">procedure&nbsp;TBitmapSpeedButton</span><span style="color: #007700">.</span><span style="color: #0000BB">EVBitmapChange</span><span style="color: #007700">(</span><span style="color: #0000BB">Sender</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TObject</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;</span><span style="color: #0000BB">FImage&nbsp;</span><span style="color: #007700">&lt;&gt;&nbsp;</span><span style="color: #0000BB">nil&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;FImage</span><span style="color: #007700">.</span><span style="color: #0000BB">Bitmap</span><span style="color: #007700">.</span><span style="color: #0000BB">Assign</span><span style="color: #007700">(</span><span style="color: #0000BB">FBitmap</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">procedure&nbsp;TBitmapSpeedButton</span><span style="color: #007700">.</span><span style="color: #0000BB">SetImageAlign</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">TImageAlign</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;FImageAlign&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">UpdateImageLayout</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">procedure&nbsp;TBitmapSpeedButton</span><span style="color: #007700">.</span><span style="color: #0000BB">SetImageHeight</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Single</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;FImageHeight&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">;<br />&nbsp;&nbsp;if&nbsp;</span><span style="color: #0000BB">FImage&nbsp;</span><span style="color: #007700">&lt;&gt;&nbsp;</span><span style="color: #0000BB">nil&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;FImage</span><span style="color: #007700">.</span><span style="color: #0000BB">Height&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">UpdateImageLayout</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">procedure&nbsp;TBitmapSpeedButton</span><span style="color: #007700">.</span><span style="color: #0000BB">SetImagePadding</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Single</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;FImagePadding&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">UpdateImageLayout</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">procedure&nbsp;TBitmapSpeedButton</span><span style="color: #007700">.</span><span style="color: #0000BB">SetImageWidth</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Single</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;FImageWidth&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">UpdateImageLayout</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">procedure&nbsp;TBitmapSpeedButton</span><span style="color: #007700">.</span><span style="color: #0000BB">SetTextVisible</span><span style="color: #007700">(const&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">Boolean</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;FTextVisible&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">;<br />&nbsp;&nbsp;if&nbsp;(</span><span style="color: #0000BB">FTextObject&nbsp;</span><span style="color: #007700">&lt;&gt;&nbsp;</span><span style="color: #0000BB">nil</span><span style="color: #007700">)&nbsp;and&nbsp;(</span><span style="color: #0000BB">FTextObject&nbsp;is&nbsp;TText</span><span style="color: #007700">)&nbsp;</span><span style="color: #0000BB">then<br />&nbsp;&nbsp;&nbsp;&nbsp;TText</span><span style="color: #007700">(</span><span style="color: #0000BB">FTextObject</span><span style="color: #007700">).</span><span style="color: #0000BB">Visible&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">Value</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">procedure&nbsp;TBitmapSpeedButton</span><span style="color: #007700">.</span><span style="color: #0000BB">UpdateImageLayout</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">begin<br />&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;</span><span style="color: #0000BB">FImage&nbsp;</span><span style="color: #007700">&lt;&gt;&nbsp;</span><span style="color: #0000BB">nil&nbsp;then<br />&nbsp;&nbsp;begin<br />&nbsp;&nbsp;&nbsp;&nbsp;FImage</span><span style="color: #007700">.</span><span style="color: #0000BB">Width&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">ImageWidth</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FImage</span><span style="color: #007700">.</span><span style="color: #0000BB">Height&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">ImageHeight</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;</span><span style="color: #0000BB">ImageAlign&nbsp;of<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iaLeft</span><span style="color: #007700">:</span><span style="color: #0000BB">FImageLayout</span><span style="color: #007700">.</span><span style="color: #0000BB">Align&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TAlignLayout</span><span style="color: #007700">.</span><span style="color: #0000BB">alLeft</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">iaTop</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">FImageLayout</span><span style="color: #007700">.</span><span style="color: #0000BB">Align&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TAlignLayout</span><span style="color: #007700">.</span><span style="color: #0000BB">alTop</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">iaRight</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">FImageLayout</span><span style="color: #007700">.</span><span style="color: #0000BB">Align&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TAlignLayout</span><span style="color: #007700">.</span><span style="color: #0000BB">alRight</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">iaBottom</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">FImageLayout</span><span style="color: #007700">.</span><span style="color: #0000BB">Align&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TAlignLAyout</span><span style="color: #007700">.</span><span style="color: #0000BB">alBottom</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;else<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">FImageLayout</span><span style="color: #007700">.</span><span style="color: #0000BB">Align&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">TAlignLayout</span><span style="color: #007700">.</span><span style="color: #0000BB">alCenter</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;<br />&nbsp;&nbsp;</span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br />&nbsp;&nbsp;if&nbsp;</span><span style="color: #0000BB">FImageLayout&nbsp;</span><span style="color: #007700">&lt;&gt;&nbsp;</span><span style="color: #0000BB">nil&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;</span><span style="color: #0000BB">ImageAlign&nbsp;in&nbsp;&#91;iaLeft</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">iaRight&#93;&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FImageLayout</span><span style="color: #007700">.</span><span style="color: #0000BB">Width&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">FImageWidth</span><span style="color: #007700">+</span><span style="color: #0000BB">FImagePadding</span><span style="color: #007700">*</span><span style="color: #0000BB">2<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">else&nbsp;if&nbsp;</span><span style="color: #0000BB">ImageAlign&nbsp;in&nbsp;&#91;iaTop</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">iaBottom&#93;&nbsp;then<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FImageLayout</span><span style="color: #007700">.</span><span style="color: #0000BB">Height&nbsp;</span><span style="color: #007700">:=&nbsp;</span><span style="color: #0000BB">FImageHeight</span><span style="color: #007700">+</span><span style="color: #0000BB">FImagePadding</span><span style="color: #007700">*</span><span style="color: #0000BB">2</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">initialization<br />&nbsp;&nbsp;RegisterFMXClasses</span><span style="color: #007700">(</span><span style="color: #0000BB">&#91;TBitmapSpeedButton&#93;</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">end</span><span style="color: #007700">.&nbsp;</span>
</span>
</code></div>

<p>&nbsp;</p>
	  ]]></content>
	</entry>

	<entry>
	  <title>Announcing MonkeyRecolor</title>
	  <link rel="alternate" type="text/html" href="http://monkeystyler.com/blog/entry/announcing-monkeyrecolor" />
	  <id>tag:,2011:/blog/6.15</id>
	  <published>2011-12-13T22:36:54Z</published>
	  <updated>2011-12-15T17:06:55Z</updated>
	  <author>
			<name>Mike Sutton</name>
			<email>mike@solentsoftware.com</email>
				  </author>

	  <category term="MonkeyRecolor"
		scheme="http://monkeystyler.com/news/category/recolor"
		label="MonkeyRecolor" />
	  <content type="html"><![CDATA[
		<p><img src="/images/uploads/RecolorSampleSmall.png" alt=""  /><br />
If you&#8217;ve been playing with the FireMonkey styles included with Delphi XE2 you&#8217;ve probably noticed a certain &#8216;sameness&#8217; to them. Grey styles created to match the operating systems built in ones, and dark styles with brightly colored buttons. Not a lot of variety then.</p>

<p>MonkeyRecolor is my answer to this. It is a simple product which enables you to take any FireMonkey style and radically changes it&#8217;s color scheme just by tweaking a few controls and clicking a single button. MonkeyRecolor can create serious business styles, either light or dark, or it can create bright and colorful styles which can really make your software &#8216;pop&#8217;.</p>

<p>You get a set of controls for adjusting the colors of six different elements of a scheme, from backgrounds to highlights and selections to glow effects. Hues for secondary colors can be based on the background hue, in which case MonkeyRecolor pretty much guarantees a scheme which adheres to the rules of color theory, or you can go off piste and set any colors your heart desires.</p>

<p>Subtle variations in the original schemes colors are respected and retained. For instance the subtle change of hue across a button face will be retained, albeit with a different base hue. This applies to all colors within the style. It also applies to the colors used by animations and effects.</p>

<p><img src="/images/uploads/MonkeyRecolorSmall.png" alt=""  /><br />
MonkeyRecolor is supplied as a form which you can attach to a Delphi or C++Builder project. Set a couple of properties and create a link from a menu item or button and you are ready to go. You can (and should) remove the links when you are ready to redistribute your software. The download also includes a pre-built application which can be used to load, edit and save default styles.</p>

<p>&#8216;Schemes&#8217; are settings for MonkeyRecolor. These can be saved a re-loaded so you can save data between sessions or to tweak later.</p>

<p>The application of color changes is controlled by a config file. The &#8216;language&#8217; used by the file can be used to specify almost any component or group of components and can thus be used to modify how a scheme is applied to styles.</p>

<p>MonkeyRecolor is a free application supplied with full source code. </p>

<p><a href="/recolor">Read more</a>.</p>

<p>Or see the <a href="/wiki/MonkeyRecolor">wiki</a> for instructions.</p>
	  ]]></content>
	</entry>

	<entry>
	  <title>Welcome to MonkeyStyler</title>
	  <link rel="alternate" type="text/html" href="http://monkeystyler.com/blog/entry/welcome-to-monkeystyler" />
	  <id>tag:,2011:/blog/6.14</id>
	  <published>2011-12-13T13:05:00Z</published>
	  <updated>2011-12-13T08:07:01Z</updated>
	  <author>
			<name>Mike Sutton</name>
			<email>mike@solentsoftware.com</email>
				  </author>

	  <category term="Styles"
		scheme="http://monkeystyler.com/news/category/styles"
		label="Styles" />
	  <content type="html"><![CDATA[
		<p>Hi, My name&#8217;s Mike Sutton and I&#8217;ve been working on some interesting projects associated with FireMonkey styles recently.</p>

<p>More to come soon.</p>

<p>Mike</p>
	  ]]></content>
	</entry>


</feed>
