GR32_RangeBars.pas 54 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105
  1. unit GR32_RangeBars;
  2. (* ***** BEGIN LICENSE BLOCK *****
  3. * Version: MPL 1.1 or LGPL 2.1 with linking exception
  4. *
  5. * The contents of this file are subject to the Mozilla Public License Version
  6. * 1.1 (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. * http://www.mozilla.org/MPL/
  9. *
  10. * Software distributed under the License is distributed on an "AS IS" basis,
  11. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12. * for the specific language governing rights and limitations under the
  13. * License.
  14. *
  15. * Alternatively, the contents of this file may be used under the terms of the
  16. * Free Pascal modified version of the GNU Lesser General Public License
  17. * Version 2.1 (the "FPC modified LGPL License"), in which case the provisions
  18. * of this license are applicable instead of those above.
  19. * Please see the file LICENSE.txt for additional information concerning this
  20. * license.
  21. *
  22. * The Original Code is Graphics32
  23. *
  24. * The Initial Developer of the Original Code is
  25. * Alex A. Denisov
  26. *
  27. * Portions created by the Initial Developer are Copyright (C) 2000-2009
  28. * the Initial Developer. All Rights Reserved.
  29. *
  30. * Contributor(s):
  31. * Andre Beckedorf <[email protected]>
  32. * Marc Lafon
  33. *
  34. * ***** END LICENSE BLOCK ***** *)
  35. interface
  36. {$I GR32.inc}
  37. uses
  38. {$IFDEF FPC}
  39. LCLIntf, LMessages, LCLType, Graphics, Controls, Forms, Dialogs, ExtCtrls,
  40. {$IFDEF Windows} Windows, {$ENDIF}
  41. {$ELSE}
  42. Windows, Messages, {$IFDEF INLININGSUPPORTED}Types,{$ENDIF}
  43. Graphics, Controls, Forms, Dialogs, ExtCtrls,
  44. {$ENDIF}
  45. SysUtils, Classes, GR32;
  46. type
  47. TRBDirection = (drLeft, drUp, drRight, drDown);
  48. TRBDirections = set of TRBDirection;
  49. TRBZone = (zNone, zBtnPrev, zTrackPrev, zHandle, zTrackNext, zBtnNext);
  50. TRBStyle = (rbsDefault, rbsMac);
  51. TRBBackgnd = (bgPattern, bgSolid);
  52. TRBGetSizeEvent = procedure(Sender: TObject; var Size: Integer) of object;
  53. TArrowBar = class(TCustomControl)
  54. private
  55. FBackgnd: TRBBackgnd;
  56. FBorderStyle: TBorderStyle;
  57. FButtonSize: Integer;
  58. FHandleColor: TColor;
  59. FButtoncolor:TColor;
  60. FHighLightColor:TColor;
  61. FShadowColor:TColor;
  62. FBorderColor:TColor;
  63. FKind: TScrollBarKind;
  64. FShowArrows: Boolean;
  65. FShowHandleGrip: Boolean;
  66. FStyle: TRBStyle;
  67. FOnChange: TNotifyEvent;
  68. FOnUserChange: TNotifyEvent;
  69. FLockUpdate: integer;
  70. procedure SetButtonSize(Value: Integer);
  71. procedure SetHandleColor(Value: TColor);
  72. procedure SetHighLightColor(Value: TColor);
  73. procedure SetShadowColor(Value: TColor);
  74. procedure SetButtonColor(Value: TColor);
  75. procedure SetBorderColor(Value: TColor);
  76. procedure SetKind(Value: TScrollBarKind);
  77. procedure SetShowArrows(Value: Boolean);
  78. procedure SetShowHandleGrip(Value: Boolean);
  79. procedure SetStyle(Value: TRBStyle);
  80. procedure SetBackgnd(Value: TRBBackgnd);
  81. {$IFDEF FPC}
  82. procedure CMEnabledChanged(var Message: TLMessage); message CM_ENABLEDCHANGED;
  83. procedure CMMouseLeave(var Message: TLMessage); message CM_MOUSELEAVE;
  84. procedure WMNCCalcSize(var Message: TLMNCCalcSize); message LM_NCCALCSIZE;
  85. procedure WMEraseBkgnd(var Message: TLmEraseBkgnd); message LM_ERASEBKGND;
  86. {$IFDEF Windows}
  87. procedure WMNCPaint(var Message: TWMNCPaint); message LM_NCPAINT;
  88. {$ENDIF}
  89. {$ELSE}
  90. procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
  91. procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
  92. procedure WMNCCalcSize(var Message: TWMNCCalcSize); message WM_NCCALCSIZE;
  93. procedure WMNCPaint(var Message: TWMNCPaint); message WM_NCPAINT;
  94. procedure WMEraseBkgnd(var Message: TWmEraseBkgnd); message WM_ERASEBKGND;
  95. {$ENDIF}
  96. protected
  97. FGenChange: Boolean;
  98. FDragZone: TRBZone;
  99. FHotZone: TRBZone;
  100. FTimer: TTimer;
  101. FTimerMode: Integer;
  102. FStored: TPoint;
  103. FPosBeforeDrag: Single;
  104. procedure BeginLockUpdate;
  105. procedure EndLockUpdate;
  106. property LockUpdate: integer read FLockUpdate;
  107. procedure DoChange; virtual;
  108. procedure DoDrawButton(R: TRect; Direction: TRBDirection; Pushed, Enabled, Hot: Boolean); virtual;
  109. procedure DoDrawHandle(R: TRect; Horz: Boolean; Pushed, Hot: Boolean); virtual;
  110. procedure DoDrawTrack(R: TRect; Direction: TRBDirection; Pushed, Enabled, Hot: Boolean); virtual;
  111. function DrawEnabled: Boolean; virtual;
  112. function GetBorderSize: Integer;
  113. function GetHandleRect: TRect; virtual;
  114. function GetButtonSize: Integer;
  115. function GetTrackBoundary: TRect;
  116. function GetZone(X, Y: Integer): TRBZone;
  117. function GetZoneRect(Zone: TRBZone): TRect;
  118. procedure MouseLeft; virtual;
  119. procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  120. procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  121. procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  122. procedure Paint; override;
  123. procedure SetBorderStyle(Value: TBorderStyle); {$IFDEF FPC} override; {$ENDIF}
  124. procedure StartDragTracking;
  125. procedure StartHotTracking;
  126. procedure StopDragTracking;
  127. procedure StopHotTracking;
  128. procedure TimerHandler(Sender: TObject); virtual;
  129. public
  130. constructor Create(AOwner: TComponent); override;
  131. property Color default clScrollBar;
  132. property Backgnd: TRBBackgnd read FBackgnd write SetBackgnd;
  133. property BorderStyle: TBorderStyle read FBorderStyle write SetBorderStyle default bsSingle;
  134. property ButtonSize: Integer read FButtonSize write SetButtonSize default 0;
  135. property HandleColor: TColor read FHandleColor write SetHandleColor default clBtnShadow;
  136. property ButtonColor: TColor read FButtonColor write SetButtonColor default clBtnFace;
  137. property HighLightColor: TColor read FHighLightColor write SetHighLightColor default clBtnHighlight;
  138. property ShadowColor: TColor read FShadowColor write SetShadowColor default clBtnShadow;
  139. property BorderColor: TColor read FBorderColor write SetBorderColor default clWindowFrame;
  140. property Kind: TScrollBarKind read FKind write SetKind default sbHorizontal;
  141. property ShowArrows: Boolean read FShowArrows write SetShowArrows default True;
  142. property ShowHandleGrip: Boolean read FShowHandleGrip write SetShowHandleGrip;
  143. property Style: TRBStyle read FStyle write SetStyle default rbsDefault;
  144. property OnChange: TNotifyEvent read FOnChange write FOnChange;
  145. property OnUserChange: TNotifyEvent read FOnUserChange write FOnUserChange;
  146. end;
  147. TRBIncrement = 1..32768;
  148. TRangeBarChangingEvent = procedure(Sender: TObject; ANewPosition: Single; var Handled: boolean) of object;
  149. TCustomRangeBar = class(TArrowBar)
  150. private
  151. FCentered: Boolean;
  152. FEffectiveWindow: Integer;
  153. FIncrement: TRBIncrement;
  154. FPosition: Single;
  155. FRange: Integer;
  156. FWindow: Integer;
  157. FOnUserChanging: TRangeBarChangingEvent;
  158. function IsPositionStored: Boolean;
  159. procedure SetPosition(Value: Single);
  160. procedure SetRange(Value: Integer);
  161. procedure SetWindow(Value: Integer);
  162. protected
  163. procedure DoChanging(ANewPosition: Single; var Handled: boolean); virtual;
  164. procedure AdjustPosition; overload;
  165. procedure AdjustPosition(var APosition: Single); overload;
  166. function DoMouseWheel(Shift: TShiftState; WheelDelta: Integer;
  167. MousePos: TPoint): Boolean; override;
  168. function DrawEnabled: Boolean; override;
  169. function GetHandleRect: TRect; override;
  170. procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  171. procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  172. procedure TimerHandler(Sender: TObject); override;
  173. procedure UpdateEffectiveWindow;
  174. property EffectiveWindow: Integer read FEffectiveWindow;
  175. public
  176. constructor Create(AOwner: TComponent); override;
  177. procedure Resize; override;
  178. procedure SetParams(NewRange, NewWindow: Integer);
  179. property Centered: Boolean read FCentered write FCentered;
  180. property Increment: TRBIncrement read FIncrement write FIncrement default 8;
  181. property Position: Single read FPosition write SetPosition stored IsPositionStored;
  182. property Range: Integer read FRange write SetRange default 0;
  183. property Window: Integer read FWindow write SetWindow default 0;
  184. property OnUserChanging: TRangeBarChangingEvent read FOnUserChanging write FOnUserChanging;
  185. end;
  186. TRangeBar = class(TCustomRangeBar)
  187. published
  188. property Align;
  189. property Anchors;
  190. property Constraints;
  191. property Color;
  192. property Backgnd;
  193. property BorderStyle;
  194. property ButtonSize;
  195. property Enabled;
  196. property HandleColor;
  197. property ButtonColor;
  198. property HighLightColor;
  199. property ShadowColor;
  200. property BorderColor;
  201. property Increment;
  202. property Kind;
  203. property Range;
  204. property Style;
  205. property Visible;
  206. property Window;
  207. property ShowArrows;
  208. property ShowHandleGrip;
  209. property Position; // this should be located after the Range property
  210. property OnChange;
  211. property OnDragDrop;
  212. property OnDragOver;
  213. property OnEndDrag;
  214. property OnMouseDown;
  215. property OnMouseMove;
  216. property OnMouseUp;
  217. property OnMouseWheelUp;
  218. property OnMouseWheelDown;
  219. property OnStartDrag;
  220. property OnUserChange;
  221. property OnUserChanging;
  222. end;
  223. TGaugeBarChangingEvent = procedure(Sender: TObject; ANewPosition: integer; var Handled: boolean) of object;
  224. TCustomGaugeBar = class(TArrowBar)
  225. private
  226. FHandleSize: Integer;
  227. FLargeChange: Integer;
  228. FMax: Integer;
  229. FMin: Integer;
  230. FPosition: Integer;
  231. FSmallChange: Integer;
  232. FOnUserChanging: TGaugeBarChangingEvent;
  233. procedure SetHandleSize(Value: Integer);
  234. procedure SetMax(Value: Integer);
  235. procedure SetMin(Value: Integer);
  236. procedure SetPosition(Value: Integer);
  237. procedure SetLargeChange(Value: Integer);
  238. procedure SetSmallChange(Value: Integer);
  239. protected
  240. procedure DoChanging(ANewPosition: integer; var Handled: boolean); virtual;
  241. procedure AdjustPosition; overload;
  242. procedure AdjustPosition(var APosition: integer); overload;
  243. function DoMouseWheel(Shift: TShiftState; WheelDelta: Integer;
  244. MousePos: TPoint): Boolean; override;
  245. function GetHandleRect: TRect; override;
  246. function GetHandleSize: Integer;
  247. procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  248. procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  249. procedure TimerHandler(Sender: TObject); override;
  250. public
  251. constructor Create(AOwner: TComponent); override;
  252. property HandleSize: Integer read FHandleSize write SetHandleSize default 0;
  253. property LargeChange: Integer read FLargeChange write SetLargeChange default 1;
  254. property Max: Integer read FMax write SetMax default 100;
  255. property Min: Integer read FMin write SetMin default 0;
  256. property Position: Integer read FPosition write SetPosition;
  257. property SmallChange: Integer read FSmallChange write SetSmallChange default 1;
  258. property OnChange;
  259. property OnUserChange;
  260. property OnUserChanging: TGaugeBarChangingEvent read FOnUserChanging write FOnUserChanging;
  261. end;
  262. TGaugeBar = class(TCustomGaugeBar)
  263. published
  264. property Align;
  265. property Anchors;
  266. property Constraints;
  267. property Color;
  268. property Backgnd;
  269. property BorderStyle;
  270. property ButtonSize;
  271. property Enabled;
  272. property HandleColor;
  273. property ButtonColor;
  274. property HighLightColor;
  275. property ShadowColor;
  276. property BorderColor;
  277. property HandleSize;
  278. property Kind;
  279. property LargeChange;
  280. property Max;
  281. property Min;
  282. property ShowArrows;
  283. property ShowHandleGrip;
  284. property Style;
  285. property SmallChange;
  286. property Visible;
  287. property Position;
  288. property OnChange;
  289. property OnDragDrop;
  290. property OnDragOver;
  291. property OnEndDrag;
  292. property OnMouseDown;
  293. property OnMouseMove;
  294. property OnMouseUp;
  295. property OnStartDrag;
  296. property OnUserChange;
  297. end;
  298. { TArrowBarAccess }
  299. { This class is designed to facilitate access to
  300. properties of TArrowBar class when creating custom controls, which
  301. incorporate TArrowBar. It allows controlling up to two arrow bars.
  302. Master is used to read and write properties, slave - only to write.
  303. Well, maybe it is not so useful itself, but it is a common ancestor
  304. for TRangeBarAccess and TGaugeBarAccess classes, which work much the
  305. same way.
  306. When writing a new control, which uses TArrowBar, declare the bar as
  307. protected member, TArrowBarAccess as published property, and assign
  308. its Master to the arrow bar }
  309. TArrowBarAccess = class(TPersistent)
  310. private
  311. FMaster: TArrowBar;
  312. FSlave: TArrowBar;
  313. function GetBackgnd: TRBBackgnd;
  314. function GetButtonSize: Integer;
  315. function GetColor: TColor;
  316. function GetHandleColor: TColor;
  317. function GetHighLightColor: TColor;
  318. function GetButtonColor: TColor;
  319. function GetBorderColor: TColor;
  320. function GetShadowColor: TColor;
  321. function GetShowArrows: Boolean;
  322. function GetShowHandleGrip: Boolean;
  323. function GetStyle: TRBStyle;
  324. procedure SetBackgnd(Value: TRBBackgnd);
  325. procedure SetButtonSize(Value: Integer);
  326. procedure SetColor(Value: TColor);
  327. procedure SetHandleColor(Value: TColor);
  328. procedure SetShowArrows(Value: Boolean);
  329. procedure SetShowHandleGrip(Value: Boolean);
  330. procedure SetStyle(Value: TRBStyle);
  331. procedure SetHighLightColor(Value: TColor);
  332. procedure SetShadowColor(Value: TColor);
  333. procedure SetButtonColor(Value: TColor);
  334. procedure SetBorderColor(Value: TColor);
  335. public
  336. property Master: TArrowBar read FMaster write FMaster;
  337. property Slave: TArrowBar read FSlave write FSlave;
  338. published
  339. property Color: TColor read GetColor write SetColor default clScrollBar;
  340. property Backgnd: TRBBackgnd read GetBackgnd write SetBackgnd default bgPattern;
  341. property ButtonSize: Integer read GetButtonSize write SetButtonSize default 0;
  342. property HandleColor: TColor read GetHandleColor write SetHandleColor default clBtnShadow;
  343. property ButtonColor:TColor read GetButtonColor write SetButtonColor default clBtnFace;
  344. property HighLightColor:TColor read GetHighLightColor write SetHighLightColor default clBtnHighlight;
  345. property ShadowColor:TColor read GetShadowColor write SetShadowColor default clBtnShadow;
  346. property BorderColor:TColor read GetBorderColor write SetBorderColor default clWindowFrame;
  347. property ShowArrows: Boolean read GetShowArrows write SetShowArrows default True;
  348. property ShowHandleGrip: Boolean read GetShowHandleGrip write SetShowHandleGrip;
  349. property Style: TRBStyle read GetStyle write SetStyle;
  350. end;
  351. implementation
  352. uses
  353. Math, GR32_XPThemes;
  354. const
  355. OppositeDirection: array [TRBDirection] of TRBDirection = (drRight, drDown, drLeft, drUp);
  356. tmScrollFirst = 1;
  357. tmScroll = 2;
  358. tmHotTrack = 3;
  359. function ClrLighten(C: TColor; Amount: Integer): TColor;
  360. var
  361. R, G, B: Integer;
  362. begin
  363. {$IFDEF Windows}
  364. if C < 0 then C := GetSysColor(C and $000000FF);
  365. {$ELSE}
  366. C := ColorToRGB(C);
  367. {$ENDIF}
  368. R := C and $FF + Amount;
  369. G := C shr 8 and $FF + Amount;
  370. B := C shr 16 and $FF + Amount;
  371. if R < 0 then R := 0 else if R > 255 then R := 255;
  372. if G < 0 then G := 0 else if G > 255 then G := 255;
  373. if B < 0 then B := 0 else if B > 255 then B := 255;
  374. Result := R or (G shl 8) or (B shl 16);
  375. end;
  376. function MixColors(C1, C2: TColor; W1: Integer): TColor;
  377. var
  378. W2: Cardinal;
  379. begin
  380. Assert(W1 in [0..255]);
  381. W2 := W1 xor 255;
  382. {$IFDEF Windows}
  383. if Integer(C1) < 0 then C1 := GetSysColor(C1 and $000000FF);
  384. if Integer(C2) < 0 then C2 := GetSysColor(C2 and $000000FF);
  385. {$ELSE}
  386. C1 := ColorToRGB(C1);
  387. C2 := ColorToRGB(C2);
  388. {$ENDIF}
  389. Result := Integer(
  390. ((Cardinal(C1) and $FF00FF) * Cardinal(W1) +
  391. (Cardinal(C2) and $FF00FF) * W2) and $FF00FF00 +
  392. ((Cardinal(C1) and $00FF00) * Cardinal(W1) +
  393. (Cardinal(C2) and $00FF00) * W2) and $00FF0000) shr 8;
  394. end;
  395. procedure DitherRect(Canvas: TCanvas; const R: TRect; C1, C2: TColor);
  396. var
  397. {$IFDEF FPC}
  398. Brush: TBrush;
  399. OldBrush: TBrush;
  400. {$ELSE}
  401. B: TBitmap;
  402. Brush: HBRUSH;
  403. {$ENDIF}
  404. begin
  405. if GR32.IsRectEmpty(R) then Exit;
  406. {$IFDEF FPC}
  407. Brush := TBrush.Create;
  408. try
  409. Brush.Color := ColorToRGB(C1);
  410. if C1 <> C2 then
  411. begin
  412. Brush.Bitmap := Graphics.TBitmap.Create;
  413. with Brush.Bitmap do
  414. begin
  415. Height := 2;
  416. Width := 2;
  417. Canvas.Pixels[0,0] := C1;
  418. Canvas.Pixels[1,0] := C2;
  419. Canvas.Pixels[0,1] := C2;
  420. Canvas.Pixels[1,1] := C1;
  421. end;
  422. Brush.Color := ColorToRGB(C1);
  423. end;
  424. OldBrush := TBrush.Create;
  425. try
  426. OldBrush.Assign(Canvas.Brush);
  427. Canvas.Brush.Assign(Brush);
  428. Canvas.FillRect(R);
  429. Canvas.Brush.Assign(OldBrush);
  430. finally
  431. OldBrush.Free;
  432. end;
  433. finally
  434. if Assigned(Brush.Bitmap) then
  435. Brush.Bitmap.Free;
  436. Brush.Free;
  437. end;
  438. {$ELSE}
  439. if C1 = C2 then
  440. Brush := CreateSolidBrush(ColorToRGB(C1))
  441. else
  442. begin
  443. B := AllocPatternBitmap(C1, C2);
  444. B.HandleType := bmDDB;
  445. Brush := CreatePatternBrush(B.Handle);
  446. end;
  447. FillRect(Canvas.Handle, R, Brush);
  448. DeleteObject(Brush);
  449. {$ENDIF}
  450. end;
  451. procedure DrawRectEx(Canvas: TCanvas; var R: TRect; Sides: TRBDirections; C: TColor);
  452. begin
  453. if Sides <> [] then with Canvas, R do
  454. begin
  455. Pen.Color := C;
  456. if drUp in Sides then
  457. begin
  458. MoveTo(Left, Top); LineTo(Right, Top); Inc(Top);
  459. end;
  460. if drDown in Sides then
  461. begin
  462. Dec(Bottom); MoveTo(Left, Bottom); LineTo(Right, Bottom);
  463. end;
  464. if drLeft in Sides then
  465. begin
  466. MoveTo(Left, Top); LineTo(Left, Bottom); Inc(Left);
  467. end;
  468. if drRight in Sides then
  469. begin
  470. Dec(Right); MoveTo(Right, Top); LineTo(Right, Bottom);
  471. end;
  472. end;
  473. end;
  474. procedure Frame3D(Canvas: TCanvas; var ARect: TRect; TopColor, BottomColor: TColor; AdjustRect: Boolean = True);
  475. var
  476. TopRight, BottomLeft: TPoint;
  477. begin
  478. with Canvas, ARect do
  479. begin
  480. Pen.Width := 1;
  481. Dec(Bottom); Dec(Right);
  482. TopRight.X := Right;
  483. TopRight.Y := Top;
  484. BottomLeft.X := Left;
  485. BottomLeft.Y := Bottom;
  486. Pen.Color := TopColor;
  487. PolyLine([BottomLeft, TopLeft, TopRight]);
  488. Pen.Color := BottomColor;
  489. Dec(Left);
  490. PolyLine([TopRight, BottomRight, BottomLeft]);
  491. if AdjustRect then
  492. begin
  493. Inc(Top); Inc(Left, 2);
  494. end
  495. else
  496. begin
  497. Inc(Left); Inc(Bottom); Inc(Right);
  498. end;
  499. end;
  500. end;
  501. procedure DrawHandle(Canvas: TCanvas; R: TRect; Color: TColor;
  502. Pushed, ShowGrip, IsHorz: Boolean; ColorBorder: TColor);
  503. var
  504. CHi, CLo: TColor;
  505. I, S: Integer;
  506. begin
  507. CHi := ClrLighten(Color, 24);
  508. CLo := ClrLighten(Color, -24);
  509. Canvas.Brush.Color := ColorBorder;
  510. FrameRect(Canvas.Handle, R, Canvas.Brush.Handle);
  511. GR32.InflateRect(R, -1, -1);
  512. if Pushed then Frame3D(Canvas, R, CLo, Color)
  513. else Frame3D(Canvas, R, CHi, MixColors(ColorBorder, Color, 96));
  514. Canvas.Brush.Color := Color;
  515. Canvas.FillRect(R);
  516. if ShowGrip then
  517. begin
  518. if Pushed then GR32.OffsetRect(R, 1, 1);
  519. if IsHorz then
  520. begin
  521. S := R.Right - R.Left;
  522. R.Left := (R.Left + R.Right) div 2 - 5;
  523. R.Right := R.Left + 2;
  524. Inc(R.Top); Dec(R.Bottom);
  525. if S > 10 then Frame3D(Canvas, R, CHi, CLo, False);
  526. Inc(R.Left, 3); Inc(R.Right, 3);
  527. Frame3D(Canvas, R, CHi, CLo, False);
  528. Inc(R.Left, 3); Inc(R.Right, 3);
  529. Frame3D(Canvas, R, CHi, CLo, False);
  530. Inc(R.Left, 3); Inc(R.Right, 3);
  531. if S > 10 then Frame3D(Canvas, R, CHi, CLo, False);
  532. end
  533. else
  534. begin
  535. I := (R.Top + R.Bottom) div 2;
  536. S := R.Bottom - R.Top;
  537. R.Top := I - 1;
  538. R.Bottom := I + 1;
  539. Dec(R.Right);
  540. Inc(R.Left);
  541. GR32.OffsetRect(R, 0, -4);
  542. if S > 10 then Frame3D(Canvas, R, CHi, CLo, False);
  543. GR32.OffsetRect(R, 0, 3);
  544. Frame3D(Canvas, R, CHi, CLo, False);
  545. GR32.OffsetRect(R, 0, 3);
  546. Frame3D(Canvas, R, CHi, CLo, False);
  547. if S > 10 then
  548. begin
  549. GR32.OffsetRect(R, 0, 3);
  550. Frame3D(Canvas, R, CHi, CLo, False);
  551. end;
  552. end;
  553. end;
  554. end;
  555. procedure DrawArrow(Canvas: TCanvas; R: TRect; Direction: TRBDirection; Color: TColor);
  556. var
  557. X, Y, Sz, Shift: Integer;
  558. begin
  559. X := (R.Left + R.Right - 1) div 2;
  560. Y := (R.Top + R.Bottom - 1) div 2;
  561. Sz := (Min(X - R.Left, Y - R.Top)) * 3 div 4 - 1;
  562. if Sz = 0 then Sz := 1;
  563. if Direction in [drUp, drLeft] then Shift := (Sz + 1) * 1 div 3
  564. else Shift := Sz * 1 div 3;
  565. Canvas.Pen.Color := Color;
  566. Canvas.Brush.Color := Color;
  567. case Direction of
  568. drUp:
  569. begin
  570. Inc(Y, Shift);
  571. Canvas.Polygon([Point(X + Sz, Y), Point(X, Y - Sz), Point(X - Sz, Y)]);
  572. end;
  573. drDown:
  574. begin
  575. Dec(Y, Shift);
  576. Canvas.Polygon([Point(X + Sz, Y), Point(X, Y + Sz), Point(X - Sz, Y)]);
  577. end;
  578. drLeft:
  579. begin
  580. Inc(X, Shift);
  581. Canvas.Polygon([Point(X, Y + Sz), Point(X - Sz, Y), Point(X, Y - Sz)]);
  582. end;
  583. drRight:
  584. begin
  585. Dec(X, Shift);
  586. Canvas.Polygon([Point(X, Y + Sz), Point(X + Sz, Y), Point(X, Y - Sz)]);
  587. end;
  588. end;
  589. end;
  590. const
  591. FIRST_DELAY = 600;
  592. SCROLL_INTERVAL = 100;
  593. HOTTRACK_INTERVAL = 150;
  594. MIN_SIZE = 17;
  595. { TArrowBar }
  596. {$IFDEF FPC}
  597. procedure TArrowBar.CMEnabledChanged(var Message: TLMessage);
  598. {$ELSE}
  599. procedure TArrowBar.CMEnabledChanged(var Message: TMessage);
  600. {$ENDIF}
  601. begin
  602. inherited;
  603. Invalidate;
  604. end;
  605. {$IFDEF FPC}
  606. procedure TArrowBar.CMMouseLeave(var Message: TLMessage);
  607. {$ELSE}
  608. procedure TArrowBar.CMMouseLeave(var Message: TMessage);
  609. {$ENDIF}
  610. begin
  611. MouseLeft;
  612. inherited;
  613. end;
  614. constructor TArrowBar.Create(AOwner: TComponent);
  615. begin
  616. inherited;
  617. ControlStyle := ControlStyle - [csAcceptsControls, csDoubleClicks] + [csOpaque];
  618. Width := 100;
  619. Height := 16;
  620. ParentColor := False;
  621. Color := clScrollBar;
  622. FTimer := TTimer.Create(Self);
  623. FTimer.OnTimer := TimerHandler;
  624. FShowArrows := True;
  625. FBorderStyle := bsSingle;
  626. FHandleColor := clBtnShadow;
  627. FButtonColor := clBtnFace;
  628. FHighLightColor := clBtnHighlight;
  629. FShadowColor := clBtnShadow;
  630. FBorderColor := clWindowFrame;
  631. FShowHandleGrip := True;
  632. end;
  633. procedure TArrowBar.BeginLockUpdate;
  634. begin
  635. Inc(FLockUpdate);
  636. end;
  637. procedure TArrowBar.EndLockUpdate;
  638. begin
  639. Dec(FLockUpdate);
  640. end;
  641. procedure TArrowBar.DoChange;
  642. begin
  643. if (LockUpdate > 0) then
  644. Exit;
  645. BeginLockUpdate;
  646. try
  647. if Assigned(FOnChange) then
  648. FOnChange(Self);
  649. if FGenChange and Assigned(FOnUserChange) then
  650. FOnUserChange(Self);
  651. finally
  652. EndLockUpdate;
  653. end;
  654. end;
  655. procedure TArrowBar.DoDrawButton(R: TRect; Direction: TRBDirection; Pushed, Enabled, Hot: Boolean);
  656. const
  657. EnabledFlags: array [Boolean] of Integer = (DFCS_INACTIVE, 0);
  658. PushedFlags: array [Boolean] of Integer = (0, DFCS_PUSHED or DFCS_FLAT);
  659. DirectionFlags: array [TRBDirection] of Integer = (DFCS_SCROLLLEFT, DFCS_SCROLLUP,
  660. DFCS_SCROLLRIGHT, DFCS_SCROLLDOWN);
  661. {$IFDEF Windows}
  662. DirectionXPFlags: array [TRBDirection] of Cardinal = (ABS_LEFTNORMAL,
  663. ABS_UPNORMAL, ABS_RIGHTNORMAL, ABS_DOWNNORMAL);
  664. {$ENDIF}
  665. var
  666. Edges: TRBDirections;
  667. {$IFDEF Windows}
  668. Flags: Integer;
  669. {$ENDIF}
  670. begin
  671. if Style = rbsDefault then
  672. begin
  673. {$IFDEF FPC}
  674. {$IFNDEF Windows}
  675. Canvas.Brush.Color := clBtnface;
  676. Canvas.FillRect(R);
  677. LCLIntf.DrawFrameControl(Canvas.Handle, R, DFC_BUTTON, 0);
  678. InflateRect(R, -2, -2);
  679. If not DrawEnabled then
  680. begin
  681. InflateRect(R, -1, -1);
  682. OffsetRect(R, 1, 1);
  683. DrawArrow(Canvas, R, Direction, clWhite);
  684. OffsetRect(R, -1, -1);
  685. DrawArrow(Canvas, R, Direction, clGrayText);
  686. end
  687. else
  688. begin
  689. If Pushed then OffsetRect(R, 1, 1);
  690. DrawArrow(Canvas, R, Direction, clBtnText);
  691. end;
  692. {$ENDIF}
  693. {$ENDIF}
  694. {$IFDEF Windows}
  695. if USE_THEMES then
  696. begin
  697. Flags := DirectionXPFlags[Direction];
  698. if not Enabled then Inc(Flags, 3)
  699. else if Pushed then Inc(Flags, 2)
  700. else if Hot then Inc(Flags);
  701. DrawThemeBackground(SCROLLBAR_THEME, Canvas.Handle, SBP_ARROWBTN, Flags, R, nil);
  702. end
  703. else
  704. DrawFrameControl(Canvas.Handle, R, DFC_SCROLL,
  705. DirectionFlags[Direction] or EnabledFlags[DrawEnabled] or PushedFlags[Pushed])
  706. {$ENDIF}
  707. end
  708. else
  709. begin
  710. Edges := [drLeft, drUp, drRight, drDown];
  711. Exclude(Edges, OppositeDirection[Direction]);
  712. if not DrawEnabled then
  713. begin
  714. DrawRectEx(Canvas, R, Edges, fShadowColor);
  715. Canvas.Brush.Color := fButtonColor;
  716. FillRect(Canvas.Handle, R, Canvas.Brush.Handle);
  717. GR32.InflateRect(R, -1, -1);
  718. GR32.OffsetRect(R, 1, 1);
  719. DrawArrow(Canvas, R, Direction, fHighLightColor);
  720. GR32.OffsetRect(R, -1, -1);
  721. DrawArrow(Canvas, R, Direction, fShadowColor);
  722. end
  723. else
  724. begin
  725. DrawRectEx(Canvas, R, Edges, fBorderColor);
  726. if Pushed then
  727. begin
  728. Canvas.Brush.Color := fButtonColor;
  729. FillRect(Canvas.Handle, R, Canvas.Brush.Handle);
  730. GR32.OffsetRect(R, 1, 1);
  731. GR32.InflateRect(R, -1, -1);
  732. end
  733. else
  734. begin
  735. Frame3D(Canvas, R, fHighLightColor, fShadowColor, True);
  736. Canvas.Brush.Color := fButtonColor;
  737. FillRect(Canvas.Handle, R, Canvas.Brush.Handle);
  738. end;
  739. DrawArrow(Canvas, R, Direction, fBorderColor);
  740. end;
  741. end;
  742. end;
  743. procedure TArrowBar.DoDrawHandle(R: TRect; Horz, Pushed, Hot: Boolean);
  744. {$IFDEF Windows}
  745. const
  746. PartXPFlags: array [Boolean] of Cardinal = (SBP_THUMBBTNVERT, SBP_THUMBBTNHORZ);
  747. GripperFlags: array [Boolean] of Cardinal = (SBP_GRIPPERVERT, SBP_GRIPPERHORZ);
  748. var
  749. Flags: Cardinal;
  750. {$ENDIF}
  751. begin
  752. if GR32.IsRectEmpty(R) then Exit;
  753. case Style of
  754. rbsDefault:
  755. begin
  756. {$IFDEF Windows}
  757. if USE_THEMES then
  758. begin
  759. Flags := SCRBS_NORMAL;
  760. if not Enabled then Inc(Flags, 3)
  761. else if Pushed then Inc(Flags, 2)
  762. else if Hot then Inc(Flags);
  763. DrawThemeBackground(SCROLLBAR_THEME, Canvas.Handle, PartXPFlags[Horz], Flags, R, nil);
  764. if ShowHandleGrip then
  765. DrawThemeBackground(SCROLLBAR_THEME, Canvas.Handle, GripperFlags[Horz], 0, R, nil);
  766. end
  767. else
  768. DrawEdge(Canvas.Handle, R, EDGE_RAISED, BF_RECT or BF_MIDDLE);
  769. {$ENDIF}
  770. end;
  771. rbsMac:
  772. begin
  773. DrawHandle(Canvas, R, HandleColor, Pushed, ShowHandleGrip, Horz, fBorderColor);
  774. end;
  775. end;
  776. end;
  777. procedure TArrowBar.DoDrawTrack(R: TRect; Direction: TRBDirection; Pushed, Enabled, Hot: Boolean);
  778. {$IFDEF Windows}
  779. const
  780. PartXPFlags: array [TRBDirection] of Cardinal =
  781. (SBP_LOWERTRACKHORZ, SBP_LOWERTRACKVERT, SBP_UPPERTRACKHORZ, SBP_UPPERTRACKVERT);
  782. {$ENDIF}
  783. var
  784. {$IFDEF Windows}
  785. Flags: Cardinal;
  786. {$ENDIF}
  787. C: TColor;
  788. Edges: set of TRBDirection;
  789. begin
  790. if (R.Right <= R.Left) or (R.Bottom <= R.Top) then Exit;
  791. if Style = rbsDefault then
  792. begin
  793. {$IFDEF Windows}
  794. if USE_THEMES then
  795. begin
  796. Flags := SCRBS_NORMAL;
  797. if Pushed then Inc(Flags, 2);
  798. DrawThemeBackground(SCROLLBAR_THEME, Canvas.Handle, PartXPFlags[Direction], Flags, R, nil);
  799. end
  800. else
  801. {$ENDIF}
  802. begin
  803. if Pushed then DitherRect(Canvas, R, clWindowFrame, clWindowFrame)
  804. else DitherRect(Canvas, R, clBtnHighlight, Color);
  805. end;
  806. end
  807. else
  808. with Canvas, R do
  809. begin
  810. if DrawEnabled then C := FBorderColor
  811. else C := FShadowColor;
  812. Edges := [drLeft, drUp, drRight, drDown];
  813. Exclude(Edges, OppositeDirection[Direction]);
  814. DrawRectEx(Canvas, R, Edges, C);
  815. if Pushed then DitherRect(Canvas, R, fBorderColor,fBorderColor)
  816. else if not GR32.IsRectEmpty(R) then with R do
  817. begin
  818. if DrawEnabled then
  819. begin
  820. Pen.Color := MixColors(fBorderColor, MixColors(fHighLightColor, Color, 127), 32);
  821. case Direction of
  822. drLeft, drUp:
  823. begin
  824. MoveTo(Left, Bottom - 1); LineTo(Left, Top); LineTo(Right, Top);
  825. Inc(Top); Inc(Left);
  826. end;
  827. drRight:
  828. begin
  829. MoveTo(Left, Top); LineTo(Right, Top);
  830. Inc(Top);
  831. end;
  832. drDown:
  833. begin
  834. MoveTo(Left, Top); LineTo(Left, Bottom);
  835. Inc(Left);
  836. end;
  837. end;
  838. if Backgnd = bgPattern then DitherRect(Canvas, R, fHighLightColor, Color)
  839. else DitherRect(Canvas, R, Color, Color);
  840. end
  841. else
  842. begin
  843. Brush.Color := fButtonColor;
  844. FillRect(R);
  845. end;
  846. end;
  847. end;
  848. end;
  849. function TArrowBar.DrawEnabled: Boolean;
  850. begin
  851. Result := Enabled;
  852. end;
  853. function TArrowBar.GetBorderSize: Integer;
  854. const
  855. CSize: array [Boolean] of Integer = (0, 1);
  856. begin
  857. Result := CSize[BorderStyle = bsSingle];
  858. end;
  859. function TArrowBar.GetButtonSize: Integer;
  860. var
  861. W, H: Integer;
  862. begin
  863. if not ShowArrows then Result := 0
  864. else
  865. begin
  866. Result := ButtonSize;
  867. if Kind = sbHorizontal then
  868. begin
  869. W := ClientWidth;
  870. H := ClientHeight;
  871. end
  872. else
  873. begin
  874. W := ClientHeight;
  875. H := ClientWidth;
  876. end;
  877. if Result = 0 then Result := Min(H, 32);
  878. if Result * 2 >= W then Result := W div 2;
  879. if Style = rbsMac then Dec(Result);
  880. if Result < 2 then Result := 0;
  881. end;
  882. end;
  883. function TArrowBar.GetHandleRect: TRect;
  884. begin
  885. Result := Rect(0, 0, 0, 0);
  886. end;
  887. function TArrowBar.GetTrackBoundary: TRect;
  888. begin
  889. Result := ClientRect;
  890. if Kind = sbHorizontal then GR32.InflateRect(Result, -GetButtonSize, 0)
  891. else GR32.InflateRect(Result, 0, -GetButtonSize);
  892. end;
  893. function TArrowBar.GetZone(X, Y: Integer): TRBZone;
  894. var
  895. P: TPoint;
  896. R, R1: TRect;
  897. Sz: Integer;
  898. begin
  899. Result := zNone;
  900. P := Point(X, Y);
  901. R := ClientRect;
  902. if not GR32.PtInrect(R, P) then Exit;
  903. Sz := GetButtonSize;
  904. R1 := R;
  905. if Kind = sbHorizontal then
  906. begin
  907. R1.Right := R1.Left + Sz;
  908. if GR32.PtInRect(R1, P) then Result := zBtnPrev
  909. else
  910. begin
  911. R1.Right := R.Right;
  912. R1.Left := R.Right - Sz;
  913. if GR32.PtInRect(R1, P) then Result := zBtnNext;
  914. end;
  915. end
  916. else
  917. begin
  918. R1.Bottom := R1.Top + Sz;
  919. if GR32.PtInRect(R1, P) then Result := zBtnPrev
  920. else
  921. begin
  922. R1.Bottom := R.Bottom;
  923. R1.Top := R.Bottom - Sz;
  924. if GR32.PtInRect(R1, P) then Result := zBtnNext;
  925. end;
  926. end;
  927. if Result = zNone then
  928. begin
  929. R := GetHandleRect;
  930. P := Point(X, Y);
  931. if GR32.PtInRect(R, P) then Result := zHandle
  932. else
  933. begin
  934. if Kind = sbHorizontal then
  935. begin
  936. if (X > 0) and (X < R.Left) then Result := zTrackPrev
  937. else if (X >= R.Right) and (X < ClientWidth - 1) then Result := zTrackNext;
  938. end
  939. else
  940. begin
  941. if (Y > 0) and (Y < R.Top) then Result := zTrackPrev
  942. else if (Y >= R.Bottom) and (Y < ClientHeight - 1) then Result := zTrackNext;
  943. end;
  944. end;
  945. end;
  946. end;
  947. function TArrowBar.GetZoneRect(Zone: TRBZone): TRect;
  948. const
  949. CEmptyRect: TRect = (Left: 0; Top: 0; Right: 0; Bottom: 0);
  950. var
  951. BtnSize: Integer;
  952. Horz: Boolean;
  953. R: TRect;
  954. begin
  955. Horz := Kind = sbHorizontal;
  956. BtnSize:= GetButtonSize;
  957. case Zone of
  958. zNone: Result := CEmptyRect;
  959. zBtnPrev:
  960. begin
  961. Result := ClientRect;
  962. if Horz then Result.Right := Result.Left + BtnSize
  963. else Result.Bottom := Result.Top + BtnSize;
  964. end;
  965. zTrackPrev..zTrackNext:
  966. begin
  967. Result := GetTrackBoundary;
  968. R := GetHandleRect;
  969. if not DrawEnabled or GR32.IsRectEmpty(R) then
  970. begin
  971. R.Left := (Result.Left + Result.Right) div 2;
  972. R.Top := (Result.Top + Result.Bottom) div 2;
  973. R.Right := R.Left;
  974. R.Bottom := R.Top;
  975. end;
  976. case Zone of
  977. zTrackPrev:
  978. if Horz then Result.Right := R.Left
  979. else Result.Bottom := R.Top;
  980. zHandle:
  981. Result := R;
  982. zTrackNext:
  983. if Horz then Result.Left := R.Right
  984. else Result.Top := R.Bottom;
  985. end;
  986. end;
  987. zBtnNext:
  988. begin
  989. Result := ClientRect;
  990. if Horz then Result.Left := Result.Right - BtnSize
  991. else Result.Top := Result.Bottom - BtnSize;
  992. end;
  993. end;
  994. end;
  995. procedure TArrowBar.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  996. begin
  997. inherited;
  998. if Button <> mbLeft then Exit;
  999. FDragZone := GetZone(X, Y);
  1000. Invalidate;
  1001. FStored.X := X;
  1002. FStored.Y := Y;
  1003. StartDragTracking;
  1004. end;
  1005. procedure TArrowBar.MouseLeft;
  1006. begin
  1007. StopHotTracking;
  1008. end;
  1009. procedure TArrowBar.MouseMove(Shift: TShiftState; X, Y: Integer);
  1010. var
  1011. NewHotZone: TRBZone;
  1012. begin
  1013. inherited;
  1014. if (FDragZone = zNone) and (DrawEnabled) and (MouseCapture) then
  1015. begin
  1016. NewHotZone := GetZone(X, Y);
  1017. if NewHotZone <> FHotZone then
  1018. begin
  1019. FHotZone := NewHotZone;
  1020. if FHotZone <> zNone then StartHotTracking;
  1021. Invalidate;
  1022. end;
  1023. end;
  1024. end;
  1025. procedure TArrowBar.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  1026. begin
  1027. inherited;
  1028. FDragZone := zNone;
  1029. Invalidate;
  1030. StopDragTracking;
  1031. end;
  1032. procedure TArrowBar.Paint;
  1033. const
  1034. CPrevDirs: array [Boolean] of TRBDirection = (drUp, drLeft);
  1035. CNextDirs: array [Boolean] of TRBDirection = (drDown, drRight);
  1036. var
  1037. BSize: Integer;
  1038. ShowEnabled: Boolean;
  1039. R, BtnRect, HandleRect: TRect;
  1040. Horz, ShowHandle: Boolean;
  1041. begin
  1042. R := ClientRect;
  1043. Horz := Kind = sbHorizontal;
  1044. ShowEnabled := DrawEnabled;
  1045. BSize := GetButtonSize;
  1046. if ShowArrows then
  1047. begin
  1048. { left / top button }
  1049. BtnRect := R;
  1050. with BtnRect do if Horz then Right := Left + BSize else Bottom := Top + BSize;
  1051. DoDrawButton(BtnRect, CPrevDirs[Horz], FDragZone = zBtnPrev, ShowEnabled, FHotZone = zBtnPrev);
  1052. { right / bottom button }
  1053. BtnRect := R;
  1054. with BtnRect do if Horz then Left := Right - BSize else Top := Bottom - BSize;
  1055. DoDrawButton(BtnRect, CNextDirs[Horz], FDragZone = zBtnNext, ShowEnabled, FHotZone = zBtnNext);
  1056. end;
  1057. if Horz then GR32.InflateRect(R, -BSize, 0) else GR32.InflateRect(R, 0, -BSize);
  1058. if ShowEnabled then HandleRect := GetHandleRect
  1059. else HandleRect := Rect(0, 0, 0, 0);
  1060. ShowHandle := not GR32.IsRectEmpty(HandleRect);
  1061. DoDrawTrack(GetZoneRect(zTrackPrev), CPrevDirs[Horz], FDragZone = zTrackPrev, ShowEnabled, FHotZone = zTrackPrev);
  1062. DoDrawTrack(GetZoneRect(zTrackNext), CNextDirs[Horz], FDragZone = zTrackNext, ShowEnabled, FHotZone = zTrackNext);
  1063. if ShowHandle then DoDrawHandle(HandleRect, Horz, FDragZone = zHandle, FHotZone = zHandle);
  1064. end;
  1065. procedure TArrowBar.SetBackgnd(Value: TRBBackgnd);
  1066. begin
  1067. if Value <> FBackgnd then
  1068. begin
  1069. FBackgnd := Value;
  1070. Invalidate;
  1071. end;
  1072. end;
  1073. procedure TArrowBar.SetBorderStyle(Value: TBorderStyle);
  1074. begin
  1075. if Value <> FBorderStyle then
  1076. begin
  1077. FBorderStyle := Value;
  1078. {$IFNDEF FPC}
  1079. RecreateWnd;
  1080. {$ELSE}
  1081. Invalidate;
  1082. {$ENDIF}
  1083. end;
  1084. end;
  1085. procedure TArrowBar.SetButtonSize(Value: Integer);
  1086. begin
  1087. if Value <> FButtonSize then
  1088. begin
  1089. FButtonSize := Value;
  1090. Invalidate;
  1091. end;
  1092. end;
  1093. procedure TArrowBar.SetHandleColor(Value: TColor);
  1094. begin
  1095. if Value <> FHandleColor then
  1096. begin
  1097. FHandleColor := Value;
  1098. Invalidate;
  1099. end;
  1100. end;
  1101. procedure TArrowBar.SetHighLightColor(Value: TColor);
  1102. begin
  1103. if Value <> FHighLightColor then
  1104. begin
  1105. FHighLightColor := Value;
  1106. Invalidate;
  1107. end;
  1108. end;
  1109. procedure TArrowBar.SetButtonColor(Value: TColor);
  1110. begin
  1111. if Value <> FButtonColor then
  1112. begin
  1113. FButtonColor := Value;
  1114. Invalidate;
  1115. end;
  1116. end;
  1117. procedure TArrowBar.SetBorderColor(Value: TColor);
  1118. begin
  1119. if Value <> FBorderColor then
  1120. begin
  1121. FBorderColor := Value;
  1122. Invalidate;
  1123. end;
  1124. end;
  1125. procedure TArrowBar.SetShadowColor(Value: TColor);
  1126. begin
  1127. if Value <> FShadowColor then
  1128. begin
  1129. FShadowColor := Value;
  1130. Invalidate;
  1131. end;
  1132. end;
  1133. procedure TArrowBar.SetKind(Value: TScrollBarKind);
  1134. var
  1135. Tmp: Integer;
  1136. begin
  1137. if Value <> FKind then
  1138. begin
  1139. FKind := Value;
  1140. if (csDesigning in ComponentState) and not (csLoading in ComponentState) then
  1141. begin
  1142. Tmp := Width;
  1143. Width := Height;
  1144. Height := Tmp;
  1145. end;
  1146. Invalidate;
  1147. end;
  1148. end;
  1149. procedure TArrowBar.SetShowArrows(Value: Boolean);
  1150. begin
  1151. if Value <> FShowArrows then
  1152. begin
  1153. FShowArrows := Value;
  1154. Invalidate;
  1155. end;
  1156. end;
  1157. procedure TArrowBar.SetShowHandleGrip(Value: Boolean);
  1158. begin
  1159. if Value <> FShowHandleGrip then
  1160. begin
  1161. FShowHandleGrip := Value;
  1162. Invalidate;
  1163. end;
  1164. end;
  1165. procedure TArrowBar.SetStyle(Value: TRBStyle);
  1166. begin
  1167. FStyle := Value;
  1168. {$IFDEF FPC}
  1169. Invalidate;
  1170. {$ELSE}
  1171. RecreateWnd;
  1172. {$ENDIF}
  1173. end;
  1174. procedure TArrowBar.StartDragTracking;
  1175. begin
  1176. FTimer.Interval := FIRST_DELAY;
  1177. FTimerMode := tmScroll;
  1178. TimerHandler(Self);
  1179. FTimerMode := tmScrollFirst;
  1180. FTimer.Enabled := True;
  1181. end;
  1182. procedure TArrowBar.StartHotTracking;
  1183. begin
  1184. FTimer.Interval := HOTTRACK_INTERVAL;
  1185. FTimerMode := tmHotTrack;
  1186. FTimer.Enabled := True;
  1187. end;
  1188. procedure TArrowBar.StopDragTracking;
  1189. begin
  1190. StartHotTracking;
  1191. end;
  1192. procedure TArrowBar.StopHotTracking;
  1193. begin
  1194. FTimer.Enabled := False;
  1195. FHotZone := zNone;
  1196. Invalidate;
  1197. end;
  1198. procedure TArrowBar.TimerHandler(Sender: TObject);
  1199. var
  1200. Pt: TPoint;
  1201. begin
  1202. case FTimerMode of
  1203. tmScrollFirst:
  1204. begin
  1205. FTimer.Interval := SCROLL_INTERVAL;
  1206. FTimerMode := tmScroll;
  1207. end;
  1208. tmHotTrack:
  1209. begin
  1210. Pt := ScreenToClient(Mouse.CursorPos);
  1211. if not GR32.PtInRect(ClientRect, Pt) then
  1212. begin
  1213. StopHotTracking;
  1214. Invalidate;
  1215. end;
  1216. end;
  1217. end;
  1218. end;
  1219. {$IFDEF FPC}
  1220. procedure TArrowBar.WMEraseBkgnd(var Message: TLmEraseBkgnd);
  1221. begin
  1222. Message.Result := -1;
  1223. end;
  1224. procedure TArrowBar.WMNCCalcSize(var Message: TLMNCCalcSize);
  1225. var
  1226. Sz: Integer;
  1227. begin
  1228. Sz := GetBorderSize;
  1229. GR32.InflateRect(Message.CalcSize_Params.rgrc[0], -Sz, -Sz);
  1230. end;
  1231. {$IFDEF Windows}
  1232. procedure TArrowBar.WMNCPaint(var Message: TWMNCPaint);
  1233. procedure DrawNCArea(ADC: HDC; const Clip: HRGN);
  1234. var
  1235. DC: HDC;
  1236. R: TRect;
  1237. begin
  1238. if BorderStyle = bsNone then Exit;
  1239. if ADC = 0 then DC := GetWindowDC(Handle)
  1240. else DC := ADC;
  1241. try
  1242. GetWindowRect(Handle, R);
  1243. OffsetRect(R, -R.Left, -R.Top);
  1244. DrawEdge(DC, R, BDR_SUNKENOUTER, BF_RECT);
  1245. finally
  1246. if ADC = 0 then ReleaseDC(Handle, DC);
  1247. end;
  1248. end;
  1249. begin
  1250. DrawNCArea(0, Message.RGN);
  1251. end;
  1252. {$ENDIF}
  1253. {$ELSE}
  1254. procedure TArrowBar.WMEraseBkgnd(var Message: TWmEraseBkgnd);
  1255. begin
  1256. Message.Result := -1;
  1257. end;
  1258. procedure TArrowBar.WMNCCalcSize(var Message: TWMNCCalcSize);
  1259. var
  1260. Sz: Integer;
  1261. begin
  1262. Sz := GetBorderSize;
  1263. GR32.InflateRect(Message.CalcSize_Params.rgrc[0], -Sz, -Sz);
  1264. end;
  1265. procedure TArrowBar.WMNCPaint(var Message: TWMNCPaint);
  1266. procedure DrawNCArea(ADC: HDC; const Clip: HRGN);
  1267. var
  1268. DC: HDC;
  1269. R: TRect;
  1270. begin
  1271. if BorderStyle = bsNone then Exit;
  1272. if ADC = 0 then DC := GetWindowDC(Handle)
  1273. else DC := ADC;
  1274. try
  1275. GetWindowRect(Handle, R);
  1276. GR32.OffsetRect(R, -R.Left, -R.Top);
  1277. DrawEdge(DC, R, BDR_SUNKENOUTER, BF_RECT);
  1278. finally
  1279. if ADC = 0 then ReleaseDC(Handle, DC);
  1280. end;
  1281. end;
  1282. begin
  1283. DrawNCArea(0, Message.RGN);
  1284. end;
  1285. {$ENDIF}
  1286. { TCustomRangeBar }
  1287. procedure TCustomRangeBar.AdjustPosition;
  1288. begin
  1289. AdjustPosition(FPosition);
  1290. end;
  1291. procedure TCustomRangeBar.AdjustPosition(var APosition: Single);
  1292. begin
  1293. if (APosition > Range - EffectiveWindow) then
  1294. APosition := Range - EffectiveWindow;
  1295. if (APosition < 0) then
  1296. APosition := 0;
  1297. end;
  1298. constructor TCustomRangeBar.Create(AOwner: TComponent);
  1299. begin
  1300. inherited;
  1301. FIncrement := 8;
  1302. end;
  1303. procedure TCustomRangeBar.DoChanging(ANewPosition: Single; var Handled: boolean);
  1304. begin
  1305. if (LockUpdate > 0) then
  1306. Exit;
  1307. BeginLockUpdate;
  1308. try
  1309. if FGenChange and Assigned(FOnUserChanging) then
  1310. FOnUserChanging(Self, ANewPosition, Handled);
  1311. finally
  1312. EndLockUpdate;
  1313. end;
  1314. end;
  1315. function TCustomRangeBar.DoMouseWheel(Shift: TShiftState; WheelDelta: Integer;
  1316. MousePos: TPoint): Boolean;
  1317. const OneHundredTwenteenth = 1 / 120;
  1318. begin
  1319. Result := inherited DoMouseWheel(Shift, WheelDelta, MousePos);
  1320. if not Result then Position := Position + Increment * WheelDelta * OneHundredTwenteenth;
  1321. Result := True;
  1322. end;
  1323. function TCustomRangeBar.DrawEnabled: Boolean;
  1324. begin
  1325. Result := Enabled and (Range > EffectiveWindow);
  1326. end;
  1327. function TCustomRangeBar.GetHandleRect: TRect;
  1328. var
  1329. BtnSz, ClientSz: Integer;
  1330. HandleSz, HandlePos: Integer;
  1331. R: TRect;
  1332. Horz: Boolean;
  1333. begin
  1334. R := Rect(0, 0, ClientWidth, ClientHeight);
  1335. Horz := Kind = sbHorizontal;
  1336. BtnSz := GetButtonSize;
  1337. if Horz then
  1338. begin
  1339. GR32.InflateRect(R, -BtnSz, 0);
  1340. ClientSz := R.Right - R.Left;
  1341. end
  1342. else
  1343. begin
  1344. GR32.InflateRect(R, 0, -BtnSz);
  1345. ClientSz := R.Bottom - R.Top;
  1346. end;
  1347. if ClientSz < 18 then
  1348. begin
  1349. Result := Rect(0, 0, 0, 0);
  1350. Exit;
  1351. end;
  1352. if Range > EffectiveWindow then
  1353. begin
  1354. HandleSz := Round(ClientSz * EffectiveWindow / Range);
  1355. if HandleSz >= MIN_SIZE then HandlePos := Round(ClientSz * Position / Range)
  1356. else
  1357. begin
  1358. HandleSz := MIN_SIZE;
  1359. HandlePos := Round((ClientSz - MIN_SIZE) * Position / (Range - EffectiveWindow));
  1360. end;
  1361. Result := R;
  1362. if Horz then
  1363. begin
  1364. Result.Left := R.Left + HandlePos;
  1365. Result.Right := R.Left + HandlePos + HandleSz;
  1366. end
  1367. else
  1368. begin
  1369. Result.Top := R.Top + HandlePos;
  1370. Result.Bottom := R.Top + HandlePos + HandleSz;
  1371. end;
  1372. end
  1373. else Result := R;
  1374. end;
  1375. function TCustomRangeBar.IsPositionStored: Boolean;
  1376. begin
  1377. Result := FPosition > 0;
  1378. end;
  1379. procedure TCustomRangeBar.MouseDown(Button: TMouseButton;
  1380. Shift: TShiftState; X, Y: Integer);
  1381. begin
  1382. if Range <= EffectiveWindow then FDragZone := zNone
  1383. else
  1384. begin
  1385. inherited;
  1386. if FDragZone = zHandle then
  1387. begin
  1388. StopDragTracking;
  1389. FPosBeforeDrag := Position;
  1390. end;
  1391. end;
  1392. end;
  1393. procedure TCustomRangeBar.MouseMove(Shift: TShiftState; X, Y: Integer);
  1394. var
  1395. Delta: Single;
  1396. WinSz: Single;
  1397. ClientSz, HandleSz: Integer;
  1398. begin
  1399. inherited;
  1400. if (FDragZone = zHandle) and (MouseCapture) then
  1401. begin
  1402. WinSz := EffectiveWindow;
  1403. if Range <= WinSz then Exit;
  1404. if Kind = sbHorizontal then Delta := X - FStored.X else Delta := Y - FStored.Y;
  1405. if Kind = sbHorizontal then ClientSz := ClientWidth else ClientSz := ClientHeight;
  1406. Dec(ClientSz, GetButtonSize * 2);
  1407. if BorderStyle = bsSingle then Dec(ClientSz, 2);
  1408. HandleSz := Round(ClientSz * WinSz / Range);
  1409. if HandleSz < MIN_SIZE then Delta := Round(Delta * (Range - WinSz) / (ClientSz - MIN_SIZE))
  1410. else Delta := Delta * Range / ClientSz;
  1411. try
  1412. FGenChange := True;
  1413. try
  1414. Position := FPosBeforeDrag + Delta;
  1415. finally
  1416. FGenChange := False;
  1417. end;
  1418. except
  1419. // Propagation of exception will cause loss of mouse capture, so we need
  1420. // to emulate mouse release in order to restore internal state.
  1421. if (MouseCapture) then
  1422. begin
  1423. MouseCapture := False;
  1424. MouseUp(mbLeft, Shift, X, Y);
  1425. end;
  1426. raise;
  1427. end;
  1428. end;
  1429. end;
  1430. procedure TCustomRangeBar.Resize;
  1431. var
  1432. OldWindow: Integer;
  1433. Center: Single;
  1434. NewPosition: Single;
  1435. begin
  1436. NewPosition := FPosition;
  1437. if Centered then
  1438. begin
  1439. OldWindow := EffectiveWindow;
  1440. UpdateEffectiveWindow;
  1441. if (Range > EffectiveWindow) then
  1442. begin
  1443. if (Range > OldWindow) and (Range <> 0) then
  1444. Center := (FPosition + OldWindow * 0.5) / Range
  1445. else
  1446. Center := 0.5;
  1447. NewPosition := Center * Range - EffectiveWindow * 0.5;
  1448. end;
  1449. end;
  1450. Position := NewPosition;
  1451. inherited;
  1452. end;
  1453. procedure TCustomRangeBar.SetParams(NewRange, NewWindow: Integer);
  1454. var
  1455. OldWindow, OldRange: Integer;
  1456. Center: Single;
  1457. NewPosition: Single;
  1458. begin
  1459. if (NewRange < 0) then
  1460. NewRange := 0;
  1461. if (NewWindow < 0) then
  1462. NewWindow := 0;
  1463. if (NewRange = FRange) and (NewWindow = EffectiveWindow) then
  1464. exit;
  1465. OldWindow := EffectiveWindow;
  1466. OldRange := Range;
  1467. FRange := NewRange;
  1468. FWindow := NewWindow;
  1469. UpdateEffectiveWindow;
  1470. NewPosition := FPosition;
  1471. if Centered and (Range > EffectiveWindow) then
  1472. begin
  1473. if (OldRange > OldWindow) and (OldRange <> 0) then
  1474. Center := (FPosition + OldWindow * 0.5) / OldRange
  1475. else
  1476. Center := 0.5;
  1477. NewPosition := Center * Range - EffectiveWindow * 0.5;
  1478. end;
  1479. Position := NewPosition;
  1480. Invalidate;
  1481. end;
  1482. procedure TCustomRangeBar.SetPosition(Value: Single);
  1483. var
  1484. NewPosition: Single;
  1485. Handled: boolean;
  1486. begin
  1487. if (Value = FPosition) then
  1488. exit;
  1489. NewPosition := Value;
  1490. AdjustPosition(NewPosition);
  1491. if (NewPosition = FPosition) then
  1492. exit;
  1493. Handled := False;
  1494. DoChanging(NewPosition, Handled);
  1495. if (Handled) then
  1496. exit;
  1497. FPosition := NewPosition;
  1498. Invalidate;
  1499. DoChange;
  1500. end;
  1501. procedure TCustomRangeBar.SetRange(Value: Integer);
  1502. begin
  1503. SetParams(Value, Window);
  1504. end;
  1505. procedure TCustomRangeBar.SetWindow(Value: Integer);
  1506. begin
  1507. SetParams(Range, Value);
  1508. end;
  1509. procedure TCustomRangeBar.TimerHandler(Sender: TObject);
  1510. var
  1511. OldPosition: Single;
  1512. Pt: TPoint;
  1513. function MousePos: TPoint;
  1514. begin
  1515. Result := ScreenToClient(Mouse.CursorPos);
  1516. if Result.X < 0 then Result.X := 0;
  1517. if Result.Y < 0 then Result.Y := 0;
  1518. if Result.X >= ClientWidth then Result.X := ClientWidth - 1;
  1519. if Result.Y >= ClientHeight then Result.Y := ClientHeight - 1
  1520. end;
  1521. begin
  1522. inherited;
  1523. if (not MouseCapture) then
  1524. Exit;
  1525. FGenChange := True;
  1526. try
  1527. OldPosition := Position;
  1528. case FDragZone of
  1529. zBtnPrev:
  1530. begin
  1531. Position := Position - Increment;
  1532. if Position = OldPosition then StopDragTracking;
  1533. end;
  1534. zBtnNext:
  1535. begin
  1536. Position := Position + Increment;
  1537. if Position = OldPosition then StopDragTracking;
  1538. end;
  1539. zTrackNext:
  1540. begin
  1541. Pt := MousePos;
  1542. if GetZone(Pt.X, Pt.Y) in [zTrackNext, zBtnNext] then
  1543. Position := Position + EffectiveWindow;
  1544. end;
  1545. zTrackPrev:
  1546. begin
  1547. Pt := MousePos;
  1548. if GetZone(Pt.X, Pt.Y) in [zTrackPrev, zBtnPrev] then
  1549. Position := Position - EffectiveWindow;
  1550. end;
  1551. end;
  1552. finally
  1553. FGenChange := False;
  1554. end;
  1555. end;
  1556. procedure TCustomRangeBar.UpdateEffectiveWindow;
  1557. begin
  1558. if (FWindow > 0) then
  1559. FEffectiveWindow := FWindow
  1560. else
  1561. begin
  1562. if (Kind = sbHorizontal) then
  1563. FEffectiveWindow := Width
  1564. else
  1565. FEffectiveWindow := Height;
  1566. end;
  1567. end;
  1568. //----------------------------------------------------------------------------//
  1569. { TCustomGaugeBar }
  1570. procedure TCustomGaugeBar.AdjustPosition;
  1571. begin
  1572. AdjustPosition(FPosition);
  1573. end;
  1574. procedure TCustomGaugeBar.AdjustPosition(var APosition: integer);
  1575. begin
  1576. if (APosition < Min) then
  1577. APosition := Min
  1578. else
  1579. if (APosition > Max) then
  1580. APosition := Max;
  1581. end;
  1582. constructor TCustomGaugeBar.Create(AOwner: TComponent);
  1583. begin
  1584. inherited;
  1585. FLargeChange := 1;
  1586. FMax := 100;
  1587. FSmallChange := 1;
  1588. end;
  1589. procedure TCustomGaugeBar.DoChanging(ANewPosition: integer; var Handled: boolean);
  1590. begin
  1591. if (LockUpdate > 0) then
  1592. Exit;
  1593. BeginLockUpdate;
  1594. try
  1595. if FGenChange and Assigned(FOnUserChanging) then
  1596. FOnUserChanging(Self, ANewPosition, Handled);
  1597. finally
  1598. EndLockUpdate;
  1599. end;
  1600. end;
  1601. function TCustomGaugeBar.DoMouseWheel(Shift: TShiftState;
  1602. WheelDelta: Integer; MousePos: TPoint): Boolean;
  1603. begin
  1604. Result := inherited DoMouseWheel(Shift, WheelDelta, MousePos);
  1605. if not Result then Position := Position + FSmallChange * WheelDelta div 120;
  1606. Result := True;
  1607. end;
  1608. function TCustomGaugeBar.GetHandleRect: TRect;
  1609. var
  1610. Sz, HandleSz: Integer;
  1611. Horz: Boolean;
  1612. Pos: Integer;
  1613. begin
  1614. Result := GetTrackBoundary;
  1615. Horz := Kind = sbHorizontal;
  1616. HandleSz := GetHandleSize;
  1617. if Horz then Sz := Result.Right - Result.Left
  1618. else Sz := Result.Bottom - Result.Top;
  1619. Pos := Round((Position - Min) / (Max - Min) * (Sz - GetHandleSize));
  1620. if Horz then
  1621. begin
  1622. Inc(Result.Left, Pos);
  1623. Result.Right := Result.Left + HandleSz;
  1624. end
  1625. else
  1626. begin
  1627. Inc(Result.Top, Pos);
  1628. Result.Bottom := Result.Top + HandleSz;
  1629. end;
  1630. end;
  1631. function TCustomGaugeBar.GetHandleSize: Integer;
  1632. var
  1633. R: TRect;
  1634. Sz: Integer;
  1635. begin
  1636. Result := HandleSize;
  1637. if Result = 0 then
  1638. begin
  1639. if Kind = sbHorizontal then Result := ClientHeight else Result := ClientWidth;
  1640. end;
  1641. R := GetTrackBoundary;
  1642. if Kind = sbHorizontal then Sz := R.Right - R.Left
  1643. else Sz := R.Bottom - R.Top;
  1644. if Sz - Result < 1 then Result := Sz - 1;
  1645. if Result < 0 then Result := 0;
  1646. end;
  1647. procedure TCustomGaugeBar.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  1648. begin
  1649. inherited;
  1650. if FDragZone = zHandle then
  1651. begin
  1652. StopDragTracking;
  1653. FPosBeforeDrag := Position;
  1654. end;
  1655. end;
  1656. procedure TCustomGaugeBar.MouseMove(Shift: TShiftState; X, Y: Integer);
  1657. var
  1658. Delta: Single;
  1659. R: TRect;
  1660. ClientSz: Integer;
  1661. begin
  1662. inherited;
  1663. if (FDragZone = zHandle) and (MouseCapture) then
  1664. begin
  1665. if Kind = sbHorizontal then Delta := X - FStored.X else Delta := Y - FStored.Y;
  1666. R := GetTrackBoundary;
  1667. if Kind = sbHorizontal then ClientSz := R.Right - R.Left
  1668. else ClientSz := R.Bottom - R.Top;
  1669. Delta := Delta * (Max - Min) / (ClientSz - GetHandleSize);
  1670. try
  1671. FGenChange := True;
  1672. try
  1673. Position := Round(FPosBeforeDrag + Delta);
  1674. finally
  1675. FGenChange := False;
  1676. end;
  1677. except
  1678. // Propagation of exception will cause loss of mouse capture, so we need
  1679. // to emulate mouse release in order to restore internal state.
  1680. if (MouseCapture) then
  1681. begin
  1682. MouseCapture := False;
  1683. MouseUp(mbLeft, Shift, X, Y);
  1684. end;
  1685. raise;
  1686. end;
  1687. end;
  1688. end;
  1689. procedure TCustomGaugeBar.SetHandleSize(Value: Integer);
  1690. begin
  1691. if Value < 0 then Value := 0;
  1692. if Value <> FHandleSize then
  1693. begin
  1694. FHandleSize := Value;
  1695. Invalidate;
  1696. end;
  1697. end;
  1698. procedure TCustomGaugeBar.SetLargeChange(Value: Integer);
  1699. begin
  1700. if Value < 1 then Value := 1;
  1701. FLargeChange := Value;
  1702. end;
  1703. procedure TCustomGaugeBar.SetMax(Value: Integer);
  1704. begin
  1705. if (Value <= FMin) and not (csLoading in ComponentState) then
  1706. Value := FMin + 1;
  1707. if Value <> FMax then
  1708. begin
  1709. FMax := Value;
  1710. Position := FPosition;
  1711. Invalidate;
  1712. end;
  1713. end;
  1714. procedure TCustomGaugeBar.SetMin(Value: Integer);
  1715. begin
  1716. if (Value >= FMax) and not (csLoading in ComponentState) then
  1717. Value := FMax - 1;
  1718. if Value <> FMin then
  1719. begin
  1720. FMin := Value;
  1721. Position := FPosition;
  1722. Invalidate;
  1723. end;
  1724. end;
  1725. procedure TCustomGaugeBar.SetPosition(Value: Integer);
  1726. var
  1727. Handled: boolean;
  1728. begin
  1729. AdjustPosition(Value);
  1730. if (Value = FPosition) then
  1731. exit;
  1732. Handled := False;
  1733. DoChanging(Value, Handled);
  1734. if (Handled) then
  1735. exit;
  1736. FPosition := Value;
  1737. Invalidate;
  1738. DoChange;
  1739. end;
  1740. procedure TCustomGaugeBar.SetSmallChange(Value: Integer);
  1741. begin
  1742. if Value < 1 then Value := 1;
  1743. FSmallChange := Value;
  1744. end;
  1745. procedure TCustomGaugeBar.TimerHandler(Sender: TObject);
  1746. var
  1747. OldPosition: Single;
  1748. Pt: TPoint;
  1749. function MousePos: TPoint;
  1750. begin
  1751. Result := ScreenToClient(Mouse.CursorPos);
  1752. if Result.X < 0 then Result.X := 0;
  1753. if Result.Y < 0 then Result.Y := 0;
  1754. if Result.X >= ClientWidth then Result.X := ClientWidth - 1;
  1755. if Result.Y >= ClientHeight then Result.Y := ClientHeight - 1
  1756. end;
  1757. begin
  1758. inherited;
  1759. if (not MouseCapture) then
  1760. Exit;
  1761. FGenChange := True;
  1762. try
  1763. OldPosition := Position;
  1764. case FDragZone of
  1765. zBtnPrev:
  1766. begin
  1767. Position := Position - SmallChange;
  1768. if Position = OldPosition then StopDragTracking;
  1769. end;
  1770. zBtnNext:
  1771. begin
  1772. Position := Position + SmallChange;
  1773. if Position = OldPosition then StopDragTracking;
  1774. end;
  1775. zTrackNext:
  1776. begin
  1777. Pt := MousePos;
  1778. if GetZone(Pt.X, Pt.Y) in [zTrackNext, zBtnNext] then
  1779. Position := Position + LargeChange;
  1780. end;
  1781. zTrackPrev:
  1782. begin
  1783. Pt := MousePos;
  1784. if GetZone(Pt.X, Pt.Y) in [zTrackPrev, zBtnPrev] then
  1785. Position := Position - LargeChange;
  1786. end;
  1787. end;
  1788. finally
  1789. FGenChange := False;
  1790. end;
  1791. end;
  1792. { TArrowBarAccess }
  1793. function TArrowBarAccess.GetBackgnd: TRBBackgnd;
  1794. begin
  1795. Result := FMaster.Backgnd;
  1796. end;
  1797. function TArrowBarAccess.GetButtonSize: Integer;
  1798. begin
  1799. Result := FMaster.ButtonSize;
  1800. end;
  1801. function TArrowBarAccess.GetColor: TColor;
  1802. begin
  1803. Result := FMaster.Color;
  1804. end;
  1805. function TArrowBarAccess.GetHandleColor: TColor;
  1806. begin
  1807. Result := FMaster.HandleColor;
  1808. end;
  1809. function TArrowBarAccess.GetHighLightColor: TColor;
  1810. begin
  1811. Result := FMaster.HighLightColor;
  1812. end;
  1813. function TArrowBarAccess.GetShadowColor: TColor;
  1814. begin
  1815. Result := FMaster.ShadowColor;
  1816. end;
  1817. function TArrowBarAccess.GetButtonColor: TColor;
  1818. begin
  1819. Result := FMaster.ButtonColor;
  1820. end;
  1821. function TArrowBarAccess.GetBorderColor: TColor;
  1822. begin
  1823. Result := FMaster.BorderColor;
  1824. end;
  1825. function TArrowBarAccess.GetShowArrows: Boolean;
  1826. begin
  1827. Result := FMaster.ShowArrows;
  1828. end;
  1829. function TArrowBarAccess.GetShowHandleGrip: Boolean;
  1830. begin
  1831. Result := FMaster.ShowHandleGrip;
  1832. end;
  1833. function TArrowBarAccess.GetStyle: TRBStyle;
  1834. begin
  1835. Result := FMaster.Style;
  1836. end;
  1837. procedure TArrowBarAccess.SetBackgnd(Value: TRBBackgnd);
  1838. begin
  1839. FMaster.Backgnd := Value;
  1840. if FSlave <> nil then FSlave.Backgnd := Value;
  1841. end;
  1842. procedure TArrowBarAccess.SetButtonSize(Value: Integer);
  1843. begin
  1844. FMaster.ButtonSize := Value;
  1845. if FSlave <> nil then FSlave.ButtonSize := Value;
  1846. end;
  1847. procedure TArrowBarAccess.SetColor(Value: TColor);
  1848. begin
  1849. FMaster.Color := Value;
  1850. if FSlave <> nil then FSlave.Color := Value;
  1851. end;
  1852. procedure TArrowBarAccess.SetHandleColor(Value: TColor);
  1853. begin
  1854. FMaster.HandleColor := Value;
  1855. if FSlave <> nil then FSlave.HandleColor := Value;
  1856. end;
  1857. procedure TArrowBarAccess.SetHighLightColor(Value: TColor);
  1858. begin
  1859. FMaster.HighLightColor := Value;
  1860. if FSlave <> nil then FSlave.HighLightColor := Value;
  1861. end;
  1862. procedure TArrowBarAccess.SetShadowColor(Value: TColor);
  1863. begin
  1864. FMaster.ShadowColor := Value;
  1865. if FSlave <> nil then FSlave.ShadowColor := Value;
  1866. end;
  1867. procedure TArrowBarAccess.SetButtonColor(Value: TColor);
  1868. begin
  1869. FMaster.ButtonColor := Value;
  1870. if FSlave <> nil then FSlave.ButtonColor := Value;
  1871. end;
  1872. procedure TArrowBarAccess.SetBorderColor(Value: TColor);
  1873. begin
  1874. FMaster.BorderColor := Value;
  1875. if FSlave <> nil then FSlave.BorderColor := Value;
  1876. end;
  1877. procedure TArrowBarAccess.SetShowArrows(Value: Boolean);
  1878. begin
  1879. FMaster.ShowArrows := Value;
  1880. if FSlave <> nil then FSlave.ShowArrows := Value;
  1881. end;
  1882. procedure TArrowBarAccess.SetShowHandleGrip(Value: Boolean);
  1883. begin
  1884. FMaster.ShowHandleGrip := Value;
  1885. if FSlave <> nil then FSlave.ShowHandleGrip := Value;
  1886. end;
  1887. procedure TArrowBarAccess.SetStyle(Value: TRBStyle);
  1888. begin
  1889. FMaster.Style := Value;
  1890. if FSlave <> nil then FSlave.Style := Value;
  1891. end;
  1892. end.