Browse Source

Added uEcontrols
- From http://sourceforge.net/projects/uecontrols/ version 5.14. Author Miguel Alberto Risco Castillo.
- Changes: changed icon folder and components tab in register procedure, removed package units to add all the units in the bgracontrols package.

lainz 11 years ago
parent
commit
a6e3bff73f

+ 36 - 11
bgracontrols.lpk

@@ -27,7 +27,7 @@
       </Other>
     </CompilerOptions>
     <Version Major="3" Minor="1"/>
-    <Files Count="22">
+    <Files Count="27">
       <Item1>
         <Filename Value="bcbasectrls.pas"/>
         <UnitName Value="BCBaseCtrls"/>
@@ -108,30 +108,55 @@
         <UnitName Value="BGRAKnob"/>
       </Item17>
       <Item18>
-        <Filename Value="bgrashape.pas"/>
+        <Filename Value="bgraresizespeedbutton.pas"/>
         <HasRegisterProc Value="True"/>
-        <UnitName Value="BGRAShape"/>
+        <UnitName Value="bgraresizespeedbutton"/>
       </Item18>
       <Item19>
-        <Filename Value="bgraspeedbutton.pas"/>
+        <Filename Value="bgrashape.pas"/>
         <HasRegisterProc Value="True"/>
-        <UnitName Value="BGRASpeedButton"/>
+        <UnitName Value="BGRAShape"/>
       </Item19>
       <Item20>
-        <Filename Value="bgraspriteanimation.pas"/>
+        <Filename Value="bgraspeedbutton.pas"/>
         <HasRegisterProc Value="True"/>
-        <UnitName Value="BGRASpriteAnimation"/>
+        <UnitName Value="BGRASpeedButton"/>
       </Item20>
       <Item21>
-        <Filename Value="bgravirtualscreen.pas"/>
+        <Filename Value="bgraspriteanimation.pas"/>
         <HasRegisterProc Value="True"/>
-        <UnitName Value="BGRAVirtualScreen"/>
+        <UnitName Value="BGRASpriteAnimation"/>
       </Item21>
       <Item22>
-        <Filename Value="bgraresizespeedbutton.pas"/>
+        <Filename Value="bgravirtualscreen.pas"/>
         <HasRegisterProc Value="True"/>
-        <UnitName Value="bgraresizespeedbutton"/>
+        <UnitName Value="BGRAVirtualScreen"/>
       </Item22>
+      <Item23>
+        <Filename Value="ueknob.pas"/>
+        <HasRegisterProc Value="True"/>
+        <UnitName Value="uEKnob"/>
+      </Item23>
+      <Item24>
+        <Filename Value="ueled.pas"/>
+        <HasRegisterProc Value="True"/>
+        <UnitName Value="ueled"/>
+      </Item24>
+      <Item25>
+        <Filename Value="uemultiturn.pas"/>
+        <HasRegisterProc Value="True"/>
+        <UnitName Value="uEMultiTurn"/>
+      </Item25>
+      <Item26>
+        <Filename Value="uerotimage.pas"/>
+        <HasRegisterProc Value="True"/>
+        <UnitName Value="uERotImage"/>
+      </Item26>
+      <Item27>
+        <Filename Value="ueselector.pas"/>
+        <HasRegisterProc Value="True"/>
+        <UnitName Value="uESelector"/>
+      </Item27>
     </Files>
     <Type Value="RunAndDesignTime"/>
     <RequiredPkgs Count="2">

+ 9 - 3
bgracontrols.pas

@@ -10,8 +10,9 @@ uses
   BCBaseCtrls, BCButton, BCEffect, bcfilters, BCGameGrid, BCImageButton, 
   BCLabel, BCPanel, BCRTTI, BCStylesForm, BCTools, BGRAFlashProgressBar, 
   BGRAGraphicControl, BGRAImageList, BGRAImageManipulation, BGRAKnob, 
-  BGRAShape, BGRASpeedButton, BGRASpriteAnimation, BGRAVirtualScreen, 
-  BGRAResizeSpeedButton, LazarusPackageIntf;
+  BGRAResizeSpeedButton, BGRAShape, BGRASpeedButton, BGRASpriteAnimation, 
+  BGRAVirtualScreen, uEKnob, ueled, uEMultiTurn, uERotImage, uESelector, 
+  LazarusPackageIntf;
 
 implementation
 
@@ -27,11 +28,16 @@ begin
   RegisterUnit('BGRAImageList', @BGRAImageList.Register);
   RegisterUnit('BGRAImageManipulation', @BGRAImageManipulation.Register);
   RegisterUnit('BGRAKnob', @BGRAKnob.Register);
+  RegisterUnit('BGRAResizeSpeedButton', @BGRAResizeSpeedButton.Register);
   RegisterUnit('BGRAShape', @BGRAShape.Register);
   RegisterUnit('BGRASpeedButton', @BGRASpeedButton.Register);
   RegisterUnit('BGRASpriteAnimation', @BGRASpriteAnimation.Register);
   RegisterUnit('BGRAVirtualScreen', @BGRAVirtualScreen.Register);
-  RegisterUnit('BGRAResizeSpeedButton', @BGRAResizeSpeedButton.Register);
+  RegisterUnit('uEKnob', @uEKnob.Register);
+  RegisterUnit('ueled', @ueled.Register);
+  RegisterUnit('uEMultiTurn', @uEMultiTurn.Register);
+  RegisterUnit('uERotImage', @uERotImage.Register);
+  RegisterUnit('uESelector', @uESelector.Register);
 end;
 
 initialization

+ 390 - 0
docs/Mozilla Public License version 1.1.htm

@@ -0,0 +1,390 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!-- saved from url=(0031)http://www.mozilla.org/MPL/1.1/ -->
+<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <title>Mozilla Public License version 1.1</title>
+ <style type="text/css">
+  .very-strong{
+   text-transform:uppercase;
+  }
+  dt{
+   font-weight:bold;
+  }
+  dd p{
+   margin:0;
+  }
+ </style>
+<style type="text/css"></style></head>
+<body>
+ <p><small>(<a href="http://www.mozilla.org/MPL/1.1/index.txt">Plain text version</a>)</small></p>
+ <h1>Mozilla Public License Version 1.1</h1>
+ <h2 id="section-1">1. Definitions.</h2>
+ <dl>
+  <dt id="section-1.0.1">1.0.1. "Commercial Use"
+  </dt><dd>means distribution or otherwise making the Covered Code available to a third party.
+  </dd><dt id="section-1.1">1.1. "Contributor"
+  </dt><dd>means each entity that creates or contributes to the creation of Modifications.
+  </dd><dt id="section-1.2">1.2. "Contributor Version"
+  </dt><dd>means the combination of the Original Code, prior Modifications used by a Contributor,
+   and the Modifications made by that particular Contributor.
+  </dd><dt id="section-1.3">1.3. "Covered Code"
+  </dt><dd>means the Original Code or Modifications or the combination of the Original Code and
+   Modifications, in each case including portions thereof.
+  </dd><dt id="section-1.4">1.4. "Electronic Distribution Mechanism"
+  </dt><dd>means a mechanism generally accepted in the software development community for the
+   electronic transfer of data.
+  </dd><dt id="section-1.5">1.5. "Executable"
+  </dt><dd>means Covered Code in any form other than Source Code.
+  </dd><dt id="section-1.6">1.6. "Initial Developer"
+  </dt><dd>means the individual or entity identified as the Initial Developer in the Source Code
+   notice required by <a href="http://www.mozilla.org/MPL/1.1/#exhibit-a">Exhibit A</a>.
+  </dd><dt id="section-1.7">1.7. "Larger Work"
+  </dt><dd>means a work which combines Covered Code or portions thereof with code not governed
+   by the terms of this License.
+  </dd><dt id="section-1.8">1.8. "License"
+  </dt><dd>means this document.
+  </dd><dt id="section-1.8.1">1.8.1. "Licensable"
+  </dt><dd>means having the right to grant, to the maximum extent possible, whether at the
+   time of the initial grant or subsequently acquired, any and all of the rights
+   conveyed herein.
+  </dd><dt id="section-1.9">1.9. "Modifications"
+  </dt><dd>
+   <p>means any addition to or deletion from the substance or structure of either the
+    Original Code or any previous Modifications. When Covered Code is released as a
+    series of files, a Modification is:
+   </p><ol type="a">
+    <li id="section-1.9-a">Any addition to or deletion from the contents of a file
+     containing Original Code or previous Modifications.
+    </li><li id="section-1.9-b">Any new file that contains any part of the Original Code or
+     previous Modifications.
+   </li></ol>
+  </dd><dt id="section-1.10">1.10. "Original Code"
+  </dt><dd>means Source Code of computer software code which is described in the Source Code
+   notice required by <a href="http://www.mozilla.org/MPL/1.1/#exhibit-a">Exhibit A</a> as Original Code, and which,
+   at the time of its release under this License is not already Covered Code governed
+   by this License.
+  </dd><dt id="section-1.10.1">1.10.1. "Patent Claims"
+  </dt><dd>means any patent claim(s), now owned or hereafter acquired, including without
+   limitation, method, process, and apparatus claims, in any patent Licensable by
+   grantor.
+  </dd><dt id="section-1.11">1.11. "Source Code"
+  </dt><dd>means the preferred form of the Covered Code for making modifications to it,
+   including all modules it contains, plus any associated interface definition files,
+   scripts used to control compilation and installation of an Executable, or source
+   code differential comparisons against either the Original Code or another well known,
+   available Covered Code of the Contributor's choice. The Source Code can be in a
+   compressed or archival form, provided the appropriate decompression or de-archiving
+   software is widely available for no charge.
+  </dd><dt id="section-1.12">1.12. "You" (or "Your")
+  </dt><dd>means an individual or a legal entity exercising rights under, and complying with
+   all of the terms of, this License or a future version of this License issued under
+   <a href="http://www.mozilla.org/MPL/1.1/#section-6.1">Section 6.1.</a> For legal entities, "You" includes any entity
+   which controls, is controlled by, or is under common control with You. For purposes of
+   this definition, "control" means (a) the power, direct or indirect, to cause the
+   direction or management of such entity, whether by contract or otherwise, or (b)
+   ownership of more than fifty percent (50%) of the outstanding shares or beneficial
+   ownership of such entity.
+ </dd></dl>
+ <h2 id="section-2">2. Source Code License.</h2>
+ <h3 id="section-2.1">2.1. The Initial Developer Grant.</h3>
+ <p>The Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive
+  license, subject to third party intellectual property claims:
+ </p><ol type="a">
+  <li id="section-2.1-a">under intellectual property rights (other than patent or
+   trademark) Licensable by Initial Developer to use, reproduce, modify, display, perform,
+   sublicense and distribute the Original Code (or portions thereof) with or without
+   Modifications, and/or as part of a Larger Work; and
+  </li><li id="section-2.1-b">under Patents Claims infringed by the making, using or selling
+   of Original Code, to make, have made, use, practice, sell, and offer for sale, and/or
+   otherwise dispose of the Original Code (or portions thereof).
+  </li><li id="section-2.1-c">the licenses granted in this Section 2.1
+   (<a href="http://www.mozilla.org/MPL/1.1/#section-2.1-a">a</a>) and (<a href="http://www.mozilla.org/MPL/1.1/#section-2.1-b">b</a>) are effective on
+   the date Initial Developer first distributes Original Code under the terms of this
+   License.
+  </li><li id="section-2.1-d">Notwithstanding Section 2.1 (<a href="http://www.mozilla.org/MPL/1.1/#section-2.1-b">b</a>)
+   above, no patent license is granted: 1) for code that You delete from the Original Code;
+   2) separate from the Original Code; or 3) for infringements caused by: i) the
+   modification of the Original Code or ii) the combination of the Original Code with other
+   software or devices.
+ </li></ol>
+ <h3 id="section-2.2">2.2. Contributor Grant.</h3>
+ <p>Subject to third party intellectual property claims, each Contributor hereby grants You
+  a world-wide, royalty-free, non-exclusive license
+ </p><ol type="a">
+  <li id="section-2.2-a">under intellectual property rights (other than patent or trademark)
+   Licensable by Contributor, to use, reproduce, modify, display, perform, sublicense and
+   distribute the Modifications created by such Contributor (or portions thereof) either on
+   an unmodified basis, with other Modifications, as Covered Code and/or as part of a Larger
+   Work; and
+  </li><li id="section-2.2-b">under Patent Claims infringed by the making, using, or selling of
+   Modifications made by that Contributor either alone and/or in combination with its
+   Contributor Version (or portions of such combination), to make, use, sell, offer for
+   sale, have made, and/or otherwise dispose of: 1) Modifications made by that Contributor
+   (or portions thereof); and 2) the combination of Modifications made by that Contributor
+   with its Contributor Version (or portions of such combination).
+  </li><li id="section-2.2-c">the licenses granted in Sections 2.2
+   (<a href="http://www.mozilla.org/MPL/1.1/#section-2.2-a">a</a>) and 2.2 (<a href="http://www.mozilla.org/MPL/1.1/#section-2.2-b">b</a>) are effective
+   on the date Contributor first makes Commercial Use of the Covered Code.
+  </li><li id="section-2.2-d">Notwithstanding Section 2.2 (<a href="http://www.mozilla.org/MPL/1.1/#section-2.2-b">b</a>)
+   above, no patent license is granted: 1) for any code that Contributor has deleted from
+   the Contributor Version; 2) separate from the Contributor Version; 3) for infringements
+   caused by: i) third party modifications of Contributor Version or ii) the combination of
+   Modifications made by that Contributor with other software (except as part of the
+   Contributor Version) or other devices; or 4) under Patent Claims infringed by Covered Code
+   in the absence of Modifications made by that Contributor.
+ </li></ol>
+ <h2 id="section-3">3. Distribution Obligations.</h2>
+ <h3 id="section-3.1">3.1. Application of License.</h3>
+ <p>The Modifications which You create or to which You contribute are governed by the terms
+  of this License, including without limitation Section <a href="http://www.mozilla.org/MPL/1.1/#section-2.2">2.2</a>. The
+  Source Code version of Covered Code may be distributed only under the terms of this License
+  or a future version of this License released under Section <a href="http://www.mozilla.org/MPL/1.1/#section-6.1">6.1</a>,
+  and You must include a copy of this License with every copy of the Source Code You
+  distribute. You may not offer or impose any terms on any Source Code version that alters or
+  restricts the applicable version of this License or the recipients' rights hereunder.
+  However, You may include an additional document offering the additional rights described in
+  Section <a href="http://www.mozilla.org/MPL/1.1/#section-3.5">3.5</a>.
+ </p><h3 id="section-3.2">3.2. Availability of Source Code.</h3>
+ <p>Any Modification which You create or to which You contribute must be made available in
+  Source Code form under the terms of this License either on the same media as an Executable
+  version or via an accepted Electronic Distribution Mechanism to anyone to whom you made an
+  Executable version available; and if made available via Electronic Distribution Mechanism,
+  must remain available for at least twelve (12) months after the date it initially became
+  available, or at least six (6) months after a subsequent version of that particular
+  Modification has been made available to such recipients. You are responsible for ensuring
+  that the Source Code version remains available even if the Electronic Distribution
+  Mechanism is maintained by a third party.
+ </p><h3 id="section-3.3">3.3. Description of Modifications.</h3>
+ <p>You must cause all Covered Code to which You contribute to contain a file documenting the
+  changes You made to create that Covered Code and the date of any change. You must include a
+  prominent statement that the Modification is derived, directly or indirectly, from Original
+  Code provided by the Initial Developer and including the name of the Initial Developer in
+  (a) the Source Code, and (b) in any notice in an Executable version or related documentation
+  in which You describe the origin or ownership of the Covered Code.
+ </p><h3 id="section-3.4">3.4. Intellectual Property Matters</h3>
+ <h4 id="section-3.4-a">(a) Third Party Claims</h4>
+ <p>If Contributor has knowledge that a license under a third party's intellectual property
+  rights is required to exercise the rights granted by such Contributor under Sections
+  <a href="http://www.mozilla.org/MPL/1.1/#section-2.1">2.1</a> or <a href="http://www.mozilla.org/MPL/1.1/#section-2.2">2.2</a>, Contributor must include a
+  text file with the Source Code distribution titled "LEGAL" which describes the claim and the
+  party making the claim in sufficient detail that a recipient will know whom to contact. If
+  Contributor obtains such knowledge after the Modification is made available as described in
+  Section <a href="http://www.mozilla.org/MPL/1.1/#section-3.2">3.2</a>, Contributor shall promptly modify the LEGAL file in
+  all copies Contributor makes available thereafter and shall take other steps (such as
+  notifying appropriate mailing lists or newsgroups) reasonably calculated to inform those who
+  received the Covered Code that new knowledge has been obtained.
+ </p><h4 id="section-3.4-b">(b) Contributor APIs</h4>
+ <p>If Contributor's Modifications include an application programming interface and Contributor
+  has knowledge of patent licenses which are reasonably necessary to implement that
+  <abbr>API</abbr>, Contributor must also include this information in the
+  <strong class="very-strong">legal</strong> file.
+ </p><h4 id="section-3.4-c">(c) Representations.</h4>
+ <p>Contributor represents that, except as disclosed pursuant to Section 3.4
+  (<a href="http://www.mozilla.org/MPL/1.1/#section-3.4-a">a</a>) above, Contributor believes that Contributor's Modifications
+  are Contributor's original creation(s) and/or Contributor has sufficient rights to grant the
+  rights conveyed by this License.
+ </p><h3 id="section-3.5">3.5. Required Notices.</h3>
+ <p>You must duplicate the notice in <a href="http://www.mozilla.org/MPL/1.1/#exhibit-a">Exhibit A</a> in each file of the
+  Source Code. If it is not possible to put such notice in a particular Source Code file due to
+  its structure, then You must include such notice in a location (such as a relevant directory)
+  where a user would be likely to look for such a notice. If You created one or more
+  Modification(s) You may add your name as a Contributor to the notice described in
+  <a href="http://www.mozilla.org/MPL/1.1/#exhibit-a">Exhibit A</a>. You must also duplicate this License in any documentation
+  for the Source Code where You describe recipients' rights or ownership rights relating to
+  Covered Code. You may choose to offer, and to charge a fee for, warranty, support, indemnity
+  or liability obligations to one or more recipients of Covered Code. However, You may do so
+  only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You
+  must make it absolutely clear than any such warranty, support, indemnity or liability
+  obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer
+  and every Contributor for any liability incurred by the Initial Developer or such Contributor
+  as a result of warranty, support, indemnity or liability terms You offer.
+ </p><h3 id="section-3.6">3.6. Distribution of Executable Versions.</h3>
+ <p>You may distribute Covered Code in Executable form only if the requirements of Sections
+  <a href="http://www.mozilla.org/MPL/1.1/#section-3.1">3.1</a>, <a href="http://www.mozilla.org/MPL/1.1/#section-3.2">3.2</a>,
+  <a href="http://www.mozilla.org/MPL/1.1/#section-3.3">3.3</a>, <a href="http://www.mozilla.org/MPL/1.1/#section-3.4">3.4</a> and
+  <a href="http://www.mozilla.org/MPL/1.1/#section-3.5">3.5</a> have been met for that Covered Code, and if You include a
+  notice stating that the Source Code version of the Covered Code is available under the terms
+  of this License, including a description of how and where You have fulfilled the obligations
+  of Section <a href="http://www.mozilla.org/MPL/1.1/#section-3.2">3.2</a>. The notice must be conspicuously included in any
+  notice in an Executable version, related documentation or collateral in which You describe
+  recipients' rights relating to the Covered Code. You may distribute the Executable version of
+  Covered Code or ownership rights under a license of Your choice, which may contain terms
+  different from this License, provided that You are in compliance with the terms of this
+  License and that the license for the Executable version does not attempt to limit or alter the
+  recipient's rights in the Source Code version from the rights set forth in this License. If
+  You distribute the Executable version under a different license You must make it absolutely
+  clear that any terms which differ from this License are offered by You alone, not by the
+  Initial Developer or any Contributor. You hereby agree to indemnify the Initial Developer and
+  every Contributor for any liability incurred by the Initial Developer or such Contributor as
+  a result of any such terms You offer.
+ </p><h3 id="section-3.7">3.7. Larger Works.</h3>
+ <p>You may create a Larger Work by combining Covered Code with other code not governed by the
+  terms of this License and distribute the Larger Work as a single product. In such a case,
+  You must make sure the requirements of this License are fulfilled for the Covered Code.
+ </p><h2 id="section-4">4. Inability to Comply Due to Statute or Regulation.</h2>
+ <p>If it is impossible for You to comply with any of the terms of this License with respect to
+  some or all of the Covered Code due to statute, judicial order, or regulation then You must:
+  (a) comply with the terms of this License to the maximum extent possible; and (b) describe
+  the limitations and the code they affect. Such description must be included in the
+  <strong class="very-strong">legal</strong> file described in Section
+  <a href="http://www.mozilla.org/MPL/1.1/#section-3.4">3.4</a> and must be included with all distributions of the Source Code.
+  Except to the extent prohibited by statute or regulation, such description must be
+  sufficiently detailed for a recipient of ordinary skill to be able to understand it.
+ </p><h2 id="section-5">5. Application of this License.</h2>
+ <p>This License applies to code to which the Initial Developer has attached the notice in
+  <a href="http://www.mozilla.org/MPL/1.1/#exhibit-a">Exhibit A</a> and to related Covered Code.
+ </p><h2 id="section-6">6. Versions of the License.</h2>
+ <h3 id="section-6.1">6.1. New Versions</h3>
+ <p>Netscape Communications Corporation ("Netscape") may publish revised and/or new versions
+  of the License from time to time. Each version will be given a distinguishing version number.
+ </p><h3 id="section-6.2">6.2. Effect of New Versions</h3>
+ <p>Once Covered Code has been published under a particular version of the License, You may
+  always continue to use it under the terms of that version. You may also choose to use such
+  Covered Code under the terms of any subsequent version of the License published by Netscape.
+  No one other than Netscape has the right to modify the terms applicable to Covered Code
+  created under this License.
+ </p><h3 id="section-6.3">6.3. Derivative Works</h3>
+ <p>If You create or use a modified version of this License (which you may only do in order to
+ apply it to code which is not already Covered Code governed by this License), You must (a)
+ rename Your license so that the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", "MPL",
+ "NPL" or any confusingly similar phrase do not appear in your license (except to note that
+ your license differs from this License) and (b) otherwise make it clear that Your version of
+ the license contains terms which differ from the Mozilla Public License and Netscape Public
+ License. (Filling in the name of the Initial Developer, Original Code or Contributor in the
+ notice described in <a href="http://www.mozilla.org/MPL/1.1/#exhibit-a">Exhibit A</a> shall not of themselves be deemed to
+ be modifications of this License.)
+ </p><h2 id="section-7">7. <strong class="very-strong">Disclaimer of warranty</strong></h2>
+ <p><strong class="very-strong">Covered code is provided under this license on an "as is"
+  basis, without warranty of any kind, either expressed or implied, including, without
+  limitation, warranties that the covered code is free of defects, merchantable, fit for a
+  particular purpose or non-infringing. The entire risk as to the quality and performance of
+  the covered code is with you. Should any covered code prove defective in any respect, you
+  (not the initial developer or any other contributor) assume the cost of any necessary
+  servicing, repair or correction. This disclaimer of warranty constitutes an essential part
+  of this license. No use of any covered code is authorized hereunder except under this
+  disclaimer.</strong>
+ </p><h2 id="section-8">8. Termination</h2>
+ <p id="section-8.1">8.1. This License and the rights granted hereunder will terminate
+  automatically if You fail to comply with terms herein and fail to cure such breach
+  within 30 days of becoming aware of the breach. All sublicenses to the Covered Code which
+  are properly granted shall survive any termination of this License. Provisions which, by
+  their nature, must remain in effect beyond the termination of this License shall survive.
+ </p><p id="section-8.2">8.2. If You initiate litigation by asserting a patent infringement
+  claim (excluding declatory judgment actions) against Initial Developer or a Contributor
+  (the Initial Developer or Contributor against whom You file such action is referred to
+  as "Participant") alleging that:
+ </p><ol type="a">
+  <li id="section-8.2-a">such Participant's Contributor Version directly or indirectly
+   infringes any patent, then any and all rights granted by such Participant to You under
+   Sections <a href="http://www.mozilla.org/MPL/1.1/#section-2.1">2.1</a> and/or <a href="http://www.mozilla.org/MPL/1.1/#section-2.2">2.2</a> of this
+   License shall, upon 60 days notice from Participant terminate prospectively, unless if
+   within 60 days after receipt of notice You either: (i) agree in writing to pay
+   Participant a mutually agreeable reasonable royalty for Your past and future use of
+   Modifications made by such Participant, or (ii) withdraw Your litigation claim with
+   respect to the Contributor Version against such Participant. If within 60 days of
+   notice, a reasonable royalty and payment arrangement are not mutually agreed upon in
+   writing by the parties or the litigation claim is not withdrawn, the rights granted by
+   Participant to You under Sections <a href="http://www.mozilla.org/MPL/1.1/#section-2.1">2.1</a> and/or
+   <a href="http://www.mozilla.org/MPL/1.1/#section-2.2">2.2</a> automatically terminate at the expiration of the 60 day
+   notice period specified above.
+  </li><li id="section-8.2-b">any software, hardware, or device, other than such Participant's
+   Contributor Version, directly or indirectly infringes any patent, then any rights
+   granted to You by such Participant under Sections 2.1(<a href="http://www.mozilla.org/MPL/1.1/#section-2.1-b">b</a>)
+   and 2.2(<a href="http://www.mozilla.org/MPL/1.1/#section-2.2-b">b</a>) are revoked effective as of the date You first
+   made, used, sold, distributed, or had made, Modifications made by that Participant.
+ </li></ol>
+ <p id="section-8.3">8.3. If You assert a patent infringement claim against Participant
+  alleging that such Participant's Contributor Version directly or indirectly infringes
+  any patent where such claim is resolved (such as by license or settlement) prior to the
+  initiation of patent infringement litigation, then the reasonable value of the licenses
+  granted by such Participant under Sections <a href="http://www.mozilla.org/MPL/1.1/#section-2.1">2.1</a> or
+  <a href="http://www.mozilla.org/MPL/1.1/#section-2.2">2.2</a> shall be taken into account in determining the amount or
+  value of any payment or license.
+ </p><p id="section-8.4">8.4. In the event of termination under Sections
+  <a href="http://www.mozilla.org/MPL/1.1/#section-8.1">8.1</a> or <a href="http://www.mozilla.org/MPL/1.1/#section-8.2">8.2</a> above, all end user
+  license agreements (excluding distributors and resellers) which have been validly
+  granted by You or any distributor hereunder prior to termination shall survive
+  termination.
+ </p><h2 id="section-9">9. <strong class="very-strong">Limitation of liability</strong></h2>
+ <p><strong class="very-strong">Under no circumstances and under no legal theory, whether
+  tort (including negligence), contract, or otherwise, shall you, the initial developer,
+  any other contributor, or any distributor of covered code, or any supplier of any of
+  such parties, be liable to any person for any indirect, special, incidental, or
+  consequential damages of any character including, without limitation, damages for loss
+  of goodwill, work stoppage, computer failure or malfunction, or any and all other
+  commercial damages or losses, even if such party shall have been informed of the
+  possibility of such damages. This limitation of liability shall not apply to liability
+  for death or personal injury resulting from such party's negligence to the extent
+  applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion
+  or limitation of incidental or consequential damages, so this exclusion and limitation
+  may not apply to you.</strong>
+ </p><h2 id="section-10">10. <abbr title="United States">U.S.</abbr> government end users</h2>
+ <p>The Covered Code is a "commercial item," as that term is defined in 48
+  <abbr>C.F.R.</abbr> 2.101 (<abbr title="October">Oct.</abbr> 1995), consisting of
+  "commercial computer software" and "commercial computer software documentation," as such
+  terms are used in 48 <abbr>C.F.R.</abbr> 12.212 (<abbr title="September">Sept.</abbr>
+  1995). Consistent with 48 <abbr>C.F.R.</abbr> 12.212 and 48 <abbr>C.F.R.</abbr>
+  227.7202-1 through 227.7202-4 (June 1995), all <abbr>U.S.</abbr> Government End Users
+  acquire Covered Code with only those rights set forth herein.
+ </p><h2 id="section-11">11. Miscellaneous</h2>
+ <p>This License represents the complete agreement concerning subject matter hereof. If
+  any provision of this License is held to be unenforceable, such provision shall be
+  reformed only to the extent necessary to make it enforceable. This License shall be
+  governed by California law provisions (except to the extent applicable law, if any,
+  provides otherwise), excluding its conflict-of-law provisions. With respect to
+  disputes in which at least one party is a citizen of, or an entity chartered or
+  registered to do business in the United States of America, any litigation relating to
+  this License shall be subject to the jurisdiction of the Federal Courts of the
+  Northern District of California, with venue lying in Santa Clara County, California,
+  with the losing party responsible for costs, including without limitation, court
+  costs and reasonable attorneys' fees and expenses. The application of the United
+  Nations Convention on Contracts for the International Sale of Goods is expressly
+  excluded. Any law or regulation which provides that the language of a contract
+  shall be construed against the drafter shall not apply to this License.
+ </p><h2 id="section-12">12. Responsibility for claims</h2>
+ <p>As between Initial Developer and the Contributors, each party is responsible for
+  claims and damages arising, directly or indirectly, out of its utilization of rights
+  under this License and You agree to work with Initial Developer and Contributors to
+  distribute such responsibility on an equitable basis. Nothing herein is intended or
+  shall be deemed to constitute any admission of liability.
+ </p><h2 id="section-13">13. Multiple-licensed code</h2>
+ <p>Initial Developer may designate portions of the Covered Code as
+  "Multiple-Licensed". "Multiple-Licensed" means that the Initial Developer permits
+  you to utilize portions of the Covered Code under Your choice of the <abbr>MPL</abbr>
+  or the alternative licenses, if any, specified by the Initial Developer in the file
+  described in <a href="http://www.mozilla.org/MPL/1.1/#exhibit-a">Exhibit A</a>.
+ </p><h2 id="exhibit-a">Exhibit A - Mozilla Public License.</h2>
+ <pre>"The contents of this file are subject to the Mozilla Public License
+Version 1.1 (the "License"); you may not use this file except in
+compliance with the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/
+
+Software distributed under the License is distributed on an "AS IS"
+basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+License for the specific language governing rights and limitations
+under the License.
+
+The Original Code is ______________________________________.
+
+The Initial Developer of the Original Code is ________________________.
+Portions created by ______________________ are Copyright (C) ______
+_______________________. All Rights Reserved.
+
+Contributor(s): ______________________________________.
+
+Alternatively, the contents of this file may be used under the terms
+of the _____ license (the  "[___] License"), in which case the
+provisions of [______] License are applicable instead of those
+above. If you wish to allow use of your version of this file only
+under the terms of the [____] License and not to allow others to use
+your version of this file under the MPL, indicate your decision by
+deleting the provisions above and replace them with the notice and
+other provisions required by the [___] License. If you do not delete
+the provisions above, a recipient may use your version of this file
+under either the MPL or the [___] License."</pre>
+ <p>NOTE: The text of this Exhibit A may differ slightly from the text of
+  the notices in the Source Code files of the Original Code. You should
+  use the text of this Exhibit A rather than the text found in the
+  Original Code Source Code for Your Modifications.
+
+
+</p></body></html>

+ 5 - 1
docs/readme.txt

@@ -49,4 +49,8 @@ BGRA Controls
 - Contributor to BCButton functionality.
 
 == Author: helix2001 ==
-- TBGRAResizeSpeedButton.
+- TBGRAResizeSpeedButton.
+
+== uEcontrols ==
+- From http://sourceforge.net/projects/uecontrols/ version 5.14. Author Miguel Alberto Risco Castillo.
+- Changes: changed icon folder and components tab in register procedure, removed package units to add all the units in the bgracontrols package.

+ 41 - 0
icons/ueknob_icon.lrs

@@ -0,0 +1,41 @@
+LazarusResources.Add('tueknob','PNG',[
+  #137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#24#0#0#0#24#8#6#0#0#0#224'w='#248#0
+  +#0#0#4'sBIT'#8#8#8#8'|'#8'd'#136#0#0#0#9'pHYs'#0#0#11#18#0#0#11#18#1#210#221
+  +'~'#252#0#0#0#22'tEXtCreation Time'#0'08/16/10,"'#238'*'#0#0#0#28'tEXtSoftwa'
+  +'re'#0'Adobe Fireworks CS4'#6#178#211#160#0#0#3'8IDATH'#137#181#149'=HcY'#20
+  +#199#127#215'|'#25#19#243#177'Et'#132'`'#145#247','#6'%k'#243'RH'#146'!'#237
+  +' '#194'4'#3#179#141#194#134#129')'#151#213'b'#251#173#167'O'#154'a'#171'-'
+  +#167#221'.!'#133'k3'#248'E`'#137#22#138'H0Q'#226#203#231'3'#155#156'-'#214#4
+  +#157'}3'#171#3#30'8'#205#187#247#254#127#156's'#207#253'?%"<eL<f'#179'R*'#173
+  +#148'z'#241'd'#0#224#251#219'|2'#192#227'CD'#238'%P'#2#158#221#249#182'."'#31
+  +#229#191#241#241'vmt'#238';'#224#15#224#249'=='#27#192'+'#224'S&'#147'I'#138
+  +#200'n.'#151#19'M'#211#4#184#151#154#166'I.'#151#19#17#217#221#216#216'x'#14
+  +#252#14#252#4#184#191#10#16#17#150#150#150#222#180'Z'#173#155'T*%J)'#9#4#2
+  +#162'i'#154#24#134'!'#137'DB4M'#19#191#223'/J)I'#165'R'#210'l6'#251#177'X'
+  +#236'g;-'#245#133'1'#221'M'#167#211#241#237#237'm'#230#231#231#137'F'#163#248
+  +'|>'#220'n7J)'#6#131#1#221'n'#151#147#147#19'*'#149#10'+++'#20#139#197'=l'#6
+  +#192'i#'#190#158#207#231#227#165'R'#137'X,F,'#22'#'#24#12#226#243#249#240'x<'
+  +'LLL'#140#1'SSS'#136#8#165'R'#137'|>'#31#207'f'#179#235#192#135#187'bv'#21#20
+  +'t]OW'#171'U'#12#195' '#18#137#16#10#133#8#4#2'x'#189'^'#28#14#7#253'~'#159
+  +'V'#171#197#245#245'5'#181'Z'#141'B'#161#192#204#204#12#149'J'#165#8#188#248
+  +#191#10#210'GGG'#232#186'N '#16'`zz'#154'p8L('#20#194#239#247#227't:'#177','
+  +#11#183#219#13'@'#191#223''''#26#141'R.'#151#1#210#182'-RJ'#165'G'#253#27'U4'
+  +';;'#203#228#228'$^'#175#23#191#223'?'#134#184#221'n'#218#237'6'#0#150'e'#209
+  +'n'#183#153#155#155#27#1'PJ'#253'x'#171'}("'#127#142#30#154#186#147#140'@'#14
+  +#135#3#151#203#133#203#229#194#227#241#16#12#6#137'D"'#227#11'w'#185'\8'#157
+  +'N'#156#206'{'#141#152#185#205#208#184#2#17')'#0#133#219#13#239#1'.//'#137'F'
+  +#163#12#135'C'#134#195'!'#131#193#0#203#178#0#184#185#185'a0'#24#140#215#206
+  +#206#206#198#234'"'#242#235']'#154#157'U'#20'5M'#227#252#252#156'^'#175'G'
+  +#175#215#163#211#233'`'#154'&'#245'z'#157'j'#181'J'#163#209#160#213'j'#209
+  +#237'v'#233't:'#156#158#158#162#235':@'#241's1;'#192#135#173#173'-L'#211#228
+  +#248#248'x<-WWW'#188'{'#243#142#183#175#223'R'#171#213'h4'#26#152#166#201#225
+  +#225'!'#205'f'#147#205#205'M'#248'lD'#191#8#200'f'#179'{'#201'd'#146'r'#185
+  +#204#193#193#1#245'z'#157'z'#189'>~'#157#23#23#23'T'#171'Uvvv'#216#223#223
+  +''''#153'L'#146#205'f'#247#236#0#182'V'#145#201'd'#146#237'v'#219#186'k'#21
+  +#203#203#203#178#182#182'&'#171#171#171#18#143#199'%'#28#14#139'RJ'#210#233
+  +#180#152#166#249#183'a'#24'/'#237#180#236#204#238#25#240'iqq'#241#135#145#217
+  +#233#186'.'#128'('#165'D)%'#128',,,H>'#159#23#17#217'5'#12#227'%'#240#27#144
+  +'x'#8#160#4#188#250#6#187'N'#252#219#144#135#153#157'm('#165'^'#3'q'#17#249
+  +#229#161'g'#158#252#143'f'#231'E_'#139#191#0#235'1'#7#30#213#162'o'#137#127#0
+  +#222#216'W'#156'o'#28''''#195#0#0#0#0'IEND'#174'B`'#130
+]);

+ 35 - 0
icons/ueled_icon.lrs

@@ -0,0 +1,35 @@
+LazarusResources.Add('tueled','PNG',[
+  #137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#24#0#0#0#24#8#6#0#0#0#224'w='#248#0
+  +#0#0#4'sBIT'#8#8#8#8'|'#8'd'#136#0#0#0#9'pHYs'#0#0#11#18#0#0#11#18#1#210#221
+  +'~'#252#0#0#0#22'tEXtCreation Time'#0'08/16/10,"'#238'*'#0#0#0#28'tEXtSoftwa'
+  +'re'#0'Adobe Fireworks CS4'#6#178#211#160#0#0#2#164'IDATH'#137#213#149'MkSA'
+  +#20#134#159'3'#247#166#149#6'l'#181#214'Rl'#161#173'Q'#20#193#162#160#171#214
+  +'.'#220#248#3'\'#232#206#127#225'B\'#137#224#207#168'{]'#184'r'#231#162'q!'
+  +#174#252#194#250#17'K'#173#17'i'#11'1*'#141#201#157#153's\$JL'#147#162'h'#5
+  +#207'r'#238#225'y'#238#153#185#247#29'13v'#178#220#142#210#255#133' '#237#245
+  +'`ED'#128'='#192'~`'#0#200'u'#180'x'#160#6#172#3#31'''{'#236#181't[o'#193'G'
+  +#128'C'#192'80'#4#244'w'#180'5'#128'*P'#6'^'#3#27#221'$[&h'#131#31#5#10'%8'
+  +#191#12's'#27#144'o'#239#27#129#205'i('#22#224#214'w'#206#138#200#22#201'O'
+  +#19't'#192#15#23#225#218';'#24#29#6'&D'#216''''#130#0'kf'#172#154'Q'#5'&`m'
+  +#14#174#2#175#128#165#206'I:'#5'{['#240'#E'#184#190#6#163#199#210#148'C'#179
+  +#179#12#158'=K~~'#30#128#218#226'"'#159#238#221#227'U'#177#200'S'#239#25'kJ'
+  +#174#0'/'#128#165'I'#179'J/'#193#17'`'#166#4#151#30#194#185#19#253#253#156
+  +#186'q'#131#220#240'0'#206'9'#4'@'#4'3'#195#204#8#149#10#15'._'#230'Q'#189
+  +#206'i'#184'['#128#155#192#227'I'#179#23#189#206'`'#0#24'Z'#134#185'!'#224
+  +#216#133#11'X'#165#130'V'#171#144'$8'#17#0#204#12'U'#197#204'8~'#241'"+'#11
+  +#11','#155#157')'#192#157#22#163#231'!'#231#128#254#13#200#207#136#224'j5'
+  +#180'TB'#147#4#151#166#136's '#2#170#16'#'#26'#I'#140'L8'#199#147#24#243'4'
+  +#191#180#220'v'#130#31'5'#150'$|'#189#127#31'7>N'#146#203'!'#185#28'I'#146' '
+  +#206#17'c$'#134#128'yO'#163'\f,My'#18'cWNO'#129#138#192#231#207#132'7oHw'#237
+  +#130#190'>'#146#190'>'#210'$'#161#225'='#150'e'#196'z'#29#171#215#183#141#131
+  +#158#130#245#24#25'4'#3'U,'#4#204'9'#162's'#160#138'z'#223'\S'#5#160#220#227
+  +#237#187#9'<'#208#24#129#205'U'#179#252#148#25'Q'#149#168#138#15#1#0#17'!'
+  +#170#18'bDU'#241#170#188#141#145#17#216#164#249'w'#251'v`'#231't5'#160':'#13
+  +#139#31#205'x'#235'=!F|'#8'd!P'#207'2'#234'YF#'#203#200#188#199#135'@'#169
+  +#209#224#139#25#211#176'H3:j'#219'M'#176#14#148#11'p'#251#3#156'|'#22#194'('
+  +#192'4'#160#170'$'#206'!"'#168#25'Y'#8#188#204'2'#158'{'#207#4#172#21#224'6'
+  +#205'\Zo'#7#254'RT'#236#22'a*M9'#144#166'D'#224'}'#8#148'c'#164#170#250'{Q'
+  +#209'E'#242'S'#216'I'#171#199#128#253#173#176';'#216#12#187'R7xWA'#135#228
+  +#143#227#186#171#160'M'#178'3'#23#206#223#172#255#255#210#255#6#221'O{'#0#13
+  +#210'x'#142#0#0#0#0'IEND'#174'B`'#130
+]);

+ 45 - 0
icons/uemultiturn_icon.lrs

@@ -0,0 +1,45 @@
+LazarusResources.Add('tuemultiturn','PNG',[
+  #137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#24#0#0#0#24#8#6#0#0#0#224'w='#248#0
+  +#0#0#4'sBIT'#8#8#8#8'|'#8'd'#136#0#0#0#9'pHYs'#0#0#11#18#0#0#11#18#1#210#221
+  +'~'#252#0#0#0#22'tEXtCreation Time'#0'08/16/10,"'#238'*'#0#0#0#28'tEXtSoftwa'
+  +'re'#0'Adobe Fireworks CS4'#6#178#211#160#0#0#3#170'IDATH'#137#181#150#205'K'
+  +'kW'#20#197#127#199'$'#198#24#205#135'b'#162'B'#240#181#185'q'#162#16'm!'#22
+  +'-'#201#168#212#18#196#14#10#165'P'#168#19#223#235'?'#160#240#6#133#210#127
+  +#162'%'#129#199'k'#7#143'b'#7#181#147'Nk'#8'h'#7#29'D'#20#161'$'#22#20#209'|'
+  +#168#205'Kb>'#212#184';H'#12#215#24'_;'#168#11'6'#220's'#207'=k'#221's'#246
+  +#218#251'^%"<&'#186#30#149#29'0v'#186#169#148#186#189't'#3#159#3#211#192#219
+  +'m'#143#197#128#239'D'#228#224'M'#2#170#253#136't'#228#207#128'O'#128'c'#224
+  +'w`'#187'y'#173#0#23' @JD'#206#223#184#5#17'iE'#19'V'#224#7'`'#13#248#232#232
+  +#232#232#153#136#172#203'}'#172#139#200#146'~}'#167'h'''#7#248#9'x'#17#14#135
+  +#167'D$'#17#137'DD'#211'4i'#190'q+4M'#147'H$""'#146#16#17#199#127#21#248#18
+  +'Xk'#146#231#131#193#160'('#165#196'f'#179#137#166'i'#18#8#4'dffF4M'#147#190
+  +#190'>QJI0'#24#20#17#201'?$'#210#202#129'Rj'#24#248#21#248'FD'#190#14#133'B'
+  +#254#173#173'-'#198#198#198#240'x<X'#173'V'#186#187#187'QJQ'#175#215#169'T*'
+  +#28#28#28#144'L&'#153#155#155'#'#22#139'm'#3'S'#237')'#208#187#232#11#224#207
+  +'L&'#227#138'F'#163#254'x<'#142#215#235#197#235#245'b'#183#219#177'Z'#173#152
+  +#205'f'#186#186#186'Z'#2#189#189#189#136#8#241'x'#156'h4'#234'_^^^'#2'^vt'
+  +#145'Rj'#13#248'MD>'#245#249'|'#161't:M '#16#192#229'r'#225'p8'#176#217'lX,'
+  +#22#12#6#3'WWW'#148'J%^'#191'~M.'#151'ccc'#3#183#219'M2'#153#140')'#165'>'#4
+  +#188'"'#178#7'w'#11#237'-'#224#15' '#148'J'#165#24#25#25#193'f'#179#209#223
+  +#223#143#211#233'dpp'#16#151#203#133#219#237'fhh'#136#129#129#1#236'v;'#14
+  +#135#3#143#199'C*'#149#2#8'5]'#248#188#211#17#153#128#204#237'`xx'#152#158
+  +#158#30','#22#11'}}}8'#157'N'#28#14#7#221#221#221'\\\'#0'P'#171#213#184#184
+  +#184'`tt'#148#189#189#189#219#165'utE'#169#223'AWS'#4'h'#184#203'`0`2'#153'0'
+  +#153'L'#152#205'f'#236'v;.'#151#171#149'p'#147#201#132#209'h'#196'h'#188#211
+  +#16#238#12#244#2#127#235''''#207#206#206#184#185#185'iE'#189'^'#167'V'#171'Q'
+  +','#22#185#188#188#164'^'#175#183#230#142#142#142#244#156'O'#244#188'z'#129
+  +'o'#129'<'#16#211'4'#141#227#227'c'#170#213'*'#213'j'#149'r'#185'L'#161'P'
+  +#224#244#244#148't:M>'#159#167'T*Q'#169'T('#151#203#28#30#30#226#243#249#160
+  +#209#159#222#5#246#239#9#136#200#143'"'#146#1'^'#174#174#174'R('#20#216#223
+  +#223'o'#185#229#252#252#156'l6K6'#155'%'#151#203#145#207#231')'#20#10#236#238
+  +#238'R,'#22'YYY'#225#228#228#228#21#240#30#13#179#0#29#154']'#19#137'P('#228
+  +#223#220#220'drr'#146#137#137#9#236'v{'#171#14#174#175#175')'#20#10'$'#18#9
+  +'vvv'#152#157#157'%'#22#139'm+'#165#158#3'_'#1#31#139'H'#182#149#204#14#225
+  +'ho'#21#211#211#211#178#184#184'('#11#11#11#226#247#251#197#233't'#138'RJB'
+  +#161#144#136'H~~~'#254#29#224#23#26']'#248'~/z@$'#17#137'D'#196#231#243#9' J'
+  +')QJ'#9' '#227#227#227#18#141'FED'#18#225'px'#10'x'#1#252#172'w'#225#191#9
+  +#220#198#210'C'#237':'#147#201'<'#5#194#192'zS'#192#218'~*'#15#229#224#14#148
+  +'R^'#160#7'8'#164'QHO'#128#247#129#15#128'!'#224#21#16#185'%'#215#163#227''''
+  +#179#3#22#129#207't'#227'.'#224'/'#26'n'#249#30'Hw"'#135#135']'#244#191#225
+  +#209#255'*'#254#1'\Pw'#127#251#22#148't'#0#0#0#0'IEND'#174'B`'#130
+]);

+ 49 - 0
icons/uerotimage_icon.lrs

@@ -0,0 +1,49 @@
+LazarusResources.Add('tuerotimage','PNG',[
+  #137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#24#0#0#0#24#8#6#0#0#0#224'w='#248#0
+  +#0#0#4'sBIT'#8#8#8#8'|'#8'd'#136#0#0#0#9'pHYs'#0#0#11#18#0#0#11#18#1#210#221
+  +'~'#252#0#0#0#28'tEXtSoftware'#0'Adobe Fireworks CS4'#6#178#211#160#0#0#4#0
+  +'IDATH'#137#189#150'KL\e'#20#199#127'wf.'#204#179'0T'#30'-S@,'#148#150'g'#1
+  +'+A"'#246'aR'#19#210'F7'#182#233'BK]'#152#176'0qabb1Z7n'#220#152#198#10'%'
+  +#213#210'T'#219#170#177#180#152'VjI'#156#22#131#218#242#152#142'T(e2'#229'5'
+  +#188#161'0'#195#12'3'#247's'#193#12#206#0'%.'#196#147#220'|9'#223'w'#242#255
+  +#221#255'w'#207'M'#142'$'#132'`=C'#181#174#234#255#7'@'#3'Pw'#166#238'C'#160
+  +#250'?'#214'>q'#236#232#177'jM0'#169'>Pq@'#248#253'~iyU'#155#189#151#191'z'
+  +#31'Q'#177#247'9'#12'z'#237#154#138#161#239')'#203'2W'#26#175#28#7#150#0#4#2
+  +#129#21#226's'#238'yN'#213#255'H'#148'>'#142#27#214':'#14#31',goY'#238#19#1
+  +#146#180'('#225'v'#187#151#246'T'#203#15#195#163#166#254#6'j}<'#217#197'E'
+  +#152'-'#22#234#27#172'|Z'#211#192#236#156'gM'''#225'ZK'#0'EQ"'#138'n'#253#246
+  +''''#142#225'I^'#218#151'Ie'#133#158#234#170'R'#202#247#228'aw'#206#240#238
+  +#199'u'#220'j'#181#173#9'Y'#1#8#15#183#199#203#229#235'-'#20#228#23#144#158
+  +#28'Kj'#226#14'2'#183'l%#'#205'@BJ'#22#194'h'#161#246#146#149#147'g~X'#213'M'
+  +#248#191#181#234#21#157'>'#223#136'%9'#137'g'#11#179'Q'#132#150#222#129'v'
+  +#250#6#218#153#152#4#147'^'#198#156'h'#193#156#146#205#239#221'S'#188#243'Q-'
+  +#214'5'#220'h'#150'o4'#223'n'#227'gk'#27#217#219#210'q'#246'u'#17#165'7s?`bt'
+  +'b'#129#209'q#1'#250#0#218'h'#137')5 e212'#192#201#243#205#220#181#245'Py'
+  +#232'eLF]'#196#203'F'#0'f'#231'<'#212#156#187#138'Z'#214#211#218#254#0#215
+  +#216'4'#5#185'Y'#228#229'd'#19'k'#138'A'#171'5042'#137#199'+!'#132#132'F'#165
+  +'B'#17#201'L'#202'&~'#177'9h'#235':'#197'[G'#246'S'#152#243#204'J'#128#16#130
+  +#239#26#154'1'#25'c'#137'7&`'#152#26#195'10'#200#224#240#24'}'#14#7#207#151
+  +#20#147#144#148'LF'#250#22#134'\'#19'hd'#15#19#140#195#130#15#181'&'#158'q'
+  +#217#128'g'#196#142#237#190#131#226#188#140#213#29'dg=MKG7'#243#238'I'#204'1'
+  +'q'#200#154'h\#'#195#220'l'#177'a'#239'vR'#186#171#128#210#146'"'#188#211#147
+  +#204#12#246'3'#237'r'#226'GC'#236#230'2'#22#30#207#240#24'/'#135#15#238'^'
+  +#253#138#132#16#20#239#220#206#182#140'T'#206'^'#188#206#157'{'#14#140#198
+  +#141#232'R'#210'0'#155'c'#233#233#237#227#234'OV'#186':[I4)h'#228'htz#'#138
+  +'*'#26#131'F'#193'73'#204#155#175#237#193'h'#208'F'#180#188'*'#28#0'`2'#234
+  +#169#170'|'#133#202'C'#251'X'#240'M'#16'X'#152'%.6'#142#130#156#28#146#18'61'
+  +'2%x'#240'h'#154'y'#191'@'#165#150#200')(A'#14#184#137'Rfi'#189'{'#143'/'#190
+  +#188#200#208#240#224#147#187'('#20'e'#187'r'#201#223#177#149#179#223'^'#227
+  +'N'#167#3#131'1'#142#212#212'4F'#199#13#184#250#189#216'{G'#217'l'#217#192
+  +#166#12#133#241#193#135#28'y'#245'E'#18'7'#154#144'e'#153#142#206'N'#212'j'
+  +#213#219#17#14'V'#11#147'QG'#213#27#139'n'#2#190')'#132#127#14#189#214'@'#220
+  +'S'#22#228'h'#19#127't'#244'p'#233#251#203#236'/'#207#199#160'S'#163'('#10'6'
+  +#187#13#16#167#143#190'^'#249'Y'#132#3#157'N'#135#207#231#251'G]'#10'-'#18'/'
+  +#148#228#179'37'#131#175#190#185'F'#227#205'vJ'#138#182#147#158#156#207'C'
+  +#167#139#152#13'&'#202'K'#11'i'#249#245'6'#253#253'N'#6#7#6'>'#175'>'#254#193
+  +'{K2B'#8'j'#235'jO'#168'T'#170#247#215'r'#243'o'#162#169#169#233#147#11'__8'
+  +#7'8'#128'Y!'#196'"@Z'#236'+'#25#136#6't'#128'6'#152'k'#0'u'#216#163#1#2#128
+  +'?l'#245#3#11#128#27#152#7#188#193'3'#17#14#8']'#138':L4'#244'}B='''#130'5'
+  +#225'SB('#23#193':'#127'p'#21','#18'"'#186'H'#4#201#129'0'#241#229'#'#199#242
+  +'\Zv'#182'bD'#145#214'{l'#249#27#183'e'#147#184'.'#131#238'f'#0#0#0#0'IEND'
+  +#174'B`'#130
+]);

+ 32 - 0
icons/ueselector_icon.lrs

@@ -0,0 +1,32 @@
+LazarusResources.Add('tueselector','PNG',[
+  #137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#24#0#0#0#24#8#6#0#0#0#224'w='#248#0
+  +#0#0#4'sBIT'#8#8#8#8'|'#8'd'#136#0#0#0#9'pHYs'#0#0#11#18#0#0#11#18#1#210#221
+  +'~'#252#0#0#0#22'tEXtCreation Time'#0'08/16/10,"'#238'*'#0#0#0#28'tEXtSoftwa'
+  +'re'#0'Adobe Fireworks CS4'#6#178#211#160#0#0#2'NIDATH'#137#181#149#191'N"Q'
+  +#24#197#207#183#204#24#9'#:'#18#131'!'#1#11#239#16#173#128#23#152#145#138'G'
+  +#216#194'F'#146'}'#5'('#182#223#134'f{'#166#241#17'|'#4#13#205#150#20#196'd'
+  +#19'i'#8#161'#'#1'D'#254#132#200#217'b'#7#130#204#200#138'YN'#242'e'#138#239
+  +#220#249#205#189'7'#223#25'!'#137']'#234#203'6f'#17'qD'#228'jg'#0#0'Y'#175'v'
+  +#6#216'^$'#255'U7$'#239#0'p'#181'H'#222'y'#189#141#235'75'#143'H'#214#171#213
+  +'*'#149'R\'#7'('#165'X'#173'VI'#178#238'y'#183#2#28#145#236#217#182'M'#17'a4'
+  +#26#245#1#12#195#160#136#208#182'm'#146#236#189#7'y'#15'P'#183'm'#155#186#174
+  +'S)'#197'|>'#239#3#20#10#5'^\\0'#20#10'- '#245#160'w'#5']'#242#141#235#186
+  +#153'Z'#173#134#179#179'3'#156#159#159#227#228#228#196'g'#138#199#227#184#188
+  +#188#132'R'#10#181'Z'#13#174#235'f'#0#220#172#251#2#1#149'J'#5#145'H'#4#169
+  +'T'#10#166'i'#226#248#248#216'g'#138#197'b0M'#19#233't'#26#134'a'#160'R'#169
+  +' '#8#160#5#0#156#167#167'''X'#150#133'h4'#138#131#131#3#152#166#233'3-'#160
+  +#179#217#12#201'd'#18#143#143#143#0#224#4#2'D'#196#129'7@'#139#232'8=='#197
+  +#254#254'>'#194#225'0'#12#195#240#1#14#15#15'1'#157'N'#241#242#242#130'D"'
+  +#177#0'@D'#190'y'#150#6#201'_'#139#29#136'WK'#145'D('#20#130#174#235#208'u'
+  +#221#7#216#219#219#131#174#235#208'4'#13#154#246#230' '#226#222#179#189#220#1
+  +#201'{'#0#247'^'#227''''#0't'#187']$'#147'I'#204#231's'#204#231's'#31#224#245
+  +#245'u'#217'k'#183#219#171#31#246'c'#213#23't'#201#15'J)t:'#29'L&'#19'L&'#19
+  +#140'F#'#159'i8'#28'b<'#30'c4'#26#161#213'j'#193#178','#0'xX'#247#5#1'n'#203
+  +#229'2'#6#131#1#154#205'&'#134#195'!'#250#253#190#207#212#235#245'0'#24#12
+  +#208'h4'#240#252#252#140'R'#169#4#0#183'>'#227#166'A'#211'4'#141#217'l'#150
+  +#215#215#215#127#7#172#231#21#192'b'#177#200'\.GM'#211'6'#14#218'vQ'#177#2'0'
+  +'M'#147'"B'#199'q>'#21#21'o'#194#206#178',_T'#164#211'i'#186#174#251#233#176
+  +#251'oq-'#139#193#250#136'D'#228'+'#128#12#201#239#31']'#179#243'?ZP'#22'm'
+  +#210'o'#0#211'm'#22'luD'#159#209#31'W'#252'po'#165#141#213#152#0#0#0#0'IEND'
+  +#174'B`'#130
+]);

+ 618 - 0
ueknob.pas

@@ -0,0 +1,618 @@
+{-----------------------------------------------------------------------------
+Miguel A. Risco Castillo TuEKnob v0.6.9
+http://ue.accesus.com/uecontrols
+
+The contents of this file are subject to the Mozilla Public License
+Version 1.1 (the "License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/MPL-1.1.html
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
+the specific language governing rights and limitations under the License.
+-----------------------------------------------------------------------------}
+
+unit uEKnob;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, ExtCtrls,
+  LCLIntf, LCLType, LCLProc, Types,
+  BGRABitmap, BGRABitmapTypes, uERotImage;
+
+type
+
+  TuEAngle = 0..3600; // 0.0 - 360.0 deg
+
+
+  { TCustomuEKnob }
+
+  TCustomuEKnob = class(TCustomuERotImage)
+  private
+  protected
+    FMax: Real;
+    FMaxAngle: TuEAngle;
+    FMin: Real;
+    FMinAngle: TuEAngle;
+    FOffsetAngle:integer;
+    FLTicks: integer;
+    FLTicksColor: TColor;
+    FLTicksSize: integer;
+    FSTicks: integer;
+    FSTicksColor: TColor;
+    FSTicksSize: integer;
+    FTicksMargin: integer;
+    FShowValues: Boolean;
+    FValuesFont: TFont;
+    FValuesMargin: integer;
+    FOnChange: TNotifyEvent;
+    FPosition: Real;
+    FTransparent:Boolean;
+    FDefKnobRadius:integer;
+    procedure SetLTicksColor(const AValue: TColor); virtual;
+    procedure SetMax(const AValue: Real); virtual;
+    procedure SetMaxAngle(const AValue: TuEAngle); virtual;
+    procedure SetMin(const AValue: Real);  virtual;
+    procedure SetMinAngle(const AValue: TuEAngle); virtual;
+    procedure SetPosition(const AValue: Real); virtual;
+    procedure SetLargeTicks(const AValue: integer); virtual;
+    procedure SetLTicksSize(const AValue: integer); virtual;
+    procedure SetSTicks(const AValue: integer); virtual;
+    procedure SetSTicksColor(const AValue: TColor); virtual;
+    procedure SetSTicksSize(const AValue: integer); virtual;
+    procedure SetTicksMargin(const AValue: integer); virtual;
+    procedure SetShowValues(const AValue: Boolean); virtual;
+    procedure SetTransparent(const AValue: Boolean); virtual;
+    procedure SetValueMargin(const AValue: integer); virtual;
+    procedure SetValuesFont(const AValue: TFont); virtual;
+    procedure SetDefKnobRadius(AValue: integer); virtual;
+    procedure SetOffsetAngle(AValue: integer); virtual;
+    class procedure WSRegisterClass; override;
+    procedure CalculatePreferredSize(var PreferredWidth,
+                                     PreferredHeight: integer;
+                                     WithThemeSpace: Boolean); override;
+    class function GetControlClassDefaultSize: TSize; override;
+    procedure Paint; override;
+    procedure Loaded; override;
+    procedure SetColor(AValue: TColor); override;
+    procedure FontChanged(Sender: TObject); override;
+    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
+    procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
+    procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
+    procedure DefaultPicture; virtual;
+    procedure ForcePosition(const AValue: Real); virtual;
+    procedure DrawScales(LBitmap:TBGRABitmap); virtual;
+    procedure UpdateScales; virtual;
+    procedure DoOnChange; virtual;
+    procedure DoOnResize; override;
+    function DoMouseWheel(Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint): Boolean; override;
+    function GetCenter: TPoint;
+    function PointToAngle(APoint, ACenter: TPoint): TuEAngle;
+    function AngleToPos(AnAngle: TuEAngle): Real;
+    function PosToAngle(Pos: Real): TuEAngle;
+    property Position: Real read FPosition write SetPosition;
+    property Max: Real read FMax write SetMax;
+    property MaxAngle: TuEAngle read FMaxAngle write SetMaxAngle;
+    property Min: Real read FMin write SetMin;
+    property MinAngle: TuEAngle read FMinAngle write SetMinAngle;
+    property OffsetAngle: integer read FOffsetAngle write SetOffsetAngle;
+    property TicksMargin:integer read FTicksMargin write SetTicksMargin;
+    property LTicks:integer read FLTicks write SetLargeTicks;
+    property LTicksSize:integer read FLTicksSize write SetLTicksSize;
+    property LTicksColor:TColor read FLTicksColor write SetLTicksColor;
+    property STicks:integer read FSTicks write SetSTicks;
+    property STicksSize:integer read FSTicksSize write SetSTicksSize;
+    property STicksColor:TColor read FSTicksColor write SetSTicksColor;
+    property ShowValues:Boolean read FShowValues write SetShowValues;
+    property ValuesMargin:integer read FValuesMargin write SetValueMargin;
+    property ValuesFont:TFont read FValuesFont write SetValuesFont;
+    property Transparent:Boolean read FTransparent write SetTransparent;
+    property DefKnobRadius:integer read FDefKnobRadius write SetDefKnobRadius;
+    property OnPaint;
+    property OnChange: TNotifyEvent read FOnChange write FOnChange;
+  public
+    Background:TBGRABitmap;
+    constructor Create(AOwner: TComponent); override;
+    destructor Destroy; override;
+  end;
+
+
+  { TuEKnob }
+
+  TuEKnob = class(TCustomuEKnob)
+  published
+    procedure DrawScales(LBitmap:TBGRABitmap); override;
+    property Max;
+    property MaxAngle;
+    property Min;
+    property MinAngle;
+    property OffsetAngle;
+    property Picture;
+    property Position;
+    property TicksMargin;
+    property LTicks;
+    property LTicksSize;
+    property LTicksColor;
+    property STicks;
+    property STicksSize;
+    property STicksColor;
+    property ShowValues;
+    property ValuesMargin;
+    property ValuesFont;
+    property Transparent;
+    property DefKnobRadius;
+    property OnChange;
+    property OnPaint;
+    property OnMouseDown;
+    property OnMouseMove;
+    property OnMouseUp;
+//
+    property Align;
+    property Anchors;
+    property BorderSpacing;
+    property Color;
+    property Constraints;
+    property DragCursor;
+    property DragKind;
+    property DragMode;
+    property Enabled;
+    property ParentColor;
+    property ParentShowHint;
+    property PopupMenu;
+    property ShowHint;
+    property Visible;
+    property OnChangeBounds;
+    property OnMouseEnter;
+    property OnMouseLeave;
+    property OnMouseWheel;
+    property OnMouseWheelDown;
+    property OnMouseWheelUp;
+    property OnClick;
+    property OnConstrainedResize;
+    property OnDblClick;
+    property OnDragDrop;
+    property OnDragOver;
+    property OnEndDock;
+    property OnEndDrag;
+    property OnResize;
+    property OnStartDock;
+    property OnStartDrag;
+
+  end;
+
+
+procedure Register;
+
+implementation
+
+{ TCustomuEKnob }
+
+procedure TCustomuEKnob.SetMax(const AValue: Real);
+begin
+  if (FMax=AValue) and (AValue<=FMin) then exit;
+  FMax:=AValue;
+  UpdateScales;
+  ForcePosition(FPosition);
+end;
+
+procedure TCustomuEKnob.SetMaxAngle(const AValue: TuEAngle);
+begin
+  if FMaxAngle=AValue then exit;
+  FMaxAngle:=AValue;
+  UpdateScales;
+  ForcePosition(FPosition);
+end;
+
+procedure TCustomuEKnob.SetMin(const AValue: Real);
+begin
+  if (FMin=AValue) and (AValue>=FMax) then exit;
+  FMin:=AValue;
+  UpdateScales;
+  ForcePosition(FPosition);
+end;
+
+procedure TCustomuEKnob.SetMinAngle(const AValue: TuEAngle);
+begin
+  if FMinAngle=AValue then exit;
+  FMinAngle:=AValue;
+  UpdateScales;
+  ForcePosition(FPosition);
+end;
+
+procedure TCustomuEKnob.SetPosition(const AValue: Real);
+begin
+  if FPosition=AValue then exit;
+  ForcePosition(AValue);
+end;
+
+procedure TCustomuEKnob.ForcePosition(const AValue: Real);
+begin
+  if AValue<FMin then FPosition:=FMin
+  else if AValue>FMax then FPosition:=FMax
+  else FPosition:=AValue;
+  inherited Angle:=(PostoAngle(FPosition)+FOffsetAngle)/10;
+  invalidate;
+  DoOnChange;
+end;
+
+procedure TCustomuEKnob.SetShowValues(const AValue: Boolean);
+begin
+  if FShowValues=AValue then exit;
+  FShowValues:=AValue;
+  UpdateScales;
+  invalidate;
+end;
+
+procedure TCustomuEKnob.SetTransparent(const AValue: Boolean);
+begin
+  if FTransparent=AValue then exit;
+  FTransparent:=AValue;
+  UpdateScales;
+  invalidate;
+end;
+
+procedure TCustomuEKnob.SetSTicks(const AValue: integer);
+begin
+  if FSTicks=AValue then exit;
+  FSTicks:=AValue;
+  UpdateScales;
+  invalidate;
+end;
+
+procedure TCustomuEKnob.SetSTicksColor(const AValue: TColor);
+begin
+  if FSTicksColor=AValue then exit;
+  FSTicksColor:=AValue;
+  UpdateScales;
+  invalidate;
+end;
+
+procedure TCustomuEKnob.SetSTicksSize(const AValue: integer);
+begin
+  if FSTicksSize=AValue then exit;
+  FSTicksSize:=AValue;
+  UpdateScales;
+  invalidate;
+end;
+
+procedure TCustomuEKnob.SetTicksMargin(const AValue: integer);
+begin
+  if FTicksMargin=AValue then exit;
+  FTicksMargin:=AValue;
+  UpdateScales;
+  invalidate;
+end;
+
+procedure TCustomuEKnob.SetValueMargin(const AValue: integer);
+begin
+  if FValuesMargin=AValue then exit;
+  FValuesMargin:=AValue;
+  UpdateScales;
+  invalidate;
+end;
+
+procedure TCustomuEKnob.SetValuesFont(const AValue: TFont);
+begin
+  if FValuesFont.IsEqual(AValue) then exit;
+  FValuesFont.Assign(AValue);
+end;
+
+class procedure TCustomuEKnob.WSRegisterClass;
+begin
+  inherited WSRegisterClass;
+end;
+
+procedure TCustomuEKnob.CalculatePreferredSize(var PreferredWidth,
+  PreferredHeight: integer; WithThemeSpace: Boolean);
+begin
+  inherited CalculatePreferredSize(PreferredWidth, PreferredHeight,
+    WithThemeSpace);
+end;
+
+class function TCustomuEKnob.GetControlClassDefaultSize: TSize;
+begin
+  Result.CX := 90;
+  Result.CY := 90;
+end;
+
+procedure TCustomuEKnob.Paint;
+begin
+  Background.Draw(inherited Canvas,0,0,false);
+  inherited Paint;
+end;
+
+procedure TCustomuEKnob.DefaultPicture;
+var
+  tbmp:TBGRABitmap;
+  c:real;
+begin
+  c:=(FDefKnobRadius-1)/2;
+  tbmp :=TBGRABitmap.Create(FDefKnobRadius,FDefKnobRadius,BGRAPixelTransparent);
+  tbmp.FillEllipseAntialias(c,c,c,c,BGRABlack);
+  tbmp.GradientFill(0,0,FDefKnobRadius,FDefKnobRadius,
+                      BGRA(128,128,128,255),BGRA(0,0,0,0),
+                      gtRadial,PointF(c,c),PointF(0,c),
+                      dmDrawWithTransparency);
+  tbmp.DrawLineAntialias(c,c+5,c,FDefKnobRadius-5,BGRAWhite,2);
+  try
+    Picture.Bitmap.Assign(tbmp.Bitmap);
+  finally
+    tbmp.free;
+  end;
+end;
+
+procedure TCustomuEKnob.Loaded;
+begin
+  inherited Loaded;
+  ForcePosition(FPosition);
+end;
+
+procedure TCustomuEKnob.SetColor(AValue: TColor);
+begin
+  if Color=AValue then exit;
+  inherited SetColor(AValue);
+  UpdateScales;
+end;
+
+procedure TCustomuEKnob.FontChanged(Sender: TObject);
+begin
+  inherited FontChanged(Sender);
+  UpdateScales;
+end;
+
+function TCustomuEKnob.AngleToPos(AnAngle: TuEAngle): Real;
+// Convert angle AnAngle to a position.
+begin
+  Result := FMin + ((FMax - FMin) * (AnAngle - FMinAngle)/(FMaxAngle - FMinAngle));
+end;
+
+function TCustomuEKnob.PosToAngle(Pos: Real): TuEAngle;
+// Convert position Pos to an angle.
+begin
+  Result := FMinAngle + Round((FMaxAngle - FMinAngle) * (Pos - FMin) / (FMax - FMin));
+end;
+
+procedure TCustomuEKnob.DoOnResize;
+begin
+  BackGround.SetSize(width,height);
+  UpdateScales;
+  inherited DoOnResize;
+end;
+
+function TCustomuEKnob.DoMouseWheel(Shift: TShiftState; WheelDelta: Integer;
+  MousePos: TPoint): Boolean;
+begin
+  Result:=inherited DoMouseWheel(Shift, WheelDelta, MousePos);
+  SetPosition(FPosition+(FMax-FMin)*WheelDelta/20000);
+end;
+
+constructor TCustomuEKnob.Create(AOwner: TComponent);
+begin
+  inherited Create(AOwner);
+  FDefKnobRadius:=34;
+  FPosition:=0;
+  FMax:=100;
+  FMin:=0;
+  FMaxAngle:=3300;
+  FMinAngle:=300;
+  FOffsetAngle:=0;
+  FTicksMargin:=20;
+  FLTicks:=10;
+  FLTicksSize:=8;
+  FLTicksColor:=clBlack;
+  FSTicks:=3;
+  FSTicksSize:=5;
+  FSTicksColor:=clBlack;
+  FShowValues:=true;
+  FValuesMargin:=8;
+  FValuesFont:=TFont.Create;
+  FValuesFont.Name:='Sans';
+  FValuesFont.Orientation:=0;
+  FValuesFont.Style:=[];
+  FValuesFont.Color:=clBlack;
+  FValuesFont.Size:=8;
+  FValuesFont.OnChange:=@FontChanged;
+  FTransparent:=true;
+  if Picture.Bitmap.Width=0 then DefaultPicture;
+  UniqueSize:=true;
+  Center:=true;
+  ControlStyle := ControlStyle + [csReplicatable, csCaptureMouse, csClickEvents, csDoubleClicks];
+  with GetControlClassDefaultSize do
+  begin
+    SetInitialBounds(0, 0, CX, CY);
+    BackGround:=TBGRABitmap.Create(CX,CY);
+  end;
+end;
+
+destructor TCustomuEKnob.Destroy;
+begin
+  FreeThenNil(Background);
+  FValuesFont.OnChange:=nil;
+  FValuesFont.free;
+  inherited Destroy;
+end;
+
+// Convert a APoint to an angle (relative to ACenter),
+// where bottom is 0, left is 900, top is 1800 and so on.
+
+function TCustomuEKnob.PointToAngle(APoint, ACenter: TPoint): TuEAngle;
+var
+  N: Integer;
+begin
+  N := APoint.X - ACenter.X;
+  if N = 0 then
+    if APoint.Y < ACenter.Y then Result := 900 else Result := 2700
+  else
+  begin
+    Result:=Round(ArcTan((ACenter.Y - APoint.Y) / N) * 1800 / PI);
+  end;
+  if N < 0 then Result := Result + 1800;
+  Result := 2700 - Result;
+end;
+
+procedure TCustomuEKnob.MouseDown(Button: TMouseButton;
+  Shift: TShiftState; X, Y: Integer);
+Var TmpAngle:Integer;
+begin
+  inherited MouseDown(Button, Shift, X, Y);
+  MouseCapture := True;
+  TmpAngle:=PointToAngle(Point(X, Y), GetCenter)-OffsetAngle;
+  if TmpAngle>3600 then TmpAngle:=TmpAngle-3600;
+  if TmpAngle<0 then TmpAngle:=TmpAngle+3600;
+  SetPosition(AngletoPos(TmpAngle));
+end;
+
+procedure TCustomuEKnob.MouseMove(Shift: TShiftState; X, Y: Integer);
+Var TmpAngle:Integer;
+begin
+  inherited MouseMove(Shift, X, Y);
+  if MouseCapture then
+  begin
+    TmpAngle:=PointToAngle(Point(X, Y), GetCenter)-OffsetAngle;
+    if TmpAngle>3600 then TmpAngle:=TmpAngle-3600;
+    if TmpAngle<0 then TmpAngle:=TmpAngle+3600;
+    SetPosition(AngletoPos(TmpAngle));
+  end;
+end;
+
+procedure TCustomuEKnob.MouseUp(Button: TMouseButton;
+  Shift: TShiftState; X, Y: Integer);
+begin
+  inherited MouseUp(Button, Shift, X, Y);
+  MouseCapture := False;
+end;
+
+procedure TCustomuEKnob.DoOnChange;
+begin
+  if Assigned(FOnChange) then FOnChange(Self);
+end;
+
+function TCustomuEKnob.GetCenter: TPoint;
+begin
+  with Result do
+  begin
+    X := Width div 2;
+    Y := Height div 2;
+  end;
+end;
+
+procedure TCustomuEKnob.SetDefKnobRadius(AValue: integer);
+begin
+  if FDefKnobRadius=AValue then Exit;
+  FDefKnobRadius:=AValue;
+end;
+
+procedure TCustomuEKnob.SetOffsetAngle(AValue: integer);
+begin
+  if FOffsetAngle=AValue then Exit;
+  FOffsetAngle:=AValue;
+  UpdateScales;
+  ForcePosition(FPosition);
+end;
+
+procedure TCustomuEKnob.SetLTicksColor(const AValue: TColor);
+begin
+  if FLTicksColor=AValue then exit;
+  FLTicksColor:=AValue;
+  UpdateScales;
+  invalidate;
+end;
+
+procedure TCustomuEKnob.SetLargeTicks(const AValue: integer);
+begin
+  if FLTicks=AValue then exit;
+  FLTicks:=AValue;
+  UpdateScales;
+  invalidate;
+end;
+
+procedure TCustomuEKnob.SetLTicksSize(const AValue: integer);
+begin
+  if FLTicksSize=AValue then exit;
+  FLTicksSize:=AValue;
+  UpdateScales;
+  invalidate;
+end;
+
+procedure TCustomuEKnob.DrawScales(LBitmap:TBGRABitmap);
+var i,j:integer;
+    x1,y1,x2,y2,lpos:real;
+    xc,yc,langle:real;
+    sn,cn:real;
+    lc,sc,vc:TBGRAPixel;
+    ts:TSize;
+    la:string;
+    ss:boolean;
+begin
+  if (Picture.Bitmap.Width mod 2) = 0 then xc:=LBitmap.Width/2-1 else xc:=LBitmap.Width/2;
+  if (Picture.Bitmap.Height mod 2) = 0 then yc:=LBitmap.Height/2-1 else yc:=LBitmap.Height/2;
+  lc:=ColorToBGRA(ColorToRGB(FLTicksColor));
+  sc:=ColorToBGRA(ColorToRGB(FSTicksColor));
+  vc:=ColorToBGRA(ColorToRGB(FValuesFont.Color));
+  LBitmap.FontHeight:=abs(FValuesFont.Height);
+  LBitmap.FontStyle:=FValuesFont.Style;
+  LBitmap.FontName:=FValuesFont.Name;
+  LBitmap.FontOrientation:=FValuesFont.Orientation;
+  ss:=((FMaxAngle-FMinAngle) mod 3600)=0;
+  if FLTicks>0 then For i:=0 to FLTicks do
+  begin
+    lpos:=(i/FLTicks)*(FMax-FMin)+FMin;
+    langle:=(PosToAngle(lpos)+FOffsetAngle)*PI/1800 +PI/2;
+    sn:=sin(langle);
+    cn:=cos(langle);
+    x1:=xc+FTicksMargin*cn;
+    y1:=yc+FTicksMargin*sn;
+    x2:=xc+(FTicksMargin+FLTicksSize)*cn;
+    y2:=yc+(FTicksMargin+FLTicksSize)*sn;
+    LBitmap.DrawLineAntialias(x1,y1,x2,y2,lc, 1);
+    if FShowValues and not(ss and (i=0)) then
+    begin
+      x2:=xc+(FTicksMargin+FLTicksSize+FValuesMargin)*cn;
+      y2:=yc+(FTicksMargin+FLTicksSize+FValuesMargin)*sn;
+      la:=floattostrF(lpos,ffGeneral,4,2);
+      ts:=LBitmap.TextSize(la);
+      LBitmap.TextOut(trunc(x2+1), trunc(y2-ts.cy/2+1), la, vc, taCenter);
+    end;
+    if (lpos<Fmax) then For j:=1 to FSTicks do
+    begin
+      lpos:=(i/FLTicks)*(FMax-FMin)+FMin+j*((FMax-FMin)/FLTicks)/(FSTicks+1);
+      langle:=(PosToAngle(lpos)+FOffsetAngle)*PI/1800 +PI/2;
+      sn:=sin(langle);
+      cn:=cos(langle);
+      x1:=xc+FTicksMargin*cn;
+      y1:=yc+FTicksMargin*sn;
+      x2:=xc+(FTicksMargin+FSTicksSize)*cn;
+      y2:=yc+(FTicksMargin+FSTicksSize)*sn;
+      LBitmap.DrawLineAntialias(x1,y1,x2,y2,sc, 1);
+    end;
+  end;
+end;
+
+procedure TCustomuEKnob.UpdateScales;
+begin
+  if ([csLoading,csDestroying]*ComponentState<>[]) then exit;
+  //if AutoSizeDelayed then exit;
+
+  if FTransparent then BackGround.Fill(BGRAPixelTransparent) else BackGround.Fill(ColortoBGRA(ColortoRGB(Color)));
+  DrawScales(BackGround);
+end;
+
+{ TuEKnob }
+
+procedure TuEKnob.DrawScales(LBitmap: TBGRABitmap);
+begin
+  inherited DrawScales(LBitmap);
+end;
+
+
+procedure Register;
+begin
+  {$I icons\ueknob_icon.lrs}
+  RegisterComponents('BGRA Controls', [TuEKnob]);
+end;
+
+
+end.

+ 371 - 0
ueled.pas

@@ -0,0 +1,371 @@
+
+{------------------------------------------------------------------------------
+
+  Miguel A. Risco Castillo TuELED v0.2
+  http://ue.accesus.com/uecontrols
+
+  The contents of this file are subject to the Mozilla Public License
+  Version 1.1 (the "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+  http://www.mozilla.org/MPL/MPL-1.1.html
+
+  Software distributed under the License is distributed on an "AS IS" basis,
+  WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
+  the specific language governing rights and limitations under the License.
+
+------------------------------------------------------------------------------}
+
+unit ueled;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
+  LCLIntf, LCLType, Types, BGRABitmap, BGRABitmapTypes;
+
+type
+
+  { TuELED }
+  TLedType = (ledRound, ledSquare);
+
+  TuELED = class(TGraphicControl)
+  private
+    FColor: TColor;
+    FActive: Boolean;
+    FOnChange: TNotifyEvent;
+    FChanging:Boolean;
+    FBright : Boolean;
+    FReflection : Boolean;
+    FLedType : TLedType;
+    procedure DrawLED;
+    procedure DrawLedRound(const r: integer; const LColor: TColor);
+    procedure DrawLedSquare(const r: integer; const LColor: TColor);
+    procedure SetActive(AValue:Boolean);
+  protected
+    class procedure WSRegisterClass; override;
+    class function GetControlClassDefaultSize: TSize; override;
+    procedure Paint; override;
+    procedure Loaded; override;
+    procedure Resize; override;
+    procedure SetColor(AValue: TColor); override;
+    procedure SetBright(Avalue:Boolean); virtual;
+    procedure SetReflection(Avalue:Boolean); virtual;
+    procedure SetLedType(AValue:TLedType); virtual;
+    procedure DoChange; virtual;
+  public
+    Bitmap: TBGRABitmap;
+    constructor Create(AOwner: TComponent); override;
+    destructor Destroy; override;
+    procedure ReDraw;
+  published
+    property Active: boolean read FActive write SetActive;
+    property LedType: TLedType read FLedType write SetLedType;
+    property Bright: boolean read FBright write SetBright;
+    property Reflection: boolean read FReflection write SetReflection;
+    property Align;
+    property Anchors;
+    property BorderSpacing;
+    property Color: tcolor read FColor write SetColor default clDefault;
+    property Constraints;
+    property DragCursor;
+    property DragKind;
+    property DragMode;
+    property Enabled;
+    property ParentColor;
+    property ParentShowHint;
+    property PopupMenu;
+    property ShowHint;
+    property Visible;
+    property OnChange: TNotifyEvent read FOnChange write FOnChange;
+    property OnChangeBounds;
+    property OnMouseEnter;
+    property OnMouseLeave;
+    property OnMouseWheel;
+    property OnMouseWheelDown;
+    property OnMouseWheelUp;
+    property OnPaint;
+    property OnClick;
+    property OnConstrainedResize;
+    property OnDblClick;
+    property OnDragDrop;
+    property OnDragOver;
+    property OnEndDock;
+    property OnEndDrag;
+    property OnMouseDown;
+    property OnMouseMove;
+    property OnMouseUp;
+    property OnResize;
+    property OnStartDock;
+    property OnStartDrag;
+  end;
+
+procedure Register;
+function Darker(Color:TColor; Percent:Byte):TBGRAPixel;
+
+implementation
+
+constructor TuELED.Create(AOwner: TComponent);
+begin
+  inherited Create(AOwner);
+  ControlStyle := ControlStyle + [csReplicatable, csCaptureMouse, csClickEvents, csDoubleClicks];
+  Bitmap:=TBGRABitmap.Create(0,0);
+  with GetControlClassDefaultSize do SetInitialBounds(0, 0, CX, CY);
+  FChanging:=false;
+  FActive:=true;
+  FBright:=true;
+  FReflection:=true;
+  FColor:=clLime;
+  FLedType:=ledRound;
+end;
+
+destructor TuELED.Destroy;
+begin
+  if Assigned(Bitmap) then
+  begin
+    Bitmap.Free;
+    Bitmap := nil;
+  end;
+  inherited Destroy;
+end;
+
+procedure TuELED.ReDraw;
+begin
+  Paint;
+end;
+
+procedure TuELED.Paint;
+
+  procedure DrawFrame;
+  begin
+    with inherited Canvas do
+    begin
+      Pen.Color := clBlack;
+      Pen.Style := psDash;
+      MoveTo(0, 0);
+      LineTo(Self.Width-1, 0);
+      LineTo(Self.Width-1, Self.Height-1);
+      LineTo(0, Self.Height-1);
+      LineTo(0, 0);
+    end;
+  end;
+
+begin
+  if csDesigning in ComponentState then DrawFrame;
+  if assigned(Bitmap) then
+  begin
+    Bitmap.Draw(inherited Canvas,0,0,false);
+  end;
+end;
+
+procedure TuELED.Loaded;
+begin
+  inherited Loaded;
+end;
+
+procedure TuELED.Resize;
+begin
+  inherited Resize;
+  DrawLED;
+end;
+
+procedure TuELED.SetColor(AValue: TColor);
+begin
+  if FColor = AValue then exit;
+  FColor := AValue;
+  DrawLED;
+  inherited SetColor(AValue);
+end;
+
+procedure TuELED.SetBright(Avalue: Boolean);
+begin
+  if FBright = AValue then exit;
+  FBright := AValue;
+  DrawLED;
+end;
+
+procedure TuELED.SetReflection(Avalue: Boolean);
+begin
+  if FReflection = AValue then exit;
+  FReflection := AValue;
+  DrawLED;
+end;
+
+procedure TuELED.SetLedType(AValue: TLedType);
+begin
+  if FLedType = AValue then exit;
+  FLedType := AValue;
+  DrawLED;
+end;
+
+
+procedure TuELED.DrawLED;
+var r:integer;
+begin
+  if (csLoading in ComponentState) or FChanging then exit;
+
+  FChanging := True;
+  Bitmap.SetSize(width,height);
+  Bitmap.Fill(BGRAPixelTransparent);
+
+  if Width < Height then r:=Width else r:=Height;
+  r:=r div 10;
+
+  Case FLedType of
+    ledSquare : DrawLedSquare(r+2, FColor);
+  else
+    DrawLedRound(r+3, FColor)
+  end;
+
+  FChanging := False;
+  Invalidate;
+  DoChange;
+end;
+
+procedure TuELED.DrawLedRound(const r: integer; const LColor: TColor);
+var
+  mask: TBGRABitmap;
+  layer: TBGRABitmap;
+begin
+  //Bright
+  if FActive and FBright then
+  begin
+    layer:=TBGRABitmap.Create(Width, Height);
+    layer.GradientFill(0,0,layer.Width,layer.Height,
+                       ColorToBGRA(ColortoRGB(LColor),240),ColorToBGRA(ColortoRGB(LColor),0),
+                       gtRadial,PointF(layer.Width/2,layer.Height/2),PointF(0,layer.Height/2),
+                       dmSet);
+    Bitmap.PutImage(0,0,layer,dmDrawWithTransparency);
+    layer.free;
+  end;
+
+  // Solid Led
+  if FActive then
+  begin
+    layer:=TBGRABitmap.Create(Width-2*r, Height-2*r);
+    layer.GradientFill(0,0,layer.Width,layer.Height,
+                       ColorToBGRA(ColortoRGB(LColor)),BGRA(0,0,0),
+                       gtRadial,PointF(layer.Width/2,layer.Height*8/15),PointF(layer.Width*1.5,layer.Height*1.5),
+                       dmSet);
+    mask := TBGRABitmap.Create(layer.Width,layer.Height,BGRABlack);
+    mask.FillEllipseAntialias((layer.Width-1)/2,(layer.Height-1)/2,layer.Width/2,layer.Height/2,BGRAWhite);
+    layer.ApplyMask(mask);
+    mask.Free;
+    Bitmap.PutImage(r,r,layer,dmDrawWithTransparency);
+    layer.free;
+  end else Bitmap.FillEllipseAntialias((Width-1)/2,(Height-1)/2,Width/2-r,Height/2-r, Darker(LColor,80));
+
+  //Reflexion
+  if FReflection then
+  begin
+    layer:=TBGRABitmap.Create((Width-1)-2*r, 5*(Height-2*r) div 8);
+    layer.GradientFill(0,0,layer.Width,layer.Height,
+                       BGRA(255,255,255,128),BGRA(255,255,255,0),
+                       gtLinear,PointF(layer.Width/2,0),PointF(layer.Width/2,layer.Height*6/10),
+                       dmSet);
+    mask := TBGRABitmap.Create(layer.Width,layer.Height,BGRABlack);
+    mask.FillEllipseAntialias(layer.Width/2,layer.Height/2,(layer.Width/2)*(4/5),(layer.Height/2)*(9/10),BGRAWhite);
+    layer.ApplyMask(mask);
+    mask.Free;
+    Bitmap.PutImage(r,r,layer,dmDrawWithTransparency);
+    layer.free;
+  end;
+end;
+
+procedure TuELED.DrawLedSquare(const r: integer; const LColor: TColor);
+var
+  mask: TBGRABitmap;
+  layer: TBGRABitmap;
+begin
+  //Bright
+  if FActive and FBright then
+  begin
+    layer:=TBGRABitmap.Create(Width, Height);
+    layer.GradientFill(0,0,layer.Width,layer.Height,
+                       ColorToBGRA(ColortoRGB(LColor),255),ColorToBGRA(ColortoRGB(LColor),0),
+                       gtRadial,PointF(layer.Width/2,layer.Height/2),PointF(0,3*layer.Height/4),
+                       dmSet);
+    Bitmap.PutImage(0,0,layer,dmDrawWithTransparency);
+    layer.free;
+  end;
+
+
+  // Solid Led
+  if FActive then
+  begin
+    layer:=TBGRABitmap.Create(Width-2*r, Height-2*r);
+    layer.GradientFill(0,0,layer.Width,layer.Height,
+                       ColorToBGRA(ColortoRGB(LColor)),BGRA(0,0,0),
+                       gtRadial,PointF(layer.Width/2,layer.Height/2),PointF(layer.Width*1.5,layer.Height*1.5),
+                       dmSet);
+    mask := TBGRABitmap.Create(layer.Width,layer.Height,BGRABlack);
+    mask.FillRoundRectAntialias(0,0,layer.Width,layer.Height,r,r,BGRAWhite);
+    layer.ApplyMask(mask);
+    mask.Free;
+    Bitmap.PutImage(r,r,layer,dmDrawWithTransparency);
+    layer.free;
+  end else Bitmap.FillRoundRectAntialias(r,r,Width-r,Height-r,r,r, Darker(LColor,80));
+
+  //Reflexion
+  if FReflection then
+  begin
+    layer:=TBGRABitmap.Create((Width-1)-2*r, 5*(Height-2*r) div 8);
+    layer.GradientFill(0,0,layer.Width,layer.Height,
+                       BGRA(255,255,255,160),BGRA(255,255,255,0),
+                       gtLinear,PointF(layer.Width/2,0),PointF(layer.Width/2,layer.Height*6/10),
+                       dmSet);
+    mask := TBGRABitmap.Create(layer.Width,layer.Height,BGRABlack);
+    mask.FillRoundRectAntialias(layer.Width*(1/20),layer.Height*(1/20),layer.Width*(19/20),layer.Height*(19/20),r,r,BGRAWhite);
+    layer.ApplyMask(mask);
+    mask.Free;
+    Bitmap.PutImage(r,r,layer,dmDrawWithTransparency);
+    layer.free;
+  end;
+
+end;
+
+procedure TuELED.SetActive(AValue: Boolean);
+begin
+  if AValue <> FActive then
+  begin
+    FActive := AValue;
+    DrawLED;
+  end;
+end;
+
+class function TuELED.GetControlClassDefaultSize: TSize;
+begin
+  Result.CX := 24;
+  Result.CY := 24;
+end;
+
+procedure TuELED.DoChange;
+begin
+  if Assigned(FOnChange) then FOnChange(Self);
+end;
+
+class procedure TuELED.WSRegisterClass;
+begin
+  inherited WSRegisterClass;
+end;
+
+function Darker(Color:TColor; Percent:Byte):TBGRAPixel;
+begin
+  Result:=ColorToBGRA(ColorToRGB(Color));
+  With Result do
+  begin
+    red:=red-muldiv(red,Percent,100);  //Percent% closer to black
+    green:=green-muldiv(green,Percent,100);
+    blue:=blue-muldiv(blue,Percent,100);
+  end;
+end;
+
+procedure Register;
+begin
+  {$I icons\ueled_icon.lrs}
+  RegisterComponents('BGRA Controls', [TuELED]);
+end;
+
+end.
+

+ 557 - 0
uemultiturn.pas

@@ -0,0 +1,557 @@
+{-----------------------------------------------------------------------------
+Miguel A. Risco Castillo TuEMultiTurn v0.2.2
+http://ue.accesus.com/uecontrols
+
+The contents of this file are subject to the Mozilla Public License
+Version 1.1 (the "License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/MPL-1.1.html
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
+the specific language governing rights and limitations under the License.
+-----------------------------------------------------------------------------}
+
+unit uEMultiTurn;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, ExtCtrls,
+  LCLIntf, LCLType, LCLProc, Types,
+  BGRABitmap, BGRABitmapTypes, uERotImage;
+
+type
+
+  TuEAngle = Integer;   //3600 = 360.0 deg
+
+
+  { TCustomuEMultiTurn }
+
+  TCustomuEMultiTurn = class(TCustomuERotImage)
+  private
+  protected
+    FLTicks: integer;
+    FLTicksColor: TColor;
+    FLTicksSize: integer;
+    FSTicks: integer;
+    FSTicksColor: TColor;
+    FSTicksSize: integer;
+    FTicksMargin: integer;
+    FShowValues: Boolean;
+    FValuesFont: TFont;
+    FValuesMargin: integer;
+    FOnChange: TNotifyEvent;
+    FPosition: Real;
+    FTransparent:Boolean;
+    FDefKnobRadius: integer;
+    procedure SetDefKnobRadius(AValue: integer);
+    procedure SetLTicksColor(const AValue: TColor); virtual;
+    procedure SetPosition(const AValue: Real); virtual;
+    procedure SetLargeTicks(const AValue: integer); virtual;
+    procedure SetLTicksSize(const AValue: integer); virtual;
+    procedure SetSTicks(const AValue: integer); virtual;
+    procedure SetSTicksColor(const AValue: TColor); virtual;
+    procedure SetSTicksSize(const AValue: integer); virtual;
+    procedure SetTicksMargin(const AValue: integer); virtual;
+    procedure SetShowValues(const AValue: Boolean); virtual;
+    procedure SetTransparent(const AValue: Boolean); virtual;
+    procedure SetValueMargin(const AValue: integer); virtual;
+    procedure SetValuesFont(const AValue: TFont); virtual;
+    class procedure WSRegisterClass; override;
+    procedure CalculatePreferredSize(var PreferredWidth,
+                                     PreferredHeight: integer;
+                                     WithThemeSpace: Boolean); override;
+    class function GetControlClassDefaultSize: TSize; override;
+    procedure Paint; override;
+    procedure Loaded; override;
+    procedure SetColor(AValue: TColor); override;
+    procedure FontChanged(Sender: TObject); override;
+    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
+    procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
+    procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
+    procedure DefaultPicture; virtual;
+    procedure ForcePosition(const AValue: Real); virtual;
+    procedure DrawScales(LBitmap:TBGRABitmap); virtual;
+    procedure UpdateScales; virtual;
+    procedure DoOnChange; virtual;
+    procedure DoOnResize; override;
+    function DoMouseWheel(Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint): Boolean; override;
+    function GetCenter: TPoint;
+    function PointToAngle(APoint, ACenter: TPoint): TuEAngle;
+    function AngleToPos(AnAngle: TuEAngle): Real;
+    function PosToAngle(Pos: Real): TuEAngle;
+    function Delta(X, Y: Integer): TuEAngle;
+    property Position: Real read FPosition write SetPosition;
+    property TicksMargin:integer read FTicksMargin write SetTicksMargin;
+    property LTicks:integer read FLTicks write SetLargeTicks;
+    property LTicksSize:integer read FLTicksSize write SetLTicksSize;
+    property LTicksColor:TColor read FLTicksColor write SetLTicksColor;
+    property STicks:integer read FSTicks write SetSTicks;
+    property STicksSize:integer read FSTicksSize write SetSTicksSize;
+    property STicksColor:TColor read FSTicksColor write SetSTicksColor;
+    property ShowValues:Boolean read FShowValues write SetShowValues;
+    property ValuesMargin:integer read FValuesMargin write SetValueMargin;
+    property ValuesFont:TFont read FValuesFont write SetValuesFont;
+    property DefKnobRadius:integer read FDefKnobRadius write SetDefKnobRadius;
+    property Transparent:Boolean read FTransparent write SetTransparent;
+    property OnPaint;
+    property OnChange: TNotifyEvent read FOnChange write FOnChange;
+  public
+    Background:TBGRABitmap;
+    constructor Create(AOwner: TComponent); override;
+    destructor Destroy; override;
+  end;
+
+
+  { TuEMultiTurn }
+
+  TuEMultiTurn = class(TCustomuEMultiTurn)
+  private
+  published
+    procedure DrawScales(LBitmap:TBGRABitmap); override;
+    property Picture;
+    property Position;
+//    property TicksMargin;
+//    property LTicks;
+//    property LTicksSize;
+//    property LTicksColor;
+//    property STicks;
+//    property STicksSize;
+//    property STicksColor;
+//    property ShowValues;
+//    property ValuesMargin;
+//    property ValuesFont;
+    property Transparent;
+    property DefKnobRadius;
+    property OnChange;
+    property OnPaint;
+    property OnMouseDown;
+    property OnMouseMove;
+    property OnMouseUp;
+//
+    property Align;
+    property Anchors;
+    property BorderSpacing;
+    property Color;
+    property Constraints;
+    property DragCursor;
+    property DragKind;
+    property DragMode;
+    property Enabled;
+    property ParentColor;
+    property ParentShowHint;
+    property PopupMenu;
+    property ShowHint;
+    property Visible;
+    property OnChangeBounds;
+    property OnMouseEnter;
+    property OnMouseLeave;
+    property OnMouseWheel;
+    property OnMouseWheelDown;
+    property OnMouseWheelUp;
+    property OnClick;
+    property OnConstrainedResize;
+    property OnDblClick;
+    property OnDragDrop;
+    property OnDragOver;
+    property OnEndDock;
+    property OnEndDrag;
+    property OnResize;
+    property OnStartDock;
+    property OnStartDrag;
+
+//    property Angle;
+  end;
+
+
+procedure Register;
+
+implementation
+
+{ TCustomuEMultiTurn }
+
+procedure TCustomuEMultiTurn.SetPosition(const AValue: Real);
+begin
+  if FPosition=AValue then exit;
+  ForcePosition(AValue);
+end;
+
+procedure TCustomuEMultiTurn.ForcePosition(const AValue: Real);
+begin
+  FPosition:=AValue;
+  inherited Angle:=PostoAngle(FPosition)/10;
+  invalidate;
+  DoOnChange;
+end;
+
+procedure TCustomuEMultiTurn.SetShowValues(const AValue: Boolean);
+begin
+  if FShowValues=AValue then exit;
+  FShowValues:=AValue;
+  UpdateScales;
+  invalidate;
+end;
+
+procedure TCustomuEMultiTurn.SetTransparent(const AValue: Boolean);
+begin
+  if FTransparent=AValue then exit;
+  FTransparent:=AValue;
+  UpdateScales;
+  invalidate;
+end;
+
+procedure TCustomuEMultiTurn.SetSTicks(const AValue: integer);
+begin
+  if FSTicks=AValue then exit;
+  FSTicks:=AValue;
+  UpdateScales;
+  invalidate;
+end;
+
+procedure TCustomuEMultiTurn.SetSTicksColor(const AValue: TColor);
+begin
+  if FSTicksColor=AValue then exit;
+  FSTicksColor:=AValue;
+  UpdateScales;
+  invalidate;
+end;
+
+procedure TCustomuEMultiTurn.SetSTicksSize(const AValue: integer);
+begin
+  if FSTicksSize=AValue then exit;
+  FSTicksSize:=AValue;
+  UpdateScales;
+  invalidate;
+end;
+
+procedure TCustomuEMultiTurn.SetTicksMargin(const AValue: integer);
+begin
+  if FTicksMargin=AValue then exit;
+  FTicksMargin:=AValue;
+  UpdateScales;
+  invalidate;
+end;
+
+procedure TCustomuEMultiTurn.SetValueMargin(const AValue: integer);
+begin
+  if FValuesMargin=AValue then exit;
+  FValuesMargin:=AValue;
+  UpdateScales;
+  invalidate;
+end;
+
+procedure TCustomuEMultiTurn.SetValuesFont(const AValue: TFont);
+begin
+  if FValuesFont.IsEqual(AValue) then exit;
+  FValuesFont.Assign(AValue);
+end;
+
+class procedure TCustomuEMultiTurn.WSRegisterClass;
+begin
+  inherited WSRegisterClass;
+end;
+
+procedure TCustomuEMultiTurn.CalculatePreferredSize(var PreferredWidth,
+  PreferredHeight: integer; WithThemeSpace: Boolean);
+begin
+  inherited CalculatePreferredSize(PreferredWidth, PreferredHeight,
+    WithThemeSpace);
+end;
+
+class function TCustomuEMultiTurn.GetControlClassDefaultSize: TSize;
+begin
+  Result.CX := 45;
+  Result.CY := 45;
+end;
+
+procedure TCustomuEMultiTurn.Paint;
+begin
+  Background.Draw(inherited Canvas,0,0,false);
+  inherited Paint;
+end;
+
+procedure TCustomuEMultiTurn.DefaultPicture;
+var
+  tbmp:TBGRABitmap;
+  c:real;
+begin
+  c:=(FDefKnobRadius-1)/2;
+  tbmp :=TBGRABitmap.Create(FDefKnobRadius,FDefKnobRadius,BGRAPixelTransparent);
+  tbmp.FillEllipseAntialias(c,c,c,c,BGRABlack);
+  tbmp.GradientFill(0,0,FDefKnobRadius,FDefKnobRadius,
+                      BGRA(128,128,128,255),BGRA(0,0,0,0),
+                      gtRadial,PointF(c,c),PointF(0,c),
+                      dmDrawWithTransparency);
+  tbmp.DrawLineAntialias(c,FDefKnobRadius-7,c,FDefKnobRadius-5,BGRAWhite,2);
+  tbmp.DrawLineAntialias(c,4,c,6,BGRAWhite,2);
+  tbmp.DrawLineAntialias(4,c,6,c,BGRAWhite,2);
+  tbmp.DrawLineAntialias(FDefKnobRadius-7,c,FDefKnobRadius-5,c,BGRAWhite,2);
+
+  tbmp.DrawLineAntialias(FDefKnobRadius-8,7,FDefKnobRadius-10,9,BGRAWhite,2);
+  tbmp.DrawLineAntialias(8,7,10,9,BGRAWhite,2);
+  tbmp.DrawLineAntialias(7,FDefKnobRadius-8,9,FDefKnobRadius-10,BGRAWhite,2);
+  tbmp.DrawLineAntialias(FDefKnobRadius-10,FDefKnobRadius-10,FDefKnobRadius-8,FDefKnobRadius-8,BGRAWhite,2);
+  try
+    Picture.Bitmap.Assign(tbmp.Bitmap);
+  finally
+    tbmp.free;
+  end;
+end;
+
+procedure TCustomuEMultiTurn.Loaded;
+begin
+  inherited Loaded;
+  ForcePosition(FPosition);
+end;
+
+procedure TCustomuEMultiTurn.SetColor(AValue: TColor);
+begin
+  if Color=AValue then exit;
+  inherited SetColor(AValue);
+  UpdateScales;
+end;
+
+procedure TCustomuEMultiTurn.FontChanged(Sender: TObject);
+begin
+  inherited FontChanged(Sender);
+  UpdateScales;
+  invalidate;
+end;
+
+function TCustomuEMultiTurn.AngleToPos(AnAngle: TuEAngle): Real;
+// Convert angle AnAngle to a position.
+begin
+  Result :=  1000*AnAngle/3600;  //FMin + ((FMax - FMin) * (AnAngle - FMinAngle)/(FMaxAngle - FMinAngle));
+end;
+
+function TCustomuEMultiTurn.PosToAngle(Pos: Real): TuEAngle;
+// Convert position Pos to an angle.
+begin
+  Result := Round(Pos*3600/1000);  //FMinAngle + Round((FMaxAngle - FMinAngle) * (Pos - FMin) / (FMax - FMin));
+end;
+
+procedure TCustomuEMultiTurn.DoOnResize;
+begin
+  BackGround.SetSize(width,height);
+  UpdateScales;
+  inherited DoOnResize;
+end;
+
+constructor TCustomuEMultiTurn.Create(AOwner: TComponent);
+begin
+  inherited Create(AOwner);
+  FDefKnobRadius:=34;
+  FPosition:=0;
+  FLTicks:=0;
+  FSTicks:=0;
+  FShowValues:=false;
+  FTransparent:=true;
+  FValuesFont:=TFont.Create;
+  FValuesFont.Name:='Sans';
+  FValuesFont.Orientation:=0;
+  FValuesFont.Style:=[];
+  FValuesFont.Color:=clBlack;
+  FValuesFont.Size:=8;
+  FValuesFont.OnChange:=@FontChanged;
+  if Picture.Bitmap.Width=0 then DefaultPicture;
+  UniqueSize:=true;
+  Center:=true;
+  ControlStyle := ControlStyle + [csReplicatable, csCaptureMouse, csClickEvents, csDoubleClicks];
+  with GetControlClassDefaultSize do
+  begin
+    SetInitialBounds(0, 0, CX, CY);
+    BackGround:=TBGRABitmap.Create(CX,CY);
+  end;
+end;
+
+destructor TCustomuEMultiTurn.Destroy;
+begin
+  FreeThenNil(Background);
+  FValuesFont.OnChange:=nil;
+  FValuesFont.free;
+  inherited Destroy;
+end;
+
+// Convert a APoint to an angle (relative to ACenter),
+// where bottom is 0, left is 900, top is 1800 and so on.
+
+function TCustomuEMultiTurn.PointToAngle(APoint, ACenter: TPoint): TuEAngle;
+var
+  N: Integer;
+begin
+  N := APoint.X - ACenter.X;
+  if N = 0 then
+    if APoint.Y < ACenter.Y then Result := 900 else Result := 2700
+  else
+  begin
+    Result:=Round(ArcTan((ACenter.Y - APoint.Y) / N) * 1800 / PI);
+  end;
+  if N < 0 then Result := Result + 1800;
+  Result := 2700 - Result;
+end;
+
+function TCustomuEMultiTurn.DoMouseWheel(Shift: TShiftState; WheelDelta: Integer;
+  MousePos: TPoint): Boolean;
+begin
+  Result:=inherited DoMouseWheel(Shift, WheelDelta, MousePos);
+  SetPosition(FPosition+WheelDelta/200);
+end;
+
+function TCustomuEMultiTurn.Delta(X,Y:Integer):TuEAngle;
+Var C,M,D:TuEAngle;
+begin
+  if Angle>0 then C:=Round(Angle*10) mod 3600 else C:=3600+(Round(Angle*10) mod 3600);
+  M:=PointToAngle(Point(X, Y), GetCenter);
+  D:=C-M;
+  Delta:=0;
+  if (D>-1800) or (D<1800) then Delta:=-D;
+  if (D>0) and (D>1800) then Delta:=(3600-D);
+  if (D<0) and (D<-1800) then Delta:=-(3600+D);
+end;
+
+procedure TCustomuEMultiTurn.MouseDown(Button: TMouseButton;
+  Shift: TShiftState; X, Y: Integer);
+begin
+  inherited MouseDown(Button, Shift, X, Y);
+  MouseCapture := True;
+  SetPosition(FPosition+AngletoPos(Delta(X,Y)));
+end;
+
+procedure TCustomuEMultiTurn.MouseMove(Shift: TShiftState; X, Y: Integer);
+begin
+  inherited MouseMove(Shift, X, Y);
+  if MouseCapture then SetPosition(FPosition+AngletoPos(Delta(X,Y)));
+end;
+
+procedure TCustomuEMultiTurn.MouseUp(Button: TMouseButton;
+  Shift: TShiftState; X, Y: Integer);
+begin
+  inherited MouseUp(Button, Shift, X, Y);
+  MouseCapture := False;
+end;
+
+procedure TCustomuEMultiTurn.DoOnChange;
+begin
+  if Assigned(FOnChange) then FOnChange(Self);
+end;
+
+function TCustomuEMultiTurn.GetCenter: TPoint;
+begin
+  with Result do
+  begin
+    X := Width div 2;
+    Y := Height div 2;
+  end;
+end;
+
+procedure TCustomuEMultiTurn.SetDefKnobRadius(AValue: integer);
+begin
+  if FDefKnobRadius=AValue then Exit;
+  FDefKnobRadius:=AValue;
+end;
+
+procedure TCustomuEMultiTurn.SetLTicksColor(const AValue: TColor);
+begin
+  if FLTicksColor=AValue then exit;
+  FLTicksColor:=AValue;
+  UpdateScales;
+  invalidate;
+end;
+
+procedure TCustomuEMultiTurn.SetLargeTicks(const AValue: integer);
+begin
+  if FLTicks=AValue then exit;
+  FLTicks:=AValue;
+  UpdateScales;
+  invalidate;
+end;
+
+procedure TCustomuEMultiTurn.SetLTicksSize(const AValue: integer);
+begin
+  if FLTicksSize=AValue then exit;
+  FLTicksSize:=AValue;
+  UpdateScales;
+  invalidate;
+end;
+
+procedure TCustomuEMultiTurn.DrawScales(LBitmap:TBGRABitmap);
+var i,j:integer;
+    x1,y1,x2,y2,lpos:real;
+    xc,yc,langle:real;
+    sn,cn:real;
+    lc,sc,vc:TBGRAPixel;
+    ts:TSize;
+    la:string;
+const
+  FMax=10;
+  FMin=0;
+
+begin
+  if (Picture.Bitmap.Width mod 2) = 0 then xc:=LBitmap.Width/2-1 else xc:=LBitmap.Width/2;
+  if (Picture.Bitmap.Height mod 2) = 0 then yc:=LBitmap.Height/2-1 else yc:=LBitmap.Height/2;
+  lc:=ColorToBGRA(ColorToRGB(FLTicksColor));
+  sc:=ColorToBGRA(ColorToRGB(FSTicksColor));
+  vc:=ColorToBGRA(ColorToRGB(FValuesFont.Color));
+  LBitmap.FontHeight:=abs(FValuesFont.Height);
+  LBitmap.FontStyle:=FValuesFont.Style;
+  LBitmap.FontName:=FValuesFont.Name;
+  LBitmap.FontOrientation:=FValuesFont.Orientation;
+  if FLTicks>0 then For i:=0 to FLTicks do
+  begin
+    lpos:=(i/FLTicks)*(FMax-FMin)+FMin;
+    langle:=PosToAngle(lpos)*PI/1800 +PI/2;
+    sn:=sin(langle);
+    cn:=cos(langle);
+    x1:=xc+FTicksMargin*cn;
+    y1:=yc+FTicksMargin*sn;
+    x2:=xc+(FTicksMargin+FLTicksSize)*cn;
+    y2:=yc+(FTicksMargin+FLTicksSize)*sn;
+    LBitmap.DrawLineAntialias(x1,y1,x2,y2,lc, 1);
+    if FShowValues then
+    begin
+      x2:=xc+(FTicksMargin+FLTicksSize+FValuesMargin)*cn;
+      y2:=yc+(FTicksMargin+FLTicksSize+FValuesMargin)*sn;
+      la:=floattostrF(lpos,ffGeneral,4,2);
+      ts:=LBitmap.TextSize(la);
+      LBitmap.TextOut(trunc(x2+1), trunc(y2-ts.cy/2+1), la, vc, taCenter);
+    end;
+    if (lpos<Fmax) then For j:=1 to FSTicks do
+    begin
+      lpos:=(i/FLTicks)*(FMax-FMin)+FMin+j*((FMax-FMin)/FLTicks)/(FSTicks+1);
+      langle:=PosToAngle(lpos)*PI/1800 +PI/2;
+      sn:=sin(langle);
+      cn:=cos(langle);
+      x1:=xc+FTicksMargin*cn;
+      y1:=yc+FTicksMargin*sn;
+      x2:=xc+(FTicksMargin+FSTicksSize)*cn;
+      y2:=yc+(FTicksMargin+FSTicksSize)*sn;
+      LBitmap.DrawLineAntialias(x1,y1,x2,y2,sc, 1);
+    end;
+  end;
+end;
+
+procedure TCustomuEMultiTurn.UpdateScales;
+begin
+  if ([csLoading,csDestroying]*ComponentState<>[]) then exit;
+  if FTransparent then BackGround.Fill(BGRAPixelTransparent) else BackGround.Fill(ColortoBGRA(ColortoRGB(Color)));
+  DrawScales(BackGround);
+end;
+
+{ TuEMultiTurn }
+
+procedure TuEMultiTurn.DrawScales(LBitmap: TBGRABitmap);
+begin
+  inherited DrawScales(LBitmap);
+end;
+
+procedure Register;
+begin
+  {$I icons\ueMultiTurn_icon.lrs}
+  RegisterComponents('BGRA Controls', [TuEMultiTurn]);
+end;
+
+
+end.

+ 474 - 0
uerotimage.pas

@@ -0,0 +1,474 @@
+
+{------------------------------------------------------------------------------
+
+  Miguel A. Risco Castillo TuERotImage v0.6.3
+  http://ue.accesus.com/uecontrols
+
+  using some ideas from:
+  TRotateImage v1.54 by Kambiz R. Khojasteh
+
+  The contents of this file are subject to the Mozilla Public License
+  Version 1.1 (the "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+  http://www.mozilla.org/MPL/MPL-1.1.html
+
+  Software distributed under the License is distributed on an "AS IS" basis,
+  WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
+  the specific language governing rights and limitations under the License.
+
+------------------------------------------------------------------------------}
+
+unit uERotImage;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs,
+  Types, BGRABitmap, BGRABitmapTypes;
+
+type
+
+  { TuECustomRotImage }
+
+  { TCustomuERotImage }
+
+  TCustomuERotImage = class(TGraphicControl)
+  private
+    FColor: TColor;
+    FPicture: TPicture;
+    FOnPictureChanged: TNotifyEvent;
+    FStretch: Boolean;
+    FCenter: Boolean;
+    FTransparent: Boolean;
+    FProportional: Boolean;
+    FAngle: Extended;
+    FUniqueSize: Boolean;
+    FMaxSize: Integer;
+    FChanging: Boolean;
+    FOnRotation: TNotifyEvent;
+    FBeforeRotation: TNotifyEvent;
+    function GetCanvas: TCanvas;
+    procedure RotateImage(AValue: Extended);
+    procedure ForceRotate(AValue: Extended);
+    procedure SetCenter(const AValue: Boolean);
+    procedure SetPicture(const AValue: TPicture);
+    procedure SetStretch(const AValue: Boolean);
+    procedure SetProportional(const AValue: Boolean);
+    procedure SetTransparent(const AValue: Boolean);
+    procedure SetAngle(const Value: Extended);
+    procedure SetUniqueSize(Value: Boolean);
+  protected
+    class procedure WSRegisterClass; override;
+    procedure PictureChanged(Sender : TObject); virtual;
+    procedure CalculatePreferredSize(var PreferredWidth,
+                                     PreferredHeight: integer;
+                                     WithThemeSpace: Boolean); override;
+    class function GetControlClassDefaultSize: TSize; override;
+    function CanAutoSize(var NewWidth, NewHeight: Integer): Boolean; override;
+    procedure Paint; override;
+    procedure Loaded; override;
+    procedure Resize; override;
+    procedure SetColor(AValue: TColor); override;
+    procedure DoRotation; virtual;
+    procedure DoBeforeRotation; virtual;
+    function DestRect: TRect; virtual;
+    property Canvas: TCanvas read GetCanvas;
+    property MaxSize: Integer read FMaxSize;
+    property Angle: Extended read FAngle write SetAngle;
+    property BorderSpacing;
+    property Center: Boolean read FCenter write SetCenter default False;
+    property Color: tcolor read FColor write SetColor default clDefault;
+    property Picture: TPicture read FPicture write SetPicture;
+    property Proportional: Boolean read FProportional write setProportional default False;
+    property Stretch: Boolean read FStretch write SetStretch default False;
+    property Transparent: Boolean read FTransparent write SetTransparent;
+    property UniqueSize: Boolean read FUniqueSize write SetUniqueSize default False;
+    property OnPictureChanged: TNotifyEvent read FOnPictureChanged write FOnPictureChanged;
+    property OnRotation: TNotifyEvent read FOnRotation write FOnRotation;
+    property BeforeRotation: TNotifyEvent read FBeforeRotation write FBeforeRotation;
+  public
+    Bitmap: TBGRABitmap;
+    constructor Create(AOwner: TComponent); override;
+    destructor Destroy; override;
+    procedure ReDraw;
+  end;
+
+
+  { TuECustomRotImage }
+
+  TuERotImage = class(TCustomuERotImage)
+  published
+    property Align;
+    property Anchors;
+    property Angle;
+    property AutoSize;
+    property BorderSpacing;
+    property Center;
+    property Color;
+    property Constraints;
+    property DragCursor;
+    property DragKind;
+    property DragMode;
+    property Enabled;
+    property MaxSize;
+    property ParentColor;
+    property ParentShowHint;
+    property Picture;
+    property PopupMenu;
+    property Proportional;
+    property ShowHint;
+    property Stretch;
+    property Transparent;
+    property UniqueSize;
+    property Visible;
+    property OnChangeBounds;
+    property OnMouseEnter;
+    property OnMouseLeave;
+    property OnMouseWheel;
+    property OnMouseWheelDown;
+    property OnMouseWheelUp;
+    property OnPaint;
+    property OnPictureChanged;
+    property OnClick;
+    property OnConstrainedResize;
+    property OnDblClick;
+    property OnDragDrop;
+    property OnDragOver;
+    property OnEndDock;
+    property OnEndDrag;
+    property OnMouseDown;
+    property OnMouseMove;
+    property OnMouseUp;
+    property OnResize;
+    property OnRotation;
+    property BeforeRotation;
+    property OnStartDock;
+    property OnStartDrag;
+  end;
+
+
+procedure Register;
+
+implementation
+
+//uses Math;
+
+constructor TCustomuERotImage.Create(AOwner: TComponent);
+begin
+  inherited Create(AOwner);
+  ControlStyle := ControlStyle + [csReplicatable, csCaptureMouse, csClickEvents, csDoubleClicks];
+  AutoSize := False;
+  FCenter := False;
+  FProportional := False;
+  FStretch := False;
+  FTransparent := True;
+  FUniqueSize := False;
+  with GetControlClassDefaultSize do
+  begin
+    SetInitialBounds(0, 0, CX, CY);
+    FPicture := TPicture.Create;
+    FPicture.Bitmap.SetSize(0,0);
+    FPicture.OnChange := @PictureChanged;
+    Bitmap:=TBGRABitmap.Create(CX,CY);
+  end;
+end;
+
+destructor TCustomuERotImage.Destroy;
+begin
+  if Assigned(Bitmap) then
+  begin
+    Bitmap.Free;
+    Bitmap := nil;
+  end;
+  FPicture.OnChange := nil;
+  FPicture.Graphic := nil;
+  FPicture.Free;
+  inherited Destroy;
+end;
+
+procedure TCustomuERotImage.ReDraw;
+begin
+  ForceRotate(FAngle);
+  Paint;
+end;
+
+procedure TCustomuERotImage.Paint;
+
+  procedure DrawFrame;
+  begin
+    with inherited Canvas do
+    begin
+      Pen.Color := clBlack;
+      Pen.Style := psDash;
+      MoveTo(0, 0);
+      LineTo(Self.Width-1, 0);
+      LineTo(Self.Width-1, Self.Height-1);
+      LineTo(0, Self.Height-1);
+      LineTo(0, 0);
+    end;
+  end;
+
+var R:TRect;
+
+begin
+  if csDesigning in ComponentState then DrawFrame;
+  if assigned(Bitmap) then
+  begin
+    R:=DestRect;
+    Bitmap.Draw(Canvas,R,false);
+  end;
+end;
+
+procedure TCustomuERotImage.Loaded;
+begin
+  inherited Loaded;
+  PictureChanged(Self);
+end;
+
+
+procedure TCustomuERotImage.Resize;
+begin
+  inherited Resize;
+  RotateImage(FAngle);
+end;
+
+function TCustomuERotImage.GetCanvas: TCanvas;
+begin
+  Result := inherited Canvas;
+end;
+
+procedure TCustomuERotImage.SetCenter(const AValue: Boolean);
+begin
+  if FCenter = AValue then exit;
+  FCenter := AValue;
+  invalidate;
+end;
+
+procedure TCustomuERotImage.SetPicture(const AValue: TPicture);
+begin
+  if FPicture=AValue then exit;
+  FPicture.Assign(AValue);
+end;
+
+procedure TCustomuERotImage.SetStretch(const AValue: Boolean);
+begin
+  if FStretch = AValue then exit;
+  FStretch := AValue;
+  invalidate;
+end;
+
+procedure TCustomuERotImage.SetProportional(const AValue: Boolean);
+begin
+  if FProportional = AValue then exit;
+  FProportional := AValue;
+  invalidate;
+end;
+
+procedure TCustomuERotImage.SetTransparent(const AValue: Boolean);
+begin
+  if FTransparent = AValue then exit;
+  FTransparent := AValue;
+  ForceRotate(FAngle);
+end;
+
+procedure TCustomuERotImage.SetColor(AValue: TColor);
+begin
+  if FColor = AValue then exit;
+  FColor := AValue;
+  ForceRotate(FAngle);
+  inherited SetColor(AValue);
+end;
+
+procedure TCustomuERotImage.ForceRotate(AValue: Extended);
+var xc,yc:real;
+  w,h:integer;
+  rad,s,c:Extended;
+  tbmp:TBGRABitmap;
+  fillc:TBGRAPixel;
+begin
+  if (csLoading in ComponentState) or FChanging then exit;
+  FChanging := True;
+  rad:=AValue*PI/180;
+  s:=abs(sin(rad));
+  c:=abs(cos(rad));
+  If FTransparent then Fillc:=BGRAPixelTransparent else Fillc:=ColortoBGRA(ColortoRGB(color));
+  if FPicture.Bitmap.Width>0 then
+  begin
+    xc:=(FPicture.Bitmap.width-1)/2;
+    yc:=(FPicture.Bitmap.height-1)/2;
+    w:= round(FPicture.Bitmap.width*c + FPicture.Bitmap.height*s);
+    h:= round(FPicture.Bitmap.width*s + FPicture.Bitmap.height*c);
+    if UniqueSize then tbmp:=TBGRABitmap.Create(MaxSize,MaxSize,Fillc)
+    else tbmp:=TBGRABitmap.Create(w,h,Fillc);
+    Bitmap.SetSize(1,1);
+    Bitmap.Fill(Fillc);
+    Bitmap.Assign(FPicture.Bitmap);
+  end else
+  begin
+    xc:=(width-1)/2;
+    yc:=(height-1)/2;
+    tbmp:=TBGRABitmap.Create(width,height,Fillc);
+    Bitmap.SetSize(width,height);
+    Bitmap.Fill(Fillc);
+  end;
+  w:=Round((tbmp.Width)/2-1);
+  h:=Round((tbmp.Height)/2-1);
+  DoBeforeRotation;
+  tbmp.PutImageAngle(w,h,Bitmap,AValue,xc,yc);
+  Bitmap.Assign(tbmp);
+  tbmp.free;
+  try
+    if AutoSize and (MaxSize <> 0) then
+    begin
+      InvalidatePreferredSize;
+      AdjustSize;
+      if UniqueSize then SetBounds(Left, Top, MaxSize, MaxSize)
+      else SetBounds(Left, Top, Bitmap.Width, Bitmap.Height);
+    end;
+  finally
+    FChanging := False;
+  end;
+  Invalidate;
+  DoRotation;
+end;
+
+procedure TCustomuERotImage.RotateImage(AValue:Extended);
+begin
+  if AValue <> FAngle then ForceRotate(FAngle);
+end;
+
+procedure TCustomuERotImage.SetAngle(const Value: Extended);
+begin
+  if Value <> FAngle then
+  begin
+    FAngle := Value;
+    ForceRotate(FAngle);
+  end;
+end;
+
+procedure TCustomuERotImage.SetUniqueSize(Value: Boolean);
+begin
+  if Value <> UniqueSize then
+  begin
+    FUniqueSize := Value;
+    ForceRotate(FAngle);
+  end;
+end;
+
+procedure TCustomuERotImage.PictureChanged(Sender: TObject);
+begin
+  if not (csLoading in ComponentState) then
+  begin
+    if FPicture.Bitmap.width>0 then
+    begin
+      if (FPicture.Graphic.MimeType='') and (csDesigning in ComponentState) then
+      begin
+        showmessage('Bug: unsupported Picture format at design time');
+        FPicture.Bitmap.SetSize(0,0);
+        FMaxSize := 0;
+      end else FMaxSize := Round(Sqrt(Sqr(FPicture.Graphic.Width) + Sqr(FPicture.Graphic.Height)));
+    end else FMaxSize := Round(Sqrt(Sqr(Width) + Sqr(Height)));
+    ForceRotate(FAngle);
+    if Assigned(OnPictureChanged) then OnPictureChanged(Self);
+  end;
+end;
+
+procedure TCustomuERotImage.CalculatePreferredSize(var PreferredWidth,
+  PreferredHeight: integer; WithThemeSpace: Boolean);
+begin
+  PreferredWidth := Bitmap.Width;
+  PreferredHeight := Bitmap.Height;
+end;
+
+class function TCustomuERotImage.GetControlClassDefaultSize: TSize;
+begin
+  Result.CX := 90;
+  Result.CY := 90;
+end;
+
+function TCustomuERotImage.CanAutoSize(var NewWidth, NewHeight: Integer): Boolean;
+begin
+  Result := True;
+  if not (csDesigning in ComponentState) or (MaxSize <> 0) then
+  begin
+    if Align in [alNone, alLeft, alRight] then
+      if UniqueSize then
+        NewWidth := MaxSize
+      else
+        NewWidth := Bitmap.Width;
+    if Align in [alNone, alTop, alBottom] then
+      if UniqueSize then
+        NewHeight := MaxSize
+      else
+        NewHeight := Bitmap.Height;
+  end;
+end;
+
+procedure TCustomuERotImage.DoRotation;
+begin
+  if Assigned(FOnRotation) then FOnRotation(Self);
+end;
+
+procedure TCustomuERotImage.DoBeforeRotation;
+begin
+  if Assigned(FBeforeRotation) then FBeforeRotation(Self);
+end;
+
+class procedure TCustomuERotImage.WSRegisterClass;
+begin
+  inherited WSRegisterClass;
+end;
+
+function TCustomuERotImage.DestRect: TRect;
+var
+  PicWidth: Integer;
+  PicHeight: Integer;
+  ImgWidth: Integer;
+  ImgHeight: Integer;
+  w: Integer;
+  h: Integer;
+begin
+  if not Assigned(Bitmap) then exit;
+  PicWidth := Bitmap.Width;
+  PicHeight := Bitmap.Height;
+  ImgWidth := ClientWidth;
+  ImgHeight := ClientHeight;
+  if Stretch or (Proportional and ((PicWidth > ImgWidth) or (PicHeight > ImgHeight))) then
+  begin
+    if Proportional and (PicWidth > 0) and (PicHeight > 0) then
+    begin
+      w:=ImgWidth;
+      h:=(PicHeight*w) div PicWidth;
+      if h>ImgHeight then
+      begin
+        h:=ImgHeight;
+        w:=(PicWidth*h) div PicHeight;
+      end;
+      PicWidth:=w;
+      PicHeight:=h;
+    end
+    else begin
+      PicWidth := ImgWidth;
+      PicHeight := ImgHeight;
+    end;
+  end;
+  Result:=Rect(0,0,PicWidth,PicHeight);
+  if Center then
+{$IFDEF WINDOWS}
+    OffsetRect(Result,(ImgWidth-PicWidth) div 2,(ImgHeight-PicHeight) div 2);
+{$ELSE}
+    OffsetRect(Result,-(ImgWidth-PicWidth) div 2,-(ImgHeight-PicHeight) div 2);
+{$ENDIF}
+end;
+
+procedure Register;
+begin
+  {$I icons\uerotimage_icon.lrs}
+  RegisterComponents('BGRA Controls',[TuERotImage]);
+end;
+
+
+end.
+

+ 236 - 0
ueselector.pas

@@ -0,0 +1,236 @@
+{-----------------------------------------------------------------------------
+Miguel A. Risco Castillo TuESelector v0.3.3
+http://ue.accesus.com/uecontrols
+
+The contents of this file are subject to the Mozilla Public License
+Version 1.1 (the "License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/MPL-1.1.html
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
+the specific language governing rights and limitations under the License.
+-----------------------------------------------------------------------------}
+
+unit uESelector;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, ExtCtrls,
+  LCLIntf, LCLType, LCLProc, Types,
+  BGRABitmap, BGRABitmapTypes, uEKnob;
+
+type
+  { TCustomuESelector }
+  TCustomuESelector = class(TCustomuEKnob)
+  private
+    FIndex: Integer;
+    FItems: TStringList;
+    procedure SetIndex(const AValue: Integer);
+    procedure SetItems(const AValue: TStringList);
+  protected
+    procedure ItemsChanged(Sender:TObject); virtual;
+    procedure DefaultPicture; override;
+    procedure ForcePosition(const AValue: Real); override;
+    property Index: Integer read FIndex write SetIndex;
+    property Items: TStringList read FItems write SetItems;
+  public
+    constructor Create(AOwner: TComponent); override;
+    destructor Destroy; override;
+    procedure DrawScales(LBitmap:TBGRABitmap); override;
+  end;
+
+
+  TuESelector = class(TCustomuESelector)
+  published
+    property MaxAngle;
+    property MinAngle;
+    property OffsetAngle;
+    property Picture;
+    property Index;
+    property Items;
+    property LTicksSize;
+    property LTicksColor;
+    property TicksMargin;
+    property ShowValues;
+    property ValuesMargin;
+    property ValuesFont;
+    property Transparent;
+    property OnChange;
+    property OnPaint;
+    property OnMouseDown;
+    property OnMouseMove;
+    property OnMouseUp;
+//
+    property Align;
+    property Anchors;
+    property BorderSpacing;
+    property Color;
+    property Constraints;
+    property DragCursor;
+    property DragKind;
+    property DragMode;
+    property Enabled;
+    property ParentColor;
+    property ParentShowHint;
+    property PopupMenu;
+    property ShowHint;
+    property Visible;
+    property OnChangeBounds;
+    property OnMouseEnter;
+    property OnMouseLeave;
+    property OnMouseWheel;
+    property OnMouseWheelDown;
+    property OnMouseWheelUp;
+    property OnClick;
+    property OnConstrainedResize;
+    property OnDblClick;
+    property OnDragDrop;
+    property OnDragOver;
+    property OnEndDock;
+    property OnEndDrag;
+    property OnResize;
+    property OnStartDock;
+    property OnStartDrag;
+
+  end;
+
+
+procedure Register;
+
+implementation
+
+procedure TCustomuESelector.SetIndex(const AValue: Integer);
+begin
+  if FIndex=AValue then exit;
+  FIndex:=AValue;
+  ForcePosition(AValue);
+end;
+
+procedure TCustomuESelector.SetItems(const AValue: TStringList);
+begin
+  if FItems.Equals(AValue) then exit;
+  if AValue.Count>2 then FItems.Assign(AValue);
+end;
+
+procedure TCustomuESelector.DefaultPicture;
+var
+  TBmp: TBGRABitmap;
+  c:real;
+begin
+  c:=(DefKnobRadius-1)/2;
+  tbmp :=TBGRABitmap.Create(DefKnobRadius,DefKnobRadius,BGRAPixelTransparent);
+  tbmp.FillEllipseAntialias(c,c,c,c,BGRABlack);
+  tbmp.GradientFill(0,0,DefKnobRadius,DefKnobRadius,
+                      BGRA(128,128,128,255),BGRA(0,0,0,0),
+                      gtRadial,PointF(c,c),PointF(0,c),
+                      dmDrawWithTransparency);
+  tbmp.FillRectAntialias(c-5,0,c+5,DefKnobRadius,BGRABlack);
+  tbmp.DrawLineAntialias(c,c+5,c,DefKnobRadius-5,BGRAWhite,2);
+  try
+    Picture.Bitmap.Assign(tbmp.Bitmap);
+  finally
+    tbmp.Free;
+  end;
+end;
+
+procedure TCustomuESelector.ItemsChanged(Sender: TObject);
+begin
+  FLTicks:=FItems.Count;
+  FMax:=FItems.Count-1;
+  ForcePosition(FIndex);
+  UpdateScales;
+  invalidate;
+end;
+
+constructor TCustomuESelector.Create(AOwner: TComponent);
+begin
+  FItems:=TStringList.Create;
+  FItems.Add('S1=10');
+  FItems.Add('S2=20');
+  FItems.Add('S3=30');
+  FItems.Add('S4=40');
+  FItems.Add('S5=50');
+  FItems.Add('S6=60');
+  FItems.Add('S7=70');
+  inherited Create(AOwner);
+  FMax:=6;
+  FMin:=0;
+  FValuesMargin:=10;
+  FLTicksSize:=5;
+  FIndex:=0;
+  FItems.OnChange := @ItemsChanged;
+end;
+
+destructor TCustomuESelector.Destroy;
+begin
+  FItems.OnChange:=nil;
+  FreeAndNil(FItems);
+  inherited Destroy;
+end;
+
+procedure TCustomuESelector.DrawScales(LBitmap: TBGRABitmap);
+var i:integer;
+    x1,y1,x2,y2,lpos:real;
+    xc,yc,langle:real;
+    sn,cn:real;
+    lc,vc:TBGRAPixel;
+    ts:TSize;
+    la:string;
+    ss:boolean;
+begin
+  xc:=LBitmap.Width/2-1;
+  yc:=LBitmap.Height/2-1;
+  lc:=ColorToBGRA(ColorToRGB(FLTicksColor));
+  vc:=ColorToBGRA(ColorToRGB(FValuesFont.Color));
+  LBitmap.FontHeight:=abs(FValuesFont.Height);
+  LBitmap.FontStyle:=FValuesFont.Style;
+  LBitmap.FontName:=FValuesFont.Name;
+  LBitmap.FontOrientation:=FValuesFont.Orientation;
+  ss:=((FMaxAngle-FMinAngle) mod 3600)=0;
+  if FItems.Count>0 then For i:=0 to  FItems.Count-1 do
+  begin
+    lpos:=(i/(FItems.Count-1))*(FMax-FMin)+FMin;
+    langle:=(PosToAngle(lpos)+FOffsetAngle)*PI/1800 +PI/2;
+    sn:=sin(langle);
+    cn:=cos(langle);
+    x1:=xc+FTicksMargin*cn;
+    y1:=yc+FTicksMargin*sn;
+    x2:=xc+(FTicksMargin+FLTicksSize)*cn;
+    y2:=yc+(FTicksMargin+FLTicksSize)*sn;
+    if FLTicksSize>0 then LBitmap.DrawLineAntialias(x1,y1,x2,y2,lc, 1);
+    if FShowValues  and not(ss and (i=0)) then
+    begin
+      la:=FItems.Names[i];
+      if la='' then la:=FItems.ValueFromIndex[i];
+      ts:=LBitmap.TextSize(la);
+      x2:=xc+(FTicksMargin+FLTicksSize+FValuesMargin+ts.cx/8)*cn;
+      y2:=yc+(FTicksMargin+FLTicksSize+FValuesMargin)*sn-ts.cy/2;
+      LBitmap.TextOut(round(x2), round(y2), la, vc, taCenter);
+    end;
+  end;
+end;
+
+procedure TCustomuESelector.ForcePosition(const AValue: Real);
+var lastindex:integer;
+begin
+  if AValue<FMin then FPosition:=FMin
+  else if AValue>FMax then FPosition:=FMax
+  else FPosition:=AValue;
+  lastindex:=FIndex;
+  FIndex:=round(FPosition);
+  Angle:=(PostoAngle(FIndex)+FOffsetAngle)/10;
+  if FIndex<>lastindex then DoOnChange;
+end;
+
+procedure Register;
+begin
+  {$I icons\ueselector_icon.lrs}
+  RegisterComponents('BGRA Controls', [TuESelector]);
+end;
+
+
+end.