GLS.Windows.pas 94 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636
  1. //
  2. // The graphics engine GLScene
  3. //
  4. unit GLS.Windows;
  5. (* OpenGL windows management classes and structures *)
  6. interface
  7. {$I Stage.Defines.inc}
  8. uses
  9. Winapi.OpenGL,
  10. Winapi.Windows,
  11. System.Classes,
  12. System.SysUtils,
  13. System.Math,
  14. Vcl.StdCtrls,
  15. Vcl.Controls,
  16. Vcl.Graphics,
  17. Stage.OpenGLTokens,
  18. GLS.PersistentClasses,
  19. Stage.Strings,
  20. GLS.Coordinates,
  21. Stage.VectorTypes,
  22. GLS.Objects,
  23. GLS.State,
  24. Stage.Utils,
  25. GLS.Scene,
  26. GLS.HudObjects,
  27. GLS.Material,
  28. GLS.Context,
  29. GLS.BitmapFont,
  30. GLS.WindowsFont,
  31. Stage.VectorGeometry,
  32. GLS.Gui,
  33. GLS.Color,
  34. GLS.ImageUtils,
  35. GLS.Texture,
  36. GLS.RenderContextInfo,
  37. GLS.BaseClasses;
  38. type
  39. TGLBaseComponent = class(TGLBaseGuiObject)
  40. private
  41. FGUIRedraw: Boolean;
  42. FGuiLayout: TGLGuiLayout;
  43. FGuiLayoutName: TGLGuiComponentName;
  44. FGuiComponent: TGLGuiComponent;
  45. FReBuildGui: Boolean;
  46. FRedrawAtOnce: Boolean;
  47. MoveX, MoveY: TGLFloat;
  48. FRenderStatus: TGUIDrawResult;
  49. FAlphaChannel: Single;
  50. FRotation: TGLFloat;
  51. FNoZWrite: Boolean;
  52. BlockRendering: Boolean;
  53. RenderingCount: Integer;
  54. BlockedCount: Integer;
  55. GuiDestroying: Boolean;
  56. FDoChangesOnProgress: Boolean;
  57. FAutosize: Boolean;
  58. procedure SetGUIRedraw(value: Boolean);
  59. procedure SetDoChangesOnProgress(const Value: Boolean);
  60. procedure SetAutosize(const Value: Boolean);
  61. protected
  62. procedure RenderHeader(var rci: TGLRenderContextInfo; renderSelf, renderChildren: Boolean);
  63. procedure RenderFooter(var rci: TGLRenderContextInfo; renderSelf, renderChildren: Boolean);
  64. procedure SetGuiLayout(NewGui: TGLGuiLayout); virtual;
  65. procedure SetGuiLayoutName(const NewName: TGLGuiComponentName);
  66. procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  67. procedure SetRotation(const val: TGLFloat);
  68. procedure SetAlphaChannel(const val: Single);
  69. function StoreAlphaChannel: Boolean;
  70. procedure SetNoZWrite(const val: Boolean);
  71. public
  72. procedure BlockRender;
  73. procedure UnBlockRender;
  74. constructor Create(AOwner: TComponent); override;
  75. destructor Destroy; override;
  76. procedure NotifyChange(Sender: TObject); override;
  77. procedure DoChanges; virtual;
  78. procedure MoveGUI(XRel, YRel: Single);
  79. procedure PlaceGUI(XPos, YPos: Single);
  80. procedure DoProgress(const progressTime: TGLProgressTimes); override;
  81. procedure DoRender(var rci: TGLRenderContextInfo; renderSelf, renderChildren: Boolean); override;
  82. procedure InternalRender(var rci: TGLRenderContextInfo; renderSelf, renderChildren: Boolean); virtual;
  83. property GUIRedraw: Boolean read FGUIRedraw write SetGUIRedraw;
  84. property ReBuildGui: Boolean read FReBuildGui write FReBuildGui;
  85. published
  86. property Autosize: Boolean read FAutosize write SetAutosize;
  87. property RedrawAtOnce: Boolean read FRedrawAtOnce write FRedrawAtOnce;
  88. property GuiLayout: TGLGuiLayout read FGuiLayout write SetGuiLayout;
  89. property GuiLayoutName: TGLGuiComponentName read FGuiLayoutName write SetGuiLayoutName;
  90. // This the ON-SCREEN rotation of the GuiComponent. Rotatation=0 is handled faster.
  91. property Rotation: TGLFloat read FRotation write SetRotation;
  92. // If different from 1, this value will replace that of Diffuse.Alpha
  93. property AlphaChannel: Single read FAlphaChannel write SetAlphaChannel stored StoreAlphaChannel;
  94. // If True, GuiComponent will not write to Z-Buffer. GuiComponent will be maskable by ZBuffer test STILL.
  95. property NoZWrite: Boolean read FNoZWrite write SetNoZWrite;
  96. property DoChangesOnProgress: Boolean read FDoChangesOnProgress write SetDoChangesOnProgress;
  97. property Visible;
  98. property Width;
  99. property Height;
  100. property Left;
  101. property Top;
  102. property Position;
  103. end;
  104. TGLFocusControl = class;
  105. TGLBaseControl = class;
  106. TGLMouseAction = (ma_mouseup, ma_mousedown, ma_mousemove);
  107. TGLAcceptMouseQuery = procedure(Sender: TGLBaseControl; Shift: TShiftState;
  108. Action: TGLMouseAction; Button: TMouseButton; X, Y: Integer; var Accept: boolean) of object;
  109. TGLBaseControl = class(TGLBaseComponent)
  110. private
  111. FOnMouseDown: TMouseEvent;
  112. FOnMouseMove: TMouseMoveEvent;
  113. FOnMouseUp: TMouseEvent;
  114. FKeepMouseEvents: Boolean;
  115. FActiveControl: TGLBaseControl;
  116. FFocusedControl: TGLFocusControl;
  117. FOnAcceptMouseQuery: TGLAcceptMouseQuery;
  118. FOnMouseLeave: TNotifyEvent;
  119. FOnMouseEnter: TNotifyEvent;
  120. FEnteredControl: TGLBaseControl;
  121. protected
  122. procedure InternalMouseDown(Shift: TShiftState; Button: TMouseButton; X, Y: Integer); virtual;
  123. procedure InternalMouseUp(Shift: TShiftState; Button: TMouseButton; X, Y: Integer); virtual;
  124. procedure InternalMouseMove(Shift: TShiftState; X, Y: Integer); virtual;
  125. procedure SetActiveControl(NewControl: TGLBaseControl);
  126. procedure SetFocusedControl(NewControl: TGLFocusControl);
  127. function FindFirstGui: TGLBaseControl;
  128. procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  129. procedure DoMouseEnter;
  130. procedure DoMouseLeave;
  131. public
  132. function MouseDown(Sender: TObject; Button: TMouseButton; Shift:
  133. TShiftState; X, Y: Integer): Boolean; virtual;
  134. function MouseUp(Sender: TObject; Button: TMouseButton; Shift:
  135. TShiftState; X, Y: Integer): Boolean; virtual;
  136. function MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer): Boolean; virtual;
  137. procedure KeyPress(Sender: TObject; var Key: Char); virtual;
  138. procedure KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); virtual;
  139. procedure KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); virtual;
  140. property ActiveControl: TGLBaseControl read FActiveControl write SetActiveControl;
  141. property KeepMouseEvents: Boolean read FKeepMouseEvents write FKeepMouseEvents default false;
  142. published
  143. property FocusedControl: TGLFocusControl read FFocusedControl write SetFocusedControl;
  144. property OnMouseDown: TMouseEvent read FOnMouseDown write FOnMouseDown;
  145. property OnMouseMove: TMouseMoveEvent read FOnMouseMove write FOnMouseMove;
  146. property OnMouseUp: TMouseEvent read FOnMouseUp write FOnMouseUp;
  147. property OnMouseEnter: TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
  148. property OnMouseLeave: TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
  149. property OnAcceptMouseQuery: TGLAcceptMouseQuery read FOnAcceptMouseQuery write FOnAcceptMouseQuery;
  150. end;
  151. TGLBaseFontControl = class(TGLBaseControl)
  152. private
  153. FBitmapFont: TGLCustomBitmapFont;
  154. FDefaultColor: TGLColorVector;
  155. protected
  156. function GetDefaultColor: TColor;
  157. procedure SetDefaultColor(value: TColor);
  158. procedure SetBitmapFont(NewFont: TGLCustomBitmapFont);
  159. function GetBitmapFont: TGLCustomBitmapFont;
  160. procedure WriteTextAt(var rci: TGLRenderContextInfo; const X, Y: TGLFloat;
  161. const Data: UnicodeString; const Color: TGLColorVector); overload;
  162. procedure WriteTextAt(var rci: TGLRenderContextInfo; const X1, Y1, X2, Y2:
  163. TGLFloat; const Data: UnicodeString; const Color: TGLColorVector); overload;
  164. function GetFontHeight: Integer;
  165. public
  166. constructor Create(AOwner: TComponent); override;
  167. destructor Destroy; override;
  168. procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  169. published
  170. property BitmapFont: TGLCustomBitmapFont read GetBitmapFont write SetBitmapFont;
  171. property DefaultColor: TColor read GetDefaultColor write SetDefaultColor;
  172. end;
  173. TGLBaseTextControl = class(TGLBaseFontControl)
  174. private
  175. FCaption: UnicodeString;
  176. protected
  177. procedure SetCaption(const NewCaption: UnicodeString);
  178. public
  179. published
  180. property Caption: UnicodeString read FCaption write SetCaption;
  181. end;
  182. TGLFocusControl = class(TGLBaseTextControl)
  183. private
  184. FRootControl: TGLBaseControl;
  185. FFocused: Boolean;
  186. FOnKeyDown: TKeyEvent;
  187. FOnKeyUp: TKeyEvent;
  188. FOnKeyPress: TKeyPressEvent;
  189. FShiftState: TShiftState;
  190. FFocusedColor: TGLColorVector;
  191. protected
  192. procedure InternalKeyPress(var Key: Char); virtual;
  193. procedure InternalKeyDown(var Key: Word; Shift: TShiftState); virtual;
  194. procedure InternalKeyUp(var Key: Word; Shift: TShiftState); virtual;
  195. procedure SetFocused(Value: Boolean); virtual;
  196. function GetRootControl: TGLBaseControl;
  197. function GetFocusedColor: TColor;
  198. procedure SetFocusedColor(const Val: TColor);
  199. public
  200. destructor Destroy; override;
  201. procedure NotifyHide; override;
  202. procedure MoveTo(newParent: TGLBaseSceneObject); override;
  203. procedure ReGetRootControl;
  204. procedure SetFocus;
  205. procedure PrevControl;
  206. procedure NextControl;
  207. procedure KeyPress(Sender: TObject; var Key: Char); override;
  208. procedure KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); override;
  209. procedure KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); override;
  210. published
  211. property RootControl: TGLBaseControl read GetRootControl;
  212. property Focused: Boolean read FFocused write SetFocused;
  213. property FocusedColor: TColor read GetFocusedColor write SetFocusedColor;
  214. property OnKeyDown: TKeyEvent read FOnKeyDown write FOnKeyDown;
  215. property OnKeyUp: TKeyEvent read FOnKeyUp write FOnKeyUp;
  216. property OnKeyPress: TKeyPressEvent read FOnKeyPress write FOnKeyPress;
  217. end;
  218. TGLCustomControl = class;
  219. TGLCustomRenderEvent = procedure(Sender: TGLCustomControl; Bitmap: TBitmap) of object;
  220. TGLCustomControl = class(TGLFocusControl)
  221. private
  222. FCustomData: Pointer;
  223. FCustomObject: TObject;
  224. FOnRender: TGLCustomRenderEvent;
  225. FMaterial: TGLMaterial;
  226. FBitmap: TBitmap;
  227. FInternalBitmap: TBitmap;
  228. FBitmapChanged: Boolean;
  229. FXTexCoord: Single;
  230. FYTexCoord: Single;
  231. FInvalidRenderCount: Integer;
  232. FMaxInvalidRenderCount: Integer;
  233. FCentered: Boolean;
  234. procedure SetCentered(const Value: Boolean);
  235. protected
  236. procedure OnBitmapChanged(Sender: TObject);
  237. procedure SetBitmap(ABitmap: TBitmap);
  238. public
  239. constructor Create(AOwner: TComponent); override;
  240. destructor Destroy; override;
  241. procedure InternalRender(var rci: TGLRenderContextInfo; renderSelf,
  242. renderChildren: Boolean); override;
  243. procedure SetMaterial(AMaterial: TGLMaterial);
  244. property CustomData: Pointer read FCustomData write FCustomData;
  245. property CustomObject: TObject read FCustomObject write FCustomObject;
  246. published
  247. property OnRender: TGLCustomRenderEvent read FOnRender write FOnRender;
  248. property Centered: Boolean read FCentered write SetCentered;
  249. property Material: TGLMaterial read FMaterial write SetMaterial;
  250. property Bitmap: TBitmap read FBitmap write SetBitmap;
  251. property MaxInvalidRenderCount: Integer read FMaxInvalidRenderCount
  252. write FMaxInvalidRenderCount;
  253. end;
  254. TGLPopupMenu = class;
  255. TGLPopupMenuClick = procedure(Sender: TGLPopupMenu; index: Integer; const MenuItemText: string) of object;
  256. TGLPopupMenu = class(TGLFocusControl)
  257. private
  258. FOnClick: TGLPopupMenuClick;
  259. FMenuItems: TStrings;
  260. FSelIndex: Integer;
  261. FMarginSize: Single;
  262. NewHeight: Single;
  263. protected
  264. procedure SetFocused(Value: Boolean); override;
  265. procedure SetMenuItems(Value: TStrings);
  266. procedure SetMarginSize(const val: Single);
  267. procedure SetSelIndex(const val: Integer);
  268. procedure InternalMouseDown(Shift: TShiftState; Button: TMouseButton; X, Y: Integer); override;
  269. procedure InternalMouseMove(Shift: TShiftState; X, Y: Integer); override;
  270. procedure OnStringListChange(Sender: TObject);
  271. public
  272. constructor Create(AOwner: TComponent); override;
  273. destructor Destroy; override;
  274. procedure PopUp(Px, Py: Integer);
  275. procedure InternalRender(var rci: TGLRenderContextInfo; renderSelf,
  276. renderChildren: Boolean); override;
  277. procedure DoRender(var rci: TGLRenderContextInfo; renderSelf, renderChildren:
  278. Boolean); override;
  279. function MouseDown(Sender: TObject; Button: TMouseButton; Shift:
  280. TShiftState; X, Y: Integer): Boolean; override;
  281. published
  282. property MenuItems: TStrings read FMenuItems write SetMenuItems;
  283. property OnClick: TGLPopupMenuClick read FOnClick write FOnClick;
  284. property MarginSize: Single read FMarginSize write SetMarginSize;
  285. property SelIndex: Integer read FSelIndex write SetSelIndex;
  286. end;
  287. TGLForm = class;
  288. TGLFormCanRequest = procedure(Sender: TGLForm; var Can: Boolean) of object;
  289. TGLFormCloseOptions = (co_Hide, co_Ignore, co_Destroy);
  290. TGLFormCanClose = procedure(Sender: TGLForm; var CanClose: TGLFormCloseOptions) of object;
  291. TGLFormNotify = procedure(Sender: TGLForm) of object;
  292. TGLFormMove = procedure(Sender: TGLForm; var Left, Top: Single) of object;
  293. TGLForm = class(TGLBaseTextControl)
  294. private
  295. FOnCanMove: TGLFormCanRequest;
  296. FOnCanResize: TGLFormCanRequest;
  297. FOnCanClose: TGLFormCanClose;
  298. FOnShow: TGLFormNotify;
  299. FOnHide: TGLFormNotify;
  300. FOnMoving: TGLFormMove;
  301. Moving: Boolean;
  302. OldX: Integer;
  303. OldY: Integer;
  304. FTitleColor: TGLColorVector;
  305. FTitleOffset: Single;
  306. protected
  307. procedure InternalMouseDown(Shift: TShiftState; Button: TMouseButton; X, Y: Integer); override;
  308. procedure InternalMouseUp(Shift: TShiftState; Button: TMouseButton; X, Y: Integer); override;
  309. procedure InternalMouseMove(Shift: TShiftState; X, Y: Integer); override;
  310. function GetTitleColor: TColor;
  311. procedure SetTitleColor(value: TColor);
  312. public
  313. constructor Create(AOwner: TComponent); override;
  314. procedure Close;
  315. procedure NotifyShow; override;
  316. procedure NotifyHide; override;
  317. function MouseUp(Sender: TObject; Button: TMouseButton; Shift:
  318. TShiftState; X, Y: Integer): Boolean; override;
  319. function MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer): Boolean; override;
  320. procedure InternalRender(var rci: TGLRenderContextInfo; renderSelf, renderChildren: Boolean); override;
  321. published
  322. property TitleColor: TColor read GetTitleColor write SetTitleColor;
  323. property OnCanMove: TGLFormCanRequest read FOnCanMove write FOnCanMove;
  324. property OnCanResize: TGLFormCanRequest read FOnCanResize write FOnCanResize;
  325. property OnCanClose: TGLFormCanClose read FOnCanClose write FOnCanClose;
  326. property OnShow: TGLFormNotify read FOnShow write FOnShow;
  327. property OnHide: TGLFormNotify read FOnHide write FOnHide;
  328. property OnMoving: TGLFormMove read FOnMoving write FOnMoving;
  329. property TitleOffset: Single read FTitleOffset write FTitleOffset;
  330. end;
  331. TGLPanel = class(TGLBaseControl)
  332. end;
  333. TGLCheckBox = class(TGLBaseControl)
  334. private
  335. FChecked: Boolean;
  336. FOnChange: TNotifyEvent;
  337. FGuiLayoutNameChecked: TGLGuiComponentName;
  338. FGuiCheckedComponent: TGLGuiComponent;
  339. FGroup: Integer;
  340. protected
  341. procedure SetChecked(NewChecked: Boolean);
  342. procedure InternalMouseDown(Shift: TShiftState; Button: TMouseButton; X, Y: Integer); override;
  343. procedure InternalMouseUp(Shift: TShiftState; Button: TMouseButton; X, Y: Integer); override;
  344. procedure SetGuiLayoutNameChecked(const newName: TGLGuiComponentName);
  345. procedure SetGuiLayout(NewGui: TGLGuiLayout); override;
  346. procedure SetGroup(const val: Integer);
  347. public
  348. constructor Create(AOwner: TComponent); override;
  349. procedure InternalRender(var rci: TGLRenderContextInfo; renderSelf,
  350. renderChildren: Boolean); override;
  351. procedure NotifyChange(Sender: TObject); override;
  352. published
  353. property Group: Integer read FGroup write SetGroup;
  354. property Checked: Boolean read FChecked write SetChecked;
  355. property OnChange: TNotifyEvent read FOnChange write FOnChange;
  356. property GuiLayoutNameChecked: TGLGuiComponentName read FGuiLayoutNameChecked
  357. write SetGuiLayoutNameChecked;
  358. end;
  359. TGLButton = class(TGLFocusControl)
  360. private
  361. FPressed : Boolean;
  362. FOnButtonClick : TNotifyEvent;
  363. FGuiLayoutNamePressed : TGLGuiComponentName;
  364. FGuiPressedComponent : TGLGuiComponent;
  365. FBitBtn : TGLMaterial;
  366. FGroup : Integer;
  367. FLogicWidth : Single;
  368. FLogicHeight : Single;
  369. FXOffSet : Single;
  370. FYOffSet : Single;
  371. FAllowUp : Boolean;
  372. protected
  373. procedure SetPressed(NewPressed: Boolean);
  374. procedure InternalMouseDown(Shift: TShiftState; Button: TMouseButton; X, Y: Integer); override;
  375. procedure InternalMouseUp(Shift: TShiftState; Button: TMouseButton; X, Y: Integer); override;
  376. procedure InternalKeyDown(var Key: Word; Shift: TShiftState); override;
  377. procedure InternalKeyUp(var Key: Word; Shift: TShiftState); override;
  378. procedure SetFocused(Value: Boolean); override;
  379. procedure SetGuiLayoutNamePressed(const newName: TGLGuiComponentName);
  380. procedure SetGuiLayout(NewGui: TGLGuiLayout); override;
  381. procedure SetBitBtn(AValue: TGLMaterial);
  382. procedure DestroyHandle; override;
  383. procedure SetGroup(const val: Integer);
  384. procedure SetLogicWidth(const val: single);
  385. procedure SetLogicHeight(const val: single);
  386. procedure SetXOffset(const val: single);
  387. procedure SetYOffset(const val: single);
  388. public
  389. constructor Create(AOwner: TComponent); override;
  390. destructor Destroy; override;
  391. procedure InternalRender(var rci: TGLRenderContextInfo; renderSelf, renderChildren: Boolean); override;
  392. published
  393. property Group: Integer read FGroup write SetGroup;
  394. property BitBtn: TGLMaterial read FBitBtn write SetBitBtn;
  395. property Pressed: Boolean read FPressed write SetPressed;
  396. property OnButtonClick: TNotifyEvent read FOnButtonClick write FOnButtonClick;
  397. property GuiLayoutNamePressed: TGLGuiComponentName read FGuiLayoutNamePressed write SetGuiLayoutNamePressed;
  398. property LogicWidth: Single read FLogicWidth write SetLogicWidth;
  399. property LogicHeight: Single read FLogicHeight write SetLogicHeight;
  400. property XOffset: Single read FXOffset write SetXOffset;
  401. property YOffset: Single read FYOffset write SetYOffset;
  402. property AllowUp: Boolean read FAllowUp write FAllowUp;
  403. end;
  404. TGLEdit = class(TGLFocusControl)
  405. private
  406. FOnChange: TNotifyEvent;
  407. FSelStart: Integer;
  408. FReadOnly: Boolean;
  409. FEditChar: string;
  410. protected
  411. procedure InternalMouseDown(Shift: TShiftState; Button: TMouseButton; X, Y: Integer); override;
  412. procedure InternalKeyPress(var Key: Char); override;
  413. procedure InternalKeyDown(var Key: Word; Shift: TShiftState); override;
  414. procedure InternalKeyUp(var Key: Word; Shift: TShiftState); override;
  415. procedure SetFocused(Value: Boolean); override;
  416. procedure SetSelStart(const Value: Integer);
  417. procedure SetEditChar(const Value: string);
  418. public
  419. constructor Create(AOwner: TComponent); override;
  420. procedure InternalRender(var rci: TGLRenderContextInfo; renderSelf,
  421. renderChildren: Boolean); override;
  422. published
  423. property EditChar: string read FEditChar write SetEditChar;
  424. property ReadOnly: Boolean read FReadOnly write FReadOnly default False;
  425. property OnChange: TNotifyEvent read FOnChange write FOnChange;
  426. property SelStart: Integer read FSelStart write SetSelStart;
  427. end;
  428. TGLLabel = class(TGLBaseTextControl)
  429. private
  430. FAlignment: TAlignment;
  431. FTextLayout: TTextLayout;
  432. procedure SetAlignment(const Value: TAlignment);
  433. procedure SetTextLayout(const Value: TTextLayout);
  434. protected
  435. public
  436. constructor Create(AOwner: TComponent); override;
  437. procedure InternalRender(var rci: TGLRenderContextInfo; renderSelf, renderChildren: Boolean); override;
  438. published
  439. property Alignment: TAlignment read FAlignment write SetAlignment;
  440. property TextLayout: TTextLayout read FTextLayout write SetTextLayout;
  441. end;
  442. TGLAdvancedLabel = class(TGLFocusControl)
  443. private
  444. protected
  445. public
  446. procedure InternalRender(var rci: TGLRenderContextInfo; renderSelf, renderChildren: Boolean); override;
  447. published
  448. end;
  449. TGLScrollbar = class(TGLFocusControl)
  450. private
  451. FMin: Single;
  452. FMax: Single;
  453. FStep: Single;
  454. FPos: Single;
  455. FPageSize: Single;
  456. FOnChange: TNotifyEvent;
  457. FGuiLayoutKnobName: TGLGuiComponentName;
  458. FGuiKnobComponent: TGLGuiComponent;
  459. FKnobRenderStatus: TGUIDrawResult;
  460. FScrollOffs: Single;
  461. FScrolling: Boolean;
  462. FHorizontal: Boolean;
  463. FLocked: Boolean;
  464. protected
  465. procedure SetMin(const val: Single);
  466. procedure SetMax(const val: Single);
  467. procedure SetPos(const val: Single);
  468. procedure SetPageSize(const val: Single);
  469. procedure SetHorizontal(const val: Boolean);
  470. procedure SetGuiLayoutKnobName(const newName: TGLGuiComponentName);
  471. procedure SetGuiLayout(NewGui: TGLGuiLayout); override;
  472. function GetScrollPosY(ScrollPos: Single): Single;
  473. function GetYScrollPos(Y: Single): Single;
  474. function GetScrollPosX(ScrollPos: Single): Single;
  475. function GetXScrollPos(X: Single): Single;
  476. procedure InternalMouseDown(Shift: TShiftState; Button: TMouseButton; X, Y: Integer); override;
  477. procedure InternalMouseUp(Shift: TShiftState; Button: TMouseButton; X, Y: Integer); override;
  478. procedure InternalMouseMove(Shift: TShiftState; X, Y: Integer); override;
  479. public
  480. constructor Create(AOwner: TComponent); override;
  481. procedure StepUp;
  482. procedure StepDown;
  483. procedure PageUp;
  484. procedure PageDown;
  485. function MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer): Boolean; override;
  486. function MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer): Boolean; override;
  487. procedure InternalRender(var rci: TGLRenderContextInfo; renderSelf, renderChildren: Boolean); override;
  488. published
  489. property Horizontal: Boolean read FHorizontal write SetHorizontal;
  490. property Pos: Single read FPos write SetPos;
  491. property Min: Single read FMin write SetMin;
  492. property Max: Single read FMax write SetMax;
  493. property Step: Single read FStep write FStep;
  494. property PageSize: Single read FPageSize write SetPageSize;
  495. property OnChange: TNotifyEvent read FOnChange write FOnChange;
  496. property GuiLayoutKnobName: TGLGuiComponentName read FGuiLayoutKnobName write SetGuiLayoutKnobName;
  497. property Locked: Boolean read FLocked write FLocked default False;
  498. end;
  499. TGLStringGrid = class(TGLFocusControl)
  500. private
  501. FSelCol, FSelRow: Integer;
  502. FRowSelect: Boolean;
  503. FColSelect: Boolean;
  504. FColumns: TStrings;
  505. FRows: TList;
  506. FHeaderColor: TGLColorVector;
  507. FMarginSize: Integer;
  508. FColumnSize: Integer;
  509. FRowHeight: Integer;
  510. FScrollbar: TGLScrollbar;
  511. FDrawHeader: Boolean;
  512. protected
  513. function GetCell(X, Y: Integer; out oCol, oRow: Integer): Boolean;
  514. procedure InternalMouseDown(Shift: TShiftState; Button: TMouseButton; X, Y: Integer); override;
  515. procedure SetColumns(const val: TStrings);
  516. procedure SetColSelect(const val: Boolean);
  517. function GetRow(index: Integer): TStringList;
  518. procedure SetRow(index: Integer; const val: TStringList);
  519. function GetRowCount: Integer;
  520. procedure SetRowCount(const val: Integer);
  521. procedure SetSelCol(const val: Integer);
  522. procedure SetSelRow(const val: Integer);
  523. procedure SetRowSelect(const val: Boolean);
  524. procedure SetDrawHeader(const val: Boolean);
  525. function GetHeaderColor: TColor;
  526. procedure SetHeaderColor(const val: TColor);
  527. procedure SetMarginSize(const val: Integer);
  528. procedure SetColumnSize(const val: Integer);
  529. procedure SetRowHeight(const val: Integer);
  530. procedure SetScrollbar(const val: TGLScrollbar);
  531. procedure SetGuiLayout(NewGui: TGLGuiLayout); override;
  532. public
  533. constructor Create(AOwner: TComponent); override;
  534. destructor Destroy; override;
  535. procedure Clear;
  536. function Add(const Data: array of string): Integer; overload;
  537. function Add(const Data: string): Integer; overload;
  538. procedure SetText(Data: string);
  539. procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  540. procedure NotifyChange(Sender: TObject); override;
  541. procedure InternalRender(var rci: TGLRenderContextInfo; renderSelf, renderChildren: Boolean); override;
  542. procedure OnStringListChange(Sender: TObject);
  543. property Row[index: Integer]: TStringList read GetRow write SetRow;
  544. published
  545. property HeaderColor: TColor read GetHeaderColor write SetHeaderColor;
  546. property Columns: TStrings read FColumns write SetColumns;
  547. property MarginSize: Integer read FMarginSize write SetMarginSize;
  548. property ColumnSize: Integer read FColumnSize write SetColumnSize;
  549. property RowHeight: Integer read FRowHeight write SetRowHeight;
  550. property RowCount: Integer read GetRowCount write SetRowCount;
  551. property SelCol: Integer read FSelCol write SetSelCol;
  552. property SelRow: Integer read FSelRow write SetSelRow;
  553. property RowSelect: Boolean read FRowSelect write SetRowSelect;
  554. property ColSelect: Boolean read FColSelect write SetColSelect;
  555. property DrawHeader: Boolean read FDrawHeader write SetDrawHeader;
  556. property Scrollbar: TGLScrollbar read FScrollbar write SetScrollbar;
  557. end;
  558. function UnpressGroup(CurrentObject: TGLBaseSceneObject; AGroupID: Integer): Boolean;
  559. //--------------------------------------------------------------------------
  560. implementation
  561. //--------------------------------------------------------------------------
  562. function UnpressGroup(CurrentObject: TGLBaseSceneObject; AGroupID: Integer): Boolean;
  563. var
  564. XC: Integer;
  565. begin
  566. Result := False;
  567. if CurrentObject is TGLButton then
  568. with CurrentObject as TGLButton do
  569. begin
  570. if Group = AGroupID then
  571. if Pressed then
  572. begin
  573. Pressed := False;
  574. Result := True;
  575. Exit;
  576. end;
  577. end;
  578. if CurrentObject is TGLCheckBox then
  579. with CurrentObject as TGLCheckBox do
  580. begin
  581. if Group = AGroupID then
  582. if Checked then
  583. begin
  584. Checked := False;
  585. Result := True;
  586. Exit;
  587. end;
  588. end;
  589. for XC := 0 to CurrentObject.Count - 1 do
  590. begin
  591. if UnpressGroup(CurrentObject.Children[XC], AGroupID) then
  592. begin
  593. Result := True;
  594. Exit;
  595. end;
  596. end;
  597. end;
  598. procedure TGLBaseComponent.SetGUIRedraw(value: Boolean);
  599. begin
  600. FGUIRedraw := Value;
  601. if Value then
  602. begin
  603. if csDestroying in ComponentState then
  604. Exit;
  605. if (FRedrawAtOnce) or (csDesigning in ComponentState) then
  606. begin
  607. FGUIRedraw := False;
  608. StructureChanged;
  609. end;
  610. end;
  611. end;
  612. procedure TGLBaseComponent.BlockRender;
  613. begin
  614. while BlockedCount <> 0 do
  615. Sleep(1);
  616. BlockRendering := True;
  617. while RenderingCount <> BlockedCount do
  618. Sleep(1);
  619. end;
  620. procedure TGLBaseComponent.UnBlockRender;
  621. begin
  622. BlockRendering := False;
  623. end;
  624. procedure TGLBaseComponent.RenderHeader(var rci: TGLRenderContextInfo; renderSelf,
  625. renderChildren: Boolean);
  626. var
  627. f: Single;
  628. begin
  629. FGuiLayout.Material.Apply(rci);
  630. if AlphaChannel <> 1 then
  631. rci.GLStates.SetGLMaterialAlphaChannel(GL_FRONT, AlphaChannel);
  632. // Prepare matrices
  633. gl.MatrixMode(GL_MODELVIEW);
  634. gl.PushMatrix;
  635. gl.LoadMatrixf(@TGLSceneBuffer(rci.buffer).BaseProjectionMatrix);
  636. if rci.renderDPI = 96 then
  637. f := 1
  638. else
  639. f := rci.renderDPI / 96;
  640. gl.Scalef(f * 2 / rci.viewPortSize.cx, f * 2 / rci.viewPortSize.cy, 1);
  641. gl.Translatef(f * Position.X - rci.viewPortSize.cx * 0.5,
  642. rci.viewPortSize.cy * 0.5 - f * Position.Y, 0);
  643. if Rotation <> 0 then
  644. gl.Rotatef(Rotation, 0, 0, 1);
  645. gl.MatrixMode(GL_PROJECTION);
  646. gl.PushMatrix;
  647. gl.LoadIdentity;
  648. rci.GLStates.Disable(stDepthTest);
  649. rci.GLStates.DepthWriteMask := False;
  650. end;
  651. procedure TGLBaseComponent.RenderFooter(var rci: TGLRenderContextInfo; renderSelf, renderChildren: Boolean);
  652. begin
  653. gl.PopMatrix;
  654. gl.MatrixMode(GL_MODELVIEW);
  655. gl.PopMatrix;
  656. FGuiLayout.Material.UnApply(rci);
  657. end;
  658. procedure TGLBaseComponent.SetGuiLayout(NewGui: TGLGuiLayout);
  659. begin
  660. if FGuiLayout <> NewGui then
  661. begin
  662. if Assigned(FGuiLayout) then
  663. begin
  664. FGuiLayout.RemoveGuiComponent(Self);
  665. end;
  666. FGuiComponent := nil;
  667. FGuiLayout := NewGui;
  668. if Assigned(FGuiLayout) then
  669. if FGuiLayoutName <> '' then
  670. FGuiComponent := FGuiLayout.GuiComponents.FindItem(FGuiLayoutName);
  671. // in effect this code have been moved...
  672. if Assigned(FGuiLayout) then
  673. FGuiLayout.AddGuiComponent(Self);
  674. NotifyChange(Self);
  675. end;
  676. end;
  677. procedure TGLBaseComponent.SetGuiLayoutName(const NewName: TGLGuiComponentName);
  678. begin
  679. if FGuiLayoutName <> NewName then
  680. begin
  681. FGuiComponent := nil;
  682. FGuiLayoutName := NewName;
  683. if FGuiLayoutName <> '' then
  684. if Assigned(FGuiLayout) then
  685. begin
  686. FGuiComponent := FGuiLayout.GuiComponents.FindItem(FGuiLayoutName);
  687. end;
  688. NotifyChange(Self);
  689. end;
  690. end;
  691. procedure TGLBaseComponent.Notification(AComponent: TComponent; Operation: TOperation);
  692. begin
  693. if Operation = opRemove then
  694. begin
  695. if AComponent = FGuiLayout then
  696. begin
  697. BlockRender;
  698. GuiLayout := nil;
  699. UnBlockRender;
  700. end;
  701. end;
  702. inherited;
  703. end;
  704. procedure TGLBaseComponent.SetRotation(const val: TGLFloat);
  705. begin
  706. if FRotation <> val then
  707. begin
  708. FRotation := val;
  709. NotifyChange(Self);
  710. end;
  711. end;
  712. procedure TGLBaseComponent.SetAlphaChannel(const val: Single);
  713. begin
  714. if val <> FAlphaChannel then
  715. begin
  716. if val < 0 then
  717. FAlphaChannel := 0
  718. else if val > 1 then
  719. FAlphaChannel := 1
  720. else
  721. FAlphaChannel := val;
  722. NotifyChange(Self);
  723. end;
  724. end;
  725. procedure TGLBaseComponent.SetAutosize(const Value: Boolean);
  726. var
  727. MarginLeft, MarginCenter, MarginRight: TGLFloat;
  728. MarginTop, MarginMiddle, MarginBottom: TGLFloat;
  729. MaxWidth: TGLFloat;
  730. MaxHeight: TGLFloat;
  731. i: integer;
  732. begin
  733. if FAutosize <> Value then
  734. begin
  735. FAutosize := Value;
  736. if FAutosize and Assigned(FGuiComponent) then
  737. begin
  738. MarginLeft := 0;
  739. MarginCenter := 0;
  740. MarginRight := 0;
  741. MarginTop := 0;
  742. MarginMiddle := 0;
  743. MarginBottom := 0;
  744. for i := 0 to FGuiComponent.Elements.Count - 1 do
  745. with FGuiComponent.Elements[i] do
  746. begin
  747. case Align of
  748. GLAlTopLeft, GLAlLeft, GLAlBottomLeft:
  749. begin
  750. MarginLeft := Max(MarginLeft, abs(BottomRight.X - TopLeft.X) *
  751. Scale.X);
  752. end;
  753. GLAlTop, GLAlCenter, GLAlBottom:
  754. begin
  755. MarginCenter := Max(MarginCenter, abs(BottomRight.X - TopLeft.X)
  756. * Scale.X);
  757. end;
  758. GLAlTopRight, GLAlRight, GLAlBottomRight:
  759. begin
  760. MarginRight := Max(MarginRight, abs(BottomRight.X - TopLeft.X) *
  761. Scale.X);
  762. end;
  763. end;
  764. end;
  765. for i := 0 to FGuiComponent.Elements.Count - 1 do
  766. with FGuiComponent.Elements[i] do
  767. begin
  768. case Align of
  769. GLAlTopLeft, GLAlTop, GLAlTopRight:
  770. begin
  771. MarginTop := Max(MarginTop, abs(BottomRight.Y - TopLeft.Y) *
  772. Scale.Y);
  773. end;
  774. GLAlLeft, GLAlCenter, GLAlRight:
  775. begin
  776. MarginMiddle := Max(MarginMiddle, abs(BottomRight.Y - TopLeft.Y)
  777. * Scale.Y);
  778. end;
  779. GLAlBottomLeft, GLAlBottom, GLAlBottomRight:
  780. begin
  781. MarginBottom := Max(MarginBottom, abs(BottomRight.Y - TopLeft.Y)
  782. * Scale.Y);
  783. end;
  784. end;
  785. end;
  786. MaxWidth := MarginLeft + MarginCenter + MarginRight;
  787. MaxHeight := MarginTop + MarginMiddle + MarginBottom;
  788. if MaxWidth > 0 then
  789. Width := MaxWidth;
  790. if MaxHeight > 0 then
  791. Height := MaxHeight;
  792. end;
  793. end;
  794. end;
  795. function TGLBaseComponent.StoreAlphaChannel: Boolean;
  796. begin
  797. Result := (FAlphaChannel <> 1);
  798. end;
  799. procedure TGLBaseComponent.SetNoZWrite(const val: Boolean);
  800. begin
  801. FNoZWrite := val;
  802. NotifyChange(Self);
  803. end;
  804. constructor TGLBaseComponent.Create(AOwner: TComponent);
  805. begin
  806. inherited;
  807. FGuiLayout := nil;
  808. FGuiComponent := nil;
  809. BlockRendering := False;
  810. BlockedCount := 0;
  811. RenderingCount := 0;
  812. Width := 50;
  813. Height := 50;
  814. FReBuildGui := True;
  815. GuiDestroying := False;
  816. FAlphaChannel := 1;
  817. end;
  818. destructor TGLBaseComponent.Destroy;
  819. begin
  820. GuiDestroying := True;
  821. while RenderingCount > 0 do
  822. Sleep(1);
  823. GuiLayout := nil;
  824. inherited;
  825. end;
  826. procedure TGLBaseComponent.NotifyChange(Sender: TObject);
  827. begin
  828. if Sender = FGuiLayout then
  829. begin
  830. if (FGuiLayoutName <> '') and (GuiLayout <> nil) then
  831. begin
  832. BlockRender;
  833. FGuiComponent := GuiLayout.GuiComponents.FindItem(FGuiLayoutName);
  834. ReBuildGui := True;
  835. GUIRedraw := True;
  836. UnBlockRender;
  837. end
  838. else
  839. begin
  840. BlockRender;
  841. FGuiComponent := nil;
  842. ReBuildGui := True;
  843. GUIRedraw := True;
  844. UnBlockRender;
  845. end;
  846. end;
  847. if Sender = Self then
  848. begin
  849. ReBuildGui := True;
  850. GUIRedraw := True;
  851. end;
  852. inherited;
  853. end;
  854. procedure TGLBaseComponent.MoveGUI(XRel, YRel: Single);
  855. var
  856. XC: Integer;
  857. begin
  858. if RedrawAtOnce then
  859. begin
  860. BeginUpdate;
  861. try
  862. MoveX := MoveX + XRel;
  863. MoveY := MoveY + YRel;
  864. for XC := 0 to Count - 1 do
  865. if Children[XC] is TGLBaseComponent then
  866. begin
  867. (Children[XC] as TGLBaseComponent).MoveGUI(XRel, YRel);
  868. end;
  869. GUIRedraw := True;
  870. DoChanges;
  871. finally
  872. Endupdate;
  873. end;
  874. end
  875. else
  876. begin
  877. MoveX := MoveX + XRel;
  878. MoveY := MoveY + YRel;
  879. for XC := 0 to Count - 1 do
  880. if Children[XC] is TGLBaseComponent then
  881. begin
  882. (Children[XC] as TGLBaseComponent).MoveGUI(XRel, YRel);
  883. end;
  884. GUIRedraw := True;
  885. end;
  886. end;
  887. procedure TGLBaseComponent.PlaceGUI(XPos, YPos: Single);
  888. begin
  889. MoveGUI(XPos - Position.X, YPos - Position.Y);
  890. end;
  891. procedure TGLBaseComponent.DoChanges;
  892. var
  893. XC: Integer;
  894. begin
  895. if GUIRedraw then
  896. begin
  897. GUIRedraw := False;
  898. BeginUpdate;
  899. try
  900. if MoveX <> 0 then
  901. Position.X := Position.X + MoveX;
  902. if MoveY <> 0 then
  903. Position.Y := Position.Y + MoveY;
  904. MoveX := 0;
  905. MoveY := 0;
  906. for XC := 0 to Count - 1 do
  907. if Children[XC] is TGLBaseComponent then
  908. begin
  909. (Children[XC] as TGLBaseComponent).DoChanges;
  910. end;
  911. finally
  912. EndUpdate;
  913. end;
  914. end
  915. else
  916. begin
  917. for XC := 0 to Count - 1 do
  918. if Children[XC] is TGLBaseComponent then
  919. begin
  920. (Children[XC] as TGLBaseComponent).DoChanges;
  921. end;
  922. end;
  923. end;
  924. procedure TGLBaseComponent.InternalRender(var rci: TGLRenderContextInfo;
  925. renderSelf, renderChildren: Boolean);
  926. begin
  927. if Assigned(FGuiComponent) then
  928. begin
  929. try
  930. FGuiComponent.RenderToArea(0, 0, Width, Height, FRenderStatus,
  931. FReBuildGui);
  932. except
  933. on E: Exception do
  934. GLOKMessageBox(E.Message,
  935. 'Exception in GuiComponents InternalRender function');
  936. end;
  937. end;
  938. end;
  939. procedure TGLBaseComponent.DoRender(var rci: TGLRenderContextInfo; renderSelf,
  940. renderChildren: Boolean);
  941. var
  942. B: Boolean;
  943. begin
  944. Inc(RenderingCount);
  945. B := BlockRendering;
  946. if B then
  947. begin
  948. Inc(BlockedCount);
  949. while BlockRendering do
  950. sleep(1);
  951. Dec(BlockedCount);
  952. end;
  953. if not GuiDestroying then
  954. if RenderSelf then
  955. if FGuiLayout <> nil then
  956. begin
  957. RenderHeader(rci, renderSelf, renderChildren);
  958. InternalRender(rci, RenderSelf, RenderChildren);
  959. RenderFooter(rci, renderSelf, renderChildren);
  960. FReBuildGui := False;
  961. end;
  962. if renderChildren then
  963. if Count > 0 then
  964. Self.RenderChildren(0, Count - 1, rci);
  965. Dec(RenderingCount);
  966. end;
  967. procedure TGLBaseControl.InternalMouseDown(Shift: TShiftState; Button:
  968. TMouseButton; X, Y: Integer);
  969. begin
  970. if Assigned(FOnMouseDown) then
  971. FOnMouseDown(Self, Button, Shift, X, Y);
  972. end;
  973. procedure TGLBaseControl.InternalMouseUp(Shift: TShiftState; Button:
  974. TMouseButton; X, Y: Integer);
  975. begin
  976. if Assigned(FOnMouseUp) then
  977. FOnMouseUp(Self, Button, Shift, X, Y);
  978. end;
  979. procedure TGLBaseControl.InternalMouseMove(Shift: TShiftState; X, Y: Integer);
  980. begin
  981. if Assigned(FOnMouseMove) then
  982. FOnMouseMove(Self, Shift, X, Y);
  983. end;
  984. procedure TGLBaseControl.SetActiveControl(NewControl: TGLBaseControl);
  985. begin
  986. FActiveControl := NewControl;
  987. end;
  988. procedure TGLBaseControl.SetFocusedControl(NewControl: TGLFocusControl);
  989. begin
  990. if NewControl <> FFocusedControl then
  991. begin
  992. if Assigned(FFocusedControl) then
  993. FFocusedControl.Focused := False;
  994. FFocusedControl := NewControl;
  995. if Assigned(FFocusedControl) then
  996. FFocusedControl.Focused := True;
  997. end;
  998. end;
  999. function TGLBaseControl.FindFirstGui: TGLBaseControl;
  1000. var
  1001. tmpFirst: TGLBaseControl;
  1002. TmpRoot: TGLBaseSceneObject;
  1003. begin
  1004. tmpFirst := Self;
  1005. TmpRoot := Self;
  1006. while (TmpRoot is TGLBaseComponent) do
  1007. begin
  1008. if Assigned(TmpRoot.parent) then
  1009. begin
  1010. if TmpRoot.parent is TGLBaseComponent then
  1011. begin
  1012. TmpRoot := TmpRoot.parent as TGLBaseComponent;
  1013. if TmpRoot is TGLBaseControl then
  1014. tmpFirst := TmpRoot as TGLBaseControl;
  1015. end
  1016. else
  1017. Break;
  1018. end
  1019. else
  1020. Break;
  1021. end;
  1022. Result := tmpFirst;
  1023. end;
  1024. procedure TGLBaseControl.Notification(AComponent: TComponent;
  1025. Operation: TOperation);
  1026. begin
  1027. if Operation = opRemove then
  1028. begin
  1029. if FEnteredControl <> nil then
  1030. begin
  1031. FEnteredControl.DoMouseLeave;
  1032. FEnteredControl := nil;
  1033. end;
  1034. end;
  1035. inherited;
  1036. end;
  1037. function TGLBaseControl.MouseDown(Sender: TObject; Button: TMouseButton;
  1038. Shift: TShiftState; X, Y: Integer): Boolean;
  1039. var
  1040. Xc: Integer;
  1041. AcceptMouseEvent: Boolean;
  1042. begin
  1043. Result := False;
  1044. AcceptMouseEvent := RecursiveVisible and ((Position.X <= X) and (Position.X +
  1045. Width > X) and (Position.Y <= Y) and (Position.Y + Height > Y));
  1046. if Assigned(OnAcceptMouseQuery) then
  1047. OnAcceptMouseQuery(Self, shift, ma_mousedown, Button, X, Y,
  1048. AcceptMouseEvent);
  1049. if AcceptMouseEvent then
  1050. begin
  1051. Result := True;
  1052. if not FKeepMouseEvents then
  1053. begin
  1054. if Assigned(FActiveControl) then
  1055. if FActiveControl.MouseDown(Sender, Button, Shift, X, Y) then
  1056. Exit;
  1057. for XC := count - 1 downto 0 do
  1058. if FActiveControl <> Children[XC] then
  1059. begin
  1060. if Children[XC] is TGLBaseControl then
  1061. begin
  1062. if (Children[XC] as TGLBaseControl).MouseDown(Sender, button, shift,
  1063. x, y) then
  1064. Exit;
  1065. end;
  1066. end;
  1067. end;
  1068. InternalMouseDown(Shift, Button, X, Y);
  1069. end;
  1070. end;
  1071. function TGLBaseControl.MouseUp(Sender: TObject; Button: TMouseButton; Shift:
  1072. TShiftState; X, Y: Integer): Boolean;
  1073. var
  1074. Xc: Integer;
  1075. AcceptMouseEvent: Boolean;
  1076. begin
  1077. Result := False;
  1078. AcceptMouseEvent := RecursiveVisible and ((Position.X <= X) and (Position.X +
  1079. Width > X) and (Position.Y <= Y) and (Position.Y + Height > Y));
  1080. if Assigned(OnAcceptMouseQuery) then
  1081. OnAcceptMouseQuery(Self, shift, ma_mouseup, Button, X, Y, AcceptMouseEvent);
  1082. if AcceptMouseEvent then
  1083. begin
  1084. Result := True;
  1085. if not FKeepMouseEvents then
  1086. begin
  1087. if Assigned(FActiveControl) then
  1088. if FActiveControl.MouseUp(Sender, button, shift, x, y) then
  1089. Exit;
  1090. for XC := count - 1 downto 0 do
  1091. if FActiveControl <> Children[XC] then
  1092. begin
  1093. if Children[XC] is TGLBaseControl then
  1094. begin
  1095. if (Children[XC] as TGLBaseControl).MouseUp(Sender, button, shift,
  1096. x, y) then
  1097. Exit;
  1098. end;
  1099. end;
  1100. end;
  1101. InternalMouseUp(Shift, Button, X, Y);
  1102. end;
  1103. end;
  1104. function TGLBaseControl.MouseMove(Sender: TObject; Shift: TShiftState; X, Y:
  1105. Integer): Boolean;
  1106. var
  1107. Xc: Integer;
  1108. AcceptMouseEvent: Boolean;
  1109. begin
  1110. Result := False;
  1111. AcceptMouseEvent := RecursiveVisible and ((Position.X <= X) and (Position.X +
  1112. Width > X) and (Position.Y <= Y) and (Position.Y + Height > Y));
  1113. if Assigned(OnAcceptMouseQuery) then
  1114. OnAcceptMouseQuery(Self, shift, ma_mousemove, mbMiddle, X, Y,
  1115. AcceptMouseEvent);
  1116. if AcceptMouseEvent then
  1117. begin
  1118. Result := True;
  1119. if not FKeepMouseEvents then
  1120. begin
  1121. if Assigned(FActiveControl) then
  1122. if FActiveControl.MouseMove(Sender, shift, x, y) then
  1123. Exit;
  1124. for XC := count - 1 downto 0 do
  1125. if FActiveControl <> Children[XC] then
  1126. begin
  1127. if Children[XC] is TGLBaseControl then
  1128. begin
  1129. if (Children[XC] as TGLBaseControl).MouseMove(Sender, shift, x, y)
  1130. then
  1131. begin
  1132. if FEnteredControl <> (Children[XC] as TGLBaseControl) then
  1133. begin
  1134. if FEnteredControl <> nil then
  1135. begin
  1136. FEnteredControl.DoMouseLeave;
  1137. end;
  1138. FEnteredControl := (Children[XC] as TGLBaseControl);
  1139. if FEnteredControl <> nil then
  1140. begin
  1141. FEnteredControl.DoMouseEnter;
  1142. end;
  1143. end;
  1144. Exit;
  1145. end;
  1146. end;
  1147. end;
  1148. end;
  1149. if FEnteredControl <> nil then
  1150. begin
  1151. FEnteredControl.DoMouseLeave;
  1152. FEnteredControl := nil;
  1153. end;
  1154. InternalMouseMove(Shift, X, Y);
  1155. end;
  1156. end;
  1157. procedure TGLBaseControl.KeyDown(Sender: TObject; var Key: Word; Shift:
  1158. TShiftState);
  1159. begin
  1160. if Assigned(FFocusedControl) then
  1161. begin
  1162. FFocusedControl.KeyDown(Sender, Key, Shift);
  1163. end;
  1164. end;
  1165. procedure TGLBaseControl.KeyUp(Sender: TObject; var Key: Word; Shift:
  1166. TShiftState);
  1167. begin
  1168. if Assigned(FFocusedControl) then
  1169. begin
  1170. FFocusedControl.KeyUp(Sender, Key, Shift);
  1171. end;
  1172. end;
  1173. procedure TGLBaseControl.KeyPress(Sender: TObject; var Key: Char);
  1174. begin
  1175. if Assigned(FFocusedControl) then
  1176. begin
  1177. FFocusedControl.KeyPress(Sender, Key);
  1178. end;
  1179. end;
  1180. procedure TGLFocusControl.InternalKeyPress(var Key: Char);
  1181. begin
  1182. if assigned(FOnKeyPress) then
  1183. FOnKeyPress(Self, Key);
  1184. end;
  1185. procedure TGLFocusControl.InternalKeyDown(var Key: Word; Shift: TShiftState);
  1186. begin
  1187. if assigned(FOnKeyDown) then
  1188. FOnKeyDown(Self, Key, shift);
  1189. end;
  1190. procedure TGLFocusControl.InternalKeyUp(var Key: Word; Shift: TShiftState);
  1191. begin
  1192. if assigned(FOnKeyUp) then
  1193. FOnKeyUp(Self, Key, shift);
  1194. end;
  1195. procedure TGLBaseControl.DoMouseEnter;
  1196. begin
  1197. if Assigned(OnMouseEnter) then
  1198. OnMouseEnter(Self);
  1199. end;
  1200. procedure TGLBaseControl.DoMouseLeave;
  1201. begin
  1202. //leave all child controls
  1203. if FEnteredControl <> nil then
  1204. begin
  1205. FEnteredControl.DoMouseLeave;
  1206. FEnteredControl := nil;
  1207. end;
  1208. if Assigned(OnMouseLeave) then
  1209. OnMouseLeave(Self);
  1210. end;
  1211. procedure TGLFocusControl.SetFocused(Value: Boolean);
  1212. begin
  1213. if Value <> FFocused then
  1214. begin
  1215. FFocused := Value;
  1216. GUIRedraw := True;
  1217. end;
  1218. end;
  1219. function TGLFocusControl.GetRootControl: TGLBaseControl;
  1220. begin
  1221. if not Assigned(FRootControl) then
  1222. begin
  1223. FRootControl := FindFirstGui;
  1224. end;
  1225. Result := FRootControl;
  1226. end;
  1227. procedure TGLFocusControl.NotifyHide;
  1228. begin
  1229. inherited;
  1230. if (RootControl.FFocusedControl = Self) and (self.focused) then
  1231. begin
  1232. RootControl.FocusedControl.PrevControl;
  1233. end;
  1234. end;
  1235. procedure TGLFocusControl.ReGetRootControl;
  1236. begin
  1237. FRootControl := FindFirstGui;
  1238. end;
  1239. function TGLFocusControl.GetFocusedColor: TColor;
  1240. begin
  1241. Result := ConvertColorVector(FFocusedColor);
  1242. end;
  1243. procedure TGLFocusControl.SetFocusedColor(const Val: TColor);
  1244. begin
  1245. FFocusedColor := ConvertWinColor(val);
  1246. GUIRedraw := True;
  1247. end;
  1248. procedure TGLFocusControl.SetFocus;
  1249. begin
  1250. RootControl.FocusedControl := Self;
  1251. end;
  1252. procedure TGLFocusControl.NextControl;
  1253. var
  1254. Host: TGLBaseComponent;
  1255. Index: Integer;
  1256. IndexedChild: TGLBaseComponent;
  1257. RestartedLoop: Boolean;
  1258. begin
  1259. RestartedLoop := False;
  1260. if Parent is TGLBaseComponent then
  1261. begin
  1262. Host := Parent as TGLBaseComponent;
  1263. Index := Host.IndexOfChild(Self);
  1264. while not Host.RecursiveVisible do
  1265. begin
  1266. if Host.Parent is TGLBaseComponent then
  1267. begin
  1268. IndexedChild := Host;
  1269. Host := Host.Parent as TGLBaseComponent;
  1270. Index := Host.IndexOfChild(IndexedChild);
  1271. end
  1272. else
  1273. begin
  1274. RootControl.FocusedControl := nil;
  1275. Exit;
  1276. end;
  1277. end;
  1278. while true do
  1279. begin
  1280. if Index > 0 then
  1281. begin
  1282. Dec(Index);
  1283. if Host.Children[Index] is TGLFocusControl then
  1284. begin
  1285. with (Host.Children[Index] as TGLFocusControl) do
  1286. if RecursiveVisible then
  1287. begin
  1288. SetFocus;
  1289. Exit;
  1290. end;
  1291. end
  1292. else
  1293. begin
  1294. if Host.Children[Index] is TGLBaseComponent then
  1295. begin
  1296. IndexedChild := Host.Children[Index] as TGLBaseComponent;
  1297. if IndexedChild.RecursiveVisible then
  1298. begin
  1299. Host := IndexedChild;
  1300. Index := Host.Count;
  1301. end;
  1302. end;
  1303. end;
  1304. end
  1305. else
  1306. begin
  1307. if Host.Parent is TGLBaseComponent then
  1308. begin
  1309. Index := Host.Parent.IndexOfChild(Host);
  1310. Host := Host.Parent as TGLBaseComponent;
  1311. end
  1312. else
  1313. begin
  1314. if RestartedLoop then
  1315. begin
  1316. SetFocus;
  1317. Exit;
  1318. end;
  1319. Index := Host.Count;
  1320. RestartedLoop := True;
  1321. end;
  1322. end;
  1323. end;
  1324. end;
  1325. end;
  1326. procedure TGLFocusControl.PrevControl;
  1327. var
  1328. Host: TGLBaseComponent;
  1329. Index: Integer;
  1330. IndexedChild: TGLBaseComponent;
  1331. RestartedLoop: Boolean;
  1332. begin
  1333. RestartedLoop := False;
  1334. if Parent is TGLBaseComponent then
  1335. begin
  1336. Host := Parent as TGLBaseComponent;
  1337. Index := Host.IndexOfChild(Self);
  1338. while not Host.RecursiveVisible do
  1339. begin
  1340. if Host.Parent is TGLBaseComponent then
  1341. begin
  1342. IndexedChild := Host;
  1343. Host := Host.Parent as TGLBaseComponent;
  1344. Index := Host.IndexOfChild(IndexedChild);
  1345. end
  1346. else
  1347. begin
  1348. RootControl.FocusedControl := nil;
  1349. Exit;
  1350. end;
  1351. end;
  1352. while true do
  1353. begin
  1354. Inc(Index);
  1355. if Index < Host.Count then
  1356. begin
  1357. if Host.Children[Index] is TGLFocusControl then
  1358. begin
  1359. with (Host.Children[Index] as TGLFocusControl) do
  1360. if RecursiveVisible then
  1361. begin
  1362. SetFocus;
  1363. Exit;
  1364. end;
  1365. end;
  1366. if Host.Children[Index] is TGLBaseComponent then
  1367. begin
  1368. IndexedChild := Host.Children[Index] as TGLBaseComponent;
  1369. if IndexedChild.RecursiveVisible then
  1370. begin
  1371. Host := IndexedChild;
  1372. Index := -1;
  1373. end;
  1374. end;
  1375. end
  1376. else
  1377. begin
  1378. if Host.Parent is TGLBaseComponent then
  1379. begin
  1380. IndexedChild := Host;
  1381. Host := Host.Parent as TGLBaseComponent;
  1382. Index := Host.IndexOfChild(IndexedChild);
  1383. end
  1384. else
  1385. begin
  1386. if RestartedLoop then
  1387. begin
  1388. RootControl.FocusedControl := nil;
  1389. Exit;
  1390. end;
  1391. Index := -1;
  1392. RestartedLoop := True;
  1393. end;
  1394. end;
  1395. end;
  1396. end;
  1397. end;
  1398. procedure TGLFocusControl.KeyPress(Sender: TObject; var Key: Char);
  1399. begin
  1400. InternalKeyPress(Key);
  1401. if Key = #9 then
  1402. begin
  1403. if ssShift in FShiftState then
  1404. begin
  1405. PrevControl;
  1406. end
  1407. else
  1408. begin
  1409. NextControl;
  1410. end;
  1411. end;
  1412. end;
  1413. procedure TGLFocusControl.KeyDown(Sender: TObject; var Key: Word; Shift:
  1414. TShiftState);
  1415. begin
  1416. FShiftState := Shift;
  1417. InternalKeyDown(Key, Shift);
  1418. if Key = VK_TAB then
  1419. begin
  1420. if ssShift in FShiftState then
  1421. begin
  1422. PrevControl;
  1423. end
  1424. else
  1425. begin
  1426. NextControl;
  1427. end;
  1428. end;
  1429. end;
  1430. procedure TGLFocusControl.KeyUp(Sender: TObject; var Key: Word; Shift:
  1431. TShiftState);
  1432. begin
  1433. FShiftState := Shift;
  1434. InternalKeyUp(Key, Shift);
  1435. if Key = VK_TAB then
  1436. begin
  1437. if ssShift in FShiftState then
  1438. begin
  1439. PrevControl;
  1440. end
  1441. else
  1442. begin
  1443. NextControl;
  1444. end;
  1445. end;
  1446. end;
  1447. //------------------------
  1448. // base font control
  1449. //------------------------
  1450. constructor TGLBaseFontControl.Create(AOwner: TComponent);
  1451. begin
  1452. inherited;
  1453. FBitmapFont := nil;
  1454. FDefaultColor := clrBlack;
  1455. end;
  1456. destructor TGLBaseFontControl.Destroy;
  1457. begin
  1458. inherited;
  1459. BitmapFont := nil;
  1460. end;
  1461. procedure TGLBaseFontControl.SetBitmapFont(NewFont: TGLCustomBitmapFont);
  1462. begin
  1463. if NewFont <> FBitmapFont then
  1464. begin
  1465. if Assigned(FBitmapFont) then
  1466. begin
  1467. FBitmapFont.RemoveFreeNotification(Self);
  1468. FBitmapFont.UnRegisterUser(Self);
  1469. end;
  1470. FBitmapFont := NewFont;
  1471. if Assigned(FBitmapFont) then
  1472. begin
  1473. FBitmapFont.RegisterUser(Self);
  1474. FBitmapFont.FreeNotification(Self);
  1475. end;
  1476. GUIRedraw := True;
  1477. end;
  1478. end;
  1479. function TGLBaseFontControl.GetBitmapFont: TGLCustomBitmapFont;
  1480. begin
  1481. Result := nil;
  1482. if Assigned(FBitmapFont) then
  1483. Result := FBitmapFont
  1484. else if Assigned(GuiLayout) then
  1485. if Assigned(GuiLayout.BitmapFont) then
  1486. begin
  1487. if not (csDesigning in ComponentState) then
  1488. begin
  1489. if not GuiDestroying then
  1490. begin
  1491. BitmapFont := GuiLayout.BitmapFont;
  1492. Result := FBitmapFont;
  1493. end;
  1494. end
  1495. else
  1496. Result := GuiLayout.BitmapFont;
  1497. end;
  1498. end;
  1499. function TGLBaseFontControl.GetDefaultColor: TColor;
  1500. begin
  1501. Result := ConvertColorVector(FDefaultColor);
  1502. end;
  1503. procedure TGLBaseFontControl.SetDefaultColor(value: TColor);
  1504. begin
  1505. FDefaultColor := ConvertWinColor(value);
  1506. GUIRedraw := True;
  1507. NotifyChange(Self);
  1508. end;
  1509. procedure TGLBaseFontControl.Notification(AComponent: TComponent; Operation:
  1510. TOperation);
  1511. begin
  1512. if (Operation = opRemove) and (AComponent = FBitmapFont) then
  1513. begin
  1514. BlockRender;
  1515. BitmapFont := nil;
  1516. UnBlockRender;
  1517. end;
  1518. inherited;
  1519. end;
  1520. //----------------------------------
  1521. // GLBaseTextControl
  1522. //----------------------------------
  1523. procedure TGLBaseTextControl.SetCaption(const NewCaption: UnicodeString);
  1524. begin
  1525. FCaption := NewCaption;
  1526. GuiRedraw := True;
  1527. end;
  1528. procedure TGLBaseFontControl.WriteTextAt(var rci: TGLRenderContextInfo; const X,
  1529. Y: TGLFloat; const Data: UnicodeString; const Color: TGLColorVector);
  1530. var
  1531. Position: TGLVector;
  1532. begin
  1533. if Assigned(BitmapFont) then
  1534. begin
  1535. Position.X := Round(X);
  1536. Position.Y := Round(Y);
  1537. Position.Z := 0;
  1538. Position.W := 0;
  1539. BitmapFont.RenderString(rci, Data, taLeftJustify, tlTop, Color, @Position);
  1540. end;
  1541. end;
  1542. procedure TGLBaseFontControl.WriteTextAt(var rci: TGLRenderContextInfo; const X1,
  1543. Y1, X2, Y2: TGLFloat; const Data: UnicodeString; const Color: TGLColorVector);
  1544. var
  1545. Position: TGLVector;
  1546. begin
  1547. if Assigned(BitmapFont) then
  1548. begin
  1549. Position.X := Round(((X2 + X1 -
  1550. BitmapFont.CalcStringWidth(Data)) * 0.5));
  1551. Position.Y := Round(-((Y2 + Y1 - GetFontHeight) * 0.5)) + 2;
  1552. Position.Z := 0;
  1553. Position.W := 0;
  1554. BitmapFont.RenderString(rci, Data, taLeftJustify, tlTop, Color, @Position);
  1555. end;
  1556. end;
  1557. function TGLBaseFontControl.GetFontHeight: Integer;
  1558. begin
  1559. if Assigned(BitmapFont) then
  1560. if BitmapFont is TGLWindowsBitmapFont then
  1561. Result := Abs((BitmapFont as TGLWindowsBitmapFont).Font.Height)
  1562. else
  1563. Result := BitmapFont.CharHeight
  1564. else
  1565. Result := -1;
  1566. end;
  1567. //----------------------------------
  1568. // GLBaseCustomControl
  1569. //----------------------------------
  1570. constructor TGLCustomControl.Create(AOwner: TComponent);
  1571. begin
  1572. inherited;
  1573. FMaterial := TGLMaterial.create(Self);
  1574. FBitmap := TBitmap.create;
  1575. FBitmap.OnChange := OnBitmapChanged;
  1576. FInternalBitmap := nil;
  1577. FInvalidRenderCount := 0;
  1578. FXTexCoord := 1;
  1579. FYTexCoord := 1;
  1580. end;
  1581. destructor TGLCustomControl.Destroy;
  1582. begin
  1583. if Assigned(FInternalBitmap) then
  1584. FInternalBitmap.Free;
  1585. Bitmap.Free;
  1586. FMaterial.Free;
  1587. inherited;
  1588. end;
  1589. procedure TGLCustomControl.SetCentered(const Value: Boolean);
  1590. begin
  1591. FCentered := Value;
  1592. end;
  1593. procedure TGLCustomControl.OnBitmapChanged(Sender: TObject);
  1594. begin
  1595. FBitmapChanged := True;
  1596. end;
  1597. procedure TGLCustomControl.SetBitmap(ABitmap: TBitmap);
  1598. begin
  1599. FBitmap.Assign(ABitmap);
  1600. end;
  1601. procedure TGLCustomControl.InternalRender(var rci: TGLRenderContextInfo;
  1602. renderSelf, renderChildren: Boolean);
  1603. var
  1604. X1, X2, Y1, Y2: Single;
  1605. begin
  1606. if Assigned(OnRender) then
  1607. OnRender(self, FBitmap);
  1608. if FBitmapChanged then
  1609. if FInvalidRenderCount >= FMaxInvalidRenderCount then
  1610. begin
  1611. FInvalidRenderCount := 0;
  1612. if not Assigned(FInternalBitmap) then
  1613. FInternalBitmap := TBitmap.Create;
  1614. FInternalBitmap.PixelFormat := FBitmap.PixelFormat;
  1615. FInternalBitmap.Width := RoundUpToPowerOf2(FBitmap.Width);
  1616. FInternalBitmap.Height := RoundUpToPowerOf2(FBitmap.Height);
  1617. FInternalBitmap.Canvas.CopyRect(FBitmap.Canvas.ClipRect, FBitmap.Canvas,
  1618. FBitmap.Canvas.ClipRect);
  1619. FBitmapChanged := False;
  1620. with Material.GetActualPrimaryTexture do
  1621. begin
  1622. Disabled := False;
  1623. Image.Assign(FInternalBitmap);
  1624. end;
  1625. FXTexCoord := FBitmap.Width / FInternalBitmap.Width;
  1626. FYTexCoord := FBitmap.Height / FInternalBitmap.Height;
  1627. end
  1628. else
  1629. Inc(FInvalidRenderCount);
  1630. if Assigned(FGuiComponent) then
  1631. begin
  1632. try
  1633. if Centered then
  1634. FGuiComponent.RenderToArea(-Width / 2, -Height / 2, Width, Height,
  1635. FRenderStatus, FReBuildGui)
  1636. else
  1637. FGuiComponent.RenderToArea(0, 0, Width, Height, FRenderStatus,
  1638. FReBuildGui);
  1639. except
  1640. on E: Exception do
  1641. GLOKMessageBox(E.Message,
  1642. 'Exception in TGLCustomControl InternalRender function');
  1643. end;
  1644. X1 := FRenderStatus[GLAlCenter].X1;
  1645. X2 := FRenderStatus[GLAlCenter].X2;
  1646. Y1 := -FRenderStatus[GLAlCenter].Y2;
  1647. Y2 := -FRenderStatus[GLAlCenter].Y1;
  1648. end
  1649. else
  1650. begin
  1651. if Centered then
  1652. begin
  1653. X2 := Width / 2;
  1654. Y1 := -Height / 2;
  1655. X1 := -X2;
  1656. Y2 := -Y1;
  1657. end
  1658. else
  1659. begin
  1660. X2 := Width;
  1661. Y2 := -Height;
  1662. X1 := 0;
  1663. Y1 := 0;
  1664. end;
  1665. end;
  1666. GuiLayout.Material.UnApply(rci);
  1667. Material.Apply(rci);
  1668. gl.Begin_(GL_QUADS);
  1669. gl.TexCoord2f(FXTexCoord, -FYTexCoord);
  1670. gl.Vertex2f(X2, Y2);
  1671. gl.TexCoord2f(FXTexCoord, 0);
  1672. gl.Vertex2f(X2, Y1);
  1673. gl.TexCoord2f(0, 0);
  1674. gl.Vertex2f(X1, Y1);
  1675. gl.TexCoord2f(0, -FYTexCoord);
  1676. gl.Vertex2f(X1, Y2);
  1677. gl.End_();
  1678. Material.UnApply(rci);
  1679. GuiLayout.Material.Apply(rci);
  1680. end;
  1681. procedure TGLCustomControl.SetMaterial(AMaterial: TGLMaterial);
  1682. begin
  1683. FMaterial.Assign(AMaterial);
  1684. end;
  1685. //----------------------------------
  1686. // GLPopupMenu
  1687. //----------------------------------
  1688. procedure TGLPopupMenu.SetFocused(Value: Boolean);
  1689. begin
  1690. inherited;
  1691. if not (csDesigning in ComponentState) then
  1692. if not FFocused then
  1693. Visible := False;
  1694. end;
  1695. procedure TGLPopupMenu.SetMenuItems(Value: TStrings);
  1696. begin
  1697. FMenuItems.Assign(Value);
  1698. NotifyChange(Self);
  1699. end;
  1700. procedure TGLPopupMenu.SetMarginSize(const val: Single);
  1701. begin
  1702. if FMarginSize <> val then
  1703. begin
  1704. FMarginSize := val;
  1705. NotifyChange(Self);
  1706. end;
  1707. end;
  1708. procedure TGLPopupMenu.SetSelIndex(const val: Integer);
  1709. begin
  1710. if FSelIndex <> val then
  1711. begin
  1712. FSelIndex := val;
  1713. NotifyChange(Self);
  1714. end;
  1715. end;
  1716. procedure TGLPopupMenu.InternalMouseDown(Shift: TShiftState; Button:
  1717. TMouseButton; X, Y: Integer);
  1718. var
  1719. ClickIndex: Integer;
  1720. Tx: Single;
  1721. Ty: Single;
  1722. begin
  1723. Tx := X - Position.X;
  1724. Ty := Y - Position.Y;
  1725. if Button = mbLeft then
  1726. if IsInRect(fRenderStatus[glAlCenter], Tx, Ty) then
  1727. if Assigned(BitmapFont) then
  1728. begin
  1729. ClickIndex := Round(Int((Ty - fRenderStatus[glAlCenter].y1) /
  1730. BitmapFont.CharHeight));
  1731. if (ClickIndex >= 0) and (ClickIndex < FMenuItems.Count) then
  1732. begin
  1733. if Assigned(OnClick) then
  1734. OnClick(Self, ClickIndex, FMenuItems[ClickIndex]);
  1735. Visible := False;
  1736. end;
  1737. end;
  1738. end;
  1739. procedure TGLPopupMenu.InternalMouseMove(Shift: TShiftState; X, Y: Integer);
  1740. var
  1741. Tx: Single;
  1742. Ty: Single;
  1743. begin
  1744. Tx := X - Position.X;
  1745. Ty := Y - Position.Y;
  1746. if IsInRect(fRenderStatus[glAlCenter], Tx, Ty) then
  1747. if Assigned(BitmapFont) then
  1748. begin
  1749. SelIndex := Round(Int((Ty - fRenderStatus[glAlCenter].y1) /
  1750. BitmapFont.CharHeight));
  1751. end;
  1752. end;
  1753. procedure TGLPopupMenu.OnStringListChange(Sender: TObject);
  1754. var
  1755. CenterHeight: Single;
  1756. TextHeight: Single;
  1757. begin
  1758. if not FReBuildGui then
  1759. begin
  1760. if Assigned(BitmapFont) then
  1761. with FRenderStatus[GLalCenter] do
  1762. begin
  1763. CenterHeight := Y2 - Y1;
  1764. CenterHeight := Round(CenterHeight + 0.499);
  1765. TextHeight := BitmapFont.CharHeight * FMenuItems.Count;
  1766. if CenterHeight <> TextHeight then // allways round up!
  1767. begin
  1768. Height := Height + TextHeight - CenterHeight;
  1769. end;
  1770. end;
  1771. end;
  1772. end;
  1773. constructor TGLPopupMenu.Create(AOwner: TComponent);
  1774. begin
  1775. inherited;
  1776. FOnClick := nil;
  1777. FMenuItems := TStringList.Create;
  1778. (FMenuItems as TStringList).OnChange := OnStringListChange;
  1779. FSelIndex := 0;
  1780. NewHeight := -1;
  1781. end;
  1782. destructor TGLPopupMenu.Destroy;
  1783. begin
  1784. inherited;
  1785. FMenuItems.Free;
  1786. end;
  1787. procedure TGLPopupMenu.PopUp(Px, Py: Integer);
  1788. begin
  1789. Position.X := PX;
  1790. Position.Y := PY;
  1791. Visible := True;
  1792. SetFocus;
  1793. RootControl.ActiveControl := Self;
  1794. end;
  1795. procedure TGLPopupMenu.InternalRender(var rci: TGLRenderContextInfo; renderSelf,
  1796. renderChildren: Boolean);
  1797. var
  1798. CenterHeight: Single;
  1799. TextHeight: Single;
  1800. YPos: Single;
  1801. XPos: Single;
  1802. XC: Integer;
  1803. changedHeight: single;
  1804. begin
  1805. if Assigned(FGuiComponent) then
  1806. begin
  1807. try
  1808. if NewHeight <> -1 then
  1809. FGuiComponent.RenderToArea(0, 0, Width, NewHeight, FRenderStatus,
  1810. FReBuildGui)
  1811. else
  1812. FGuiComponent.RenderToArea(0, 0, Width, Height, FRenderStatus,
  1813. FReBuildGui);
  1814. except
  1815. on E: Exception do
  1816. GLOKMessageBox(E.Message,
  1817. 'Exception in GuiComponents InternalRender function');
  1818. end;
  1819. end;
  1820. if Assigned(BitmapFont) and (FMenuItems.Count > 0) then
  1821. with FRenderStatus[GLalCenter] do
  1822. begin
  1823. CenterHeight := Y2 - Y1;
  1824. CenterHeight := Round(CenterHeight + 0.499);
  1825. TextHeight := BitmapFont.CharHeight * FMenuItems.Count;
  1826. if CenterHeight <> TextHeight then // allways round up!
  1827. begin
  1828. changedHeight := Height + TextHeight - CenterHeight;
  1829. if changedHeight <> newHeight then
  1830. begin
  1831. newHeight := changedHeight;
  1832. InternalRender(rci, RenderSelf, RenderChildren);
  1833. end;
  1834. end
  1835. else
  1836. begin
  1837. YPos := -Y1;
  1838. XPos := X1 + MarginSize;
  1839. for XC := 0 to FMenuItems.count - 1 do
  1840. begin
  1841. if FSelIndex = XC then
  1842. WriteTextAt(rci, XPos, YPos, FMenuItems[XC], FFocusedColor)
  1843. else
  1844. WriteTextAt(rci, XPos, YPos, FMenuItems[XC], FDefaultColor);
  1845. YPos := YPos - BitmapFont.CharHeight;
  1846. end;
  1847. end;
  1848. end;
  1849. end;
  1850. procedure TGLPopupMenu.DoRender(var rci: TGLRenderContextInfo; renderSelf,
  1851. renderChildren: Boolean);
  1852. begin
  1853. inherited;
  1854. // to avoid gui render-block deadlock!
  1855. if NewHeight <> -1 then
  1856. begin
  1857. Height := NewHeight;
  1858. NewHeight := -1;
  1859. end;
  1860. end;
  1861. function TGLPopupMenu.MouseDown(Sender: TObject; Button: TMouseButton; Shift:
  1862. TShiftState; X, Y: Integer): Boolean;
  1863. begin
  1864. Result := inherited MouseDown(Sender, Button, Shift, X, Y);
  1865. if (not Result) and (RootControl.ActiveControl = Self) then
  1866. begin
  1867. RootControl.ActiveControl := nil;
  1868. NextControl;
  1869. end;
  1870. end;
  1871. //----------------------------------
  1872. // GLForm
  1873. //----------------------------------
  1874. procedure TGLForm.InternalMouseDown(Shift: TShiftState; Button: TMouseButton;
  1875. X, Y: Integer);
  1876. var
  1877. CanMove: Boolean;
  1878. YHere: TGLFloat;
  1879. begin
  1880. YHere := Y - Position.Y;
  1881. if YHere < FRenderStatus[GLALTop].Y2 then
  1882. begin
  1883. if Button = mbLeft then
  1884. begin
  1885. (* If contains(Width-22,Width-6,XHere) and contains(8,24,YHere) then
  1886. Begin
  1887. Close;
  1888. End else(**)
  1889. begin
  1890. CanMove := True;
  1891. if Assigned(FOnCanMove) then
  1892. FOnCanMove(Self, CanMove);
  1893. if CanMove then
  1894. begin
  1895. OldX := X;
  1896. OldY := Y;
  1897. Moving := True;
  1898. if Parent is TGLFocusControl then
  1899. (Parent as TGLFocusControl).ActiveControl := Self;
  1900. end;
  1901. end;
  1902. end;
  1903. end
  1904. else
  1905. inherited;
  1906. end;
  1907. procedure TGLForm.InternalMouseUp(Shift: TShiftState; Button: TMouseButton; X,
  1908. Y: Integer);
  1909. begin
  1910. if (Button = mbLeft) and Moving then
  1911. begin
  1912. Moving := False;
  1913. if Parent is TGLFocusControl then
  1914. (Parent as TGLFocusControl).ActiveControl := nil;
  1915. Exit;
  1916. end;
  1917. if Y - Position.Y < 27 then
  1918. begin
  1919. end
  1920. else
  1921. inherited;
  1922. end;
  1923. procedure TGLForm.InternalMouseMove(Shift: TShiftState; X, Y: Integer);
  1924. var
  1925. XRel, YRel: Single;
  1926. begin
  1927. if Moving then
  1928. begin
  1929. if (X <> OldX) or (Y <> OldY) then
  1930. begin
  1931. XRel := X - OldX;
  1932. YRel := Y - OldY;
  1933. XRel := XRel + Position.X;
  1934. YRel := YRel + Position.Y;
  1935. if Assigned(OnMoving) then
  1936. OnMoving(Self, XRel, YRel);
  1937. XRel := XRel - Position.X;
  1938. YRel := YRel - Position.Y;
  1939. MoveGUI(XRel, YRel);
  1940. OldX := X;
  1941. OldY := Y;
  1942. end;
  1943. end
  1944. else if Y - Position.Y < 27 then
  1945. begin
  1946. //
  1947. end
  1948. else
  1949. inherited;
  1950. end;
  1951. function TGLForm.GetTitleColor: TColor;
  1952. begin
  1953. Result := ConvertColorVector(FTitleColor);
  1954. end;
  1955. procedure TGLForm.SetTitleColor(value: TColor);
  1956. begin
  1957. FTitleColor := ConvertWinColor(value);
  1958. GUIRedraw := True;
  1959. end;
  1960. constructor TGLForm.Create(AOwner: TComponent);
  1961. begin
  1962. inherited;
  1963. FTitleOffset := 2;
  1964. end;
  1965. procedure TGLForm.Close;
  1966. var
  1967. HowClose: TGLFormCloseOptions;
  1968. begin
  1969. HowClose := co_hide;
  1970. if Assigned(FOnCanClose) then
  1971. FOnCanClose(Self, HowClose);
  1972. case HowClose of
  1973. co_hide: Visible := False;
  1974. co_ignore: ;
  1975. co_Destroy: Free;
  1976. end;
  1977. end;
  1978. procedure TGLForm.NotifyShow;
  1979. begin
  1980. inherited;
  1981. if Assigned(FOnShow) then
  1982. FOnShow(Self);
  1983. end;
  1984. procedure TGLForm.NotifyHide;
  1985. begin
  1986. inherited;
  1987. if Assigned(FOnHide) then
  1988. FOnHide(Self);
  1989. end;
  1990. function TGLForm.MouseUp(Sender: TObject; Button: TMouseButton; Shift:
  1991. TShiftState; X, Y: Integer): Boolean;
  1992. begin
  1993. if (Button = mbLeft) and (Moving) then
  1994. begin
  1995. Result := True;
  1996. InternalMouseUp(Shift, Button, X, Y);
  1997. end
  1998. else
  1999. Result := inherited MouseUp(Sender, Button, Shift, X, Y);
  2000. end;
  2001. function TGLForm.MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer):
  2002. Boolean;
  2003. begin
  2004. if (Moving) then
  2005. begin
  2006. Result := True;
  2007. InternalMouseMove(Shift, X, Y);
  2008. end
  2009. else
  2010. Result := inherited MouseMove(Sender, Shift, X, Y);
  2011. end;
  2012. procedure TGLForm.InternalRender(var rci: TGLRenderContextInfo; renderSelf,
  2013. renderChildren: Boolean);
  2014. var
  2015. ATitleColor: TGLColorVector;
  2016. begin
  2017. if Assigned(FGuiComponent) then
  2018. begin
  2019. FGuiComponent.RenderToArea(0, 0, Width, Height, FRenderStatus, FReBuildGui);
  2020. ATitleColor := FTitleColor;
  2021. ATitleColor.W := AlphaChannel;
  2022. WriteTextAt(rci, ((FRenderStatus[GLAlTop].X2 + FRenderStatus[GLAlTop].X1 -
  2023. BitmapFont.CalcStringWidth(Caption)) * 0.5),
  2024. -((FRenderStatus[GLAlTop].Y2 + FRenderStatus[GLAlTop].Y1 - GetFontHeight) *
  2025. 0.5) + TitleOffset, Caption, ATitleColor);
  2026. end;
  2027. end;
  2028. procedure TGLCheckBox.SetChecked(NewChecked: Boolean);
  2029. begin
  2030. if NewChecked <> FChecked then
  2031. begin
  2032. BlockRender;
  2033. try
  2034. if NewChecked then
  2035. if Group >= 0 then
  2036. UnpressGroup(FindFirstGui, Group);
  2037. FChecked := NewChecked;
  2038. finally
  2039. UnBlockRender;
  2040. end;
  2041. NotifyChange(Self);
  2042. if Assigned(FOnChange) then
  2043. FOnChange(Self);
  2044. end;
  2045. end;
  2046. procedure TGLCheckBox.InternalMouseDown(Shift: TShiftState; Button:
  2047. TMouseButton; X, Y: Integer);
  2048. begin
  2049. Checked := not Checked;
  2050. inherited;
  2051. end;
  2052. procedure TGLCheckBox.InternalMouseUp(Shift: TShiftState; Button:
  2053. TMouseButton; X, Y: Integer);
  2054. begin
  2055. inherited;
  2056. end;
  2057. procedure TGLCheckBox.SetGuiLayoutNameChecked(const newName: TGLGuiComponentName);
  2058. begin
  2059. if FGuiLayoutNameChecked <> NewName then
  2060. begin
  2061. FGuiCheckedComponent := nil;
  2062. FGuiLayoutNameChecked := NewName;
  2063. if Assigned(FGuiLayout) then
  2064. begin
  2065. FGuiCheckedComponent :=
  2066. FGuiLayout.GuiComponents.FindItem(FGuiLayoutNameChecked);
  2067. FReBuildGui := True;
  2068. GUIRedraw := True;
  2069. end;
  2070. end;
  2071. end;
  2072. procedure TGLCheckBox.SetGuiLayout(NewGui: TGLGuiLayout);
  2073. begin
  2074. FGuiCheckedComponent := nil;
  2075. inherited;
  2076. if Assigned(FGuiLayout) then
  2077. begin
  2078. FGuiCheckedComponent :=
  2079. FGuiLayout.GuiComponents.FindItem(FGuiLayoutNameChecked);
  2080. FReBuildGui := True;
  2081. GUIRedraw := True;
  2082. end;
  2083. end;
  2084. procedure TGLCheckBox.SetGroup(const val: Integer);
  2085. begin
  2086. FGroup := val;
  2087. if Checked then
  2088. begin
  2089. BlockRender;
  2090. FChecked := False;
  2091. UnpressGroup(FindFirstGui, val);
  2092. FChecked := true;
  2093. UnBlockRender;
  2094. end;
  2095. end;
  2096. constructor TGLCheckBox.Create(AOwner: TComponent);
  2097. begin
  2098. inherited;
  2099. FChecked := False;
  2100. FGroup := -1;
  2101. end;
  2102. procedure TGLCheckBox.InternalRender(var rci: TGLRenderContextInfo; renderSelf,
  2103. renderChildren: Boolean);
  2104. begin
  2105. if Checked then
  2106. begin
  2107. if Assigned(FGuiCheckedComponent) then
  2108. begin
  2109. FGuiCheckedComponent.RenderToArea(0, 0, Width, Height, FRenderStatus,
  2110. FReBuildGui);
  2111. end;
  2112. end
  2113. else
  2114. begin
  2115. if Assigned(FGuiComponent) then
  2116. begin
  2117. FGuiComponent.RenderToArea(0, 0, Width, Height, FRenderStatus,
  2118. FReBuildGui);
  2119. end;
  2120. end;
  2121. end;
  2122. procedure TGLCheckBox.NotifyChange(Sender: TObject);
  2123. begin
  2124. if Sender = FGuiLayout then
  2125. begin
  2126. if (FGuiLayoutNameChecked <> '') and (GuiLayout <> nil) then
  2127. begin
  2128. BlockRender;
  2129. FGuiCheckedComponent :=
  2130. GuiLayout.GuiComponents.FindItem(FGuiLayoutNameChecked);
  2131. ReBuildGui := True;
  2132. GUIRedraw := True;
  2133. UnBlockRender;
  2134. end
  2135. else
  2136. begin
  2137. BlockRender;
  2138. FGuiCheckedComponent := nil;
  2139. ReBuildGui := True;
  2140. GUIRedraw := True;
  2141. UnBlockRender;
  2142. end;
  2143. end;
  2144. inherited;
  2145. end;
  2146. procedure TGLButton.SetPressed(NewPressed: Boolean);
  2147. begin
  2148. if FPressed <> NewPressed then
  2149. begin
  2150. BlockRender;
  2151. try
  2152. if NewPressed then
  2153. if Group >= 0 then
  2154. UnpressGroup(RootControl, Group);
  2155. FPressed := NewPressed;
  2156. finally
  2157. UnBlockRender;
  2158. end;
  2159. if FPressed then
  2160. if Assigned(FOnButtonClick) then
  2161. FOnButtonClick(Self);
  2162. NotifyChange(Self);
  2163. end;
  2164. end;
  2165. procedure TGLButton.InternalMouseDown(Shift: TShiftState; Button:
  2166. TMouseButton; X, Y: Integer);
  2167. begin
  2168. SetFocus;
  2169. inherited;
  2170. if Button = mbLeft then
  2171. if AllowUp then
  2172. Pressed := not Pressed
  2173. else
  2174. Pressed := True;
  2175. end;
  2176. procedure TGLButton.InternalMouseUp(Shift: TShiftState; Button: TMouseButton;
  2177. X, Y: Integer);
  2178. begin
  2179. if (Button = mbLeft) and (Group < 0) then
  2180. Pressed := False;
  2181. inherited;
  2182. end;
  2183. procedure TGLButton.InternalKeyDown(var Key: Word; Shift: TShiftState);
  2184. begin
  2185. inherited;
  2186. if Key = VK_SPACE then
  2187. begin
  2188. Pressed := True;
  2189. end;
  2190. if Key = VK_RETURN then
  2191. begin
  2192. Pressed := True;
  2193. end;
  2194. end;
  2195. procedure TGLButton.InternalKeyUp(var Key: Word; Shift: TShiftState);
  2196. begin
  2197. if ((Key = VK_SPACE) or (Key = VK_RETURN)) and (Group < 0) then
  2198. begin
  2199. Pressed := False;
  2200. end;
  2201. inherited;
  2202. end;
  2203. procedure TGLButton.SetFocused(Value: Boolean);
  2204. begin
  2205. inherited;
  2206. if (not FFocused) and (Group < 0) then
  2207. Pressed := False;
  2208. end;
  2209. procedure TGLButton.SetGuiLayoutNamePressed(const newName: TGLGuiComponentName);
  2210. begin
  2211. if FGuiLayoutNamePressed <> NewName then
  2212. begin
  2213. FGuiPressedComponent := nil;
  2214. FGuiLayoutNamePressed := NewName;
  2215. if Assigned(FGuiLayout) then
  2216. begin
  2217. FGuiPressedComponent :=
  2218. FGuiLayout.GuiComponents.FindItem(FGuiLayoutNamePressed);
  2219. FReBuildGui := True;
  2220. GUIRedraw := True;
  2221. end;
  2222. end;
  2223. end;
  2224. procedure TGLButton.SetGuiLayout(NewGui: TGLGuiLayout);
  2225. begin
  2226. FGuiPressedComponent := nil;
  2227. inherited;
  2228. if Assigned(FGuiLayout) then
  2229. begin
  2230. FGuiPressedComponent :=
  2231. FGuiLayout.GuiComponents.FindItem(FGuiLayoutNamePressed);
  2232. FReBuildGui := True;
  2233. GUIRedraw := True;
  2234. end;
  2235. end;
  2236. procedure TGLButton.SetBitBtn(AValue: TGLMaterial);
  2237. begin
  2238. FBitBtn.Assign(AValue);
  2239. NotifyChange(Self);
  2240. end;
  2241. procedure TGLButton.DestroyHandle;
  2242. begin
  2243. inherited;
  2244. FBitBtn.DestroyHandles;
  2245. end;
  2246. procedure TGLButton.SetGroup(const val: Integer);
  2247. begin
  2248. FGroup := val;
  2249. if Pressed then
  2250. begin
  2251. BlockRender;
  2252. FPressed := False;
  2253. UnpressGroup(RootControl, Group);
  2254. FPressed := True;
  2255. UnBlockRender;
  2256. end;
  2257. end;
  2258. procedure TGLButton.SetLogicWidth(const val: single);
  2259. begin
  2260. FLogicWidth := val;
  2261. NotifyChange(Self);
  2262. end;
  2263. procedure TGLButton.SetLogicHeight(const val: single);
  2264. begin
  2265. FLogicHeight := val;
  2266. NotifyChange(Self);
  2267. end;
  2268. procedure TGLButton.SetXOffset(const val: single);
  2269. begin
  2270. FXOffSet := val;
  2271. NotifyChange(Self);
  2272. end;
  2273. procedure TGLButton.SetYOffset(const val: single);
  2274. begin
  2275. FYOffSet := val;
  2276. NotifyChange(Self);
  2277. end;
  2278. constructor TGLButton.Create(AOwner: TComponent);
  2279. begin
  2280. inherited Create(AOwner);
  2281. FBitBtn := TGLMaterial.Create(Self);
  2282. FGroup := -1;
  2283. FPressed := False;
  2284. end;
  2285. destructor TGLButton.Destroy;
  2286. begin
  2287. inherited Destroy;
  2288. FBitBtn.Free;
  2289. end;
  2290. procedure TGLButton.InternalRender(var rci: TGLRenderContextInfo; renderSelf,
  2291. renderChildren: Boolean);
  2292. var
  2293. B: Boolean;
  2294. TexWidth: Integer;
  2295. TexHeight: Integer;
  2296. Material: TGLMaterial;
  2297. LibMaterial: TGLLibMaterial;
  2298. TextColor: TGLColorVector;
  2299. begin
  2300. if Pressed then
  2301. begin
  2302. if Assigned(FGuiPressedComponent) then
  2303. begin
  2304. FGuiPressedComponent.RenderToArea(0, 0, Width, Height, FRenderStatus,
  2305. FReBuildGui);
  2306. end;
  2307. end
  2308. else
  2309. begin
  2310. if Assigned(FGuiComponent) then
  2311. begin
  2312. FGuiComponent.RenderToArea(0, 0, Width, Height, FRenderStatus,
  2313. FReBuildGui);
  2314. end;
  2315. end;
  2316. B := not BitBtn.Texture.Disabled;
  2317. Material := nil;
  2318. if not B then
  2319. begin
  2320. if (BitBtn.MaterialLibrary <> nil) and (BitBtn.MaterialLibrary is
  2321. TGLMaterialLibrary) then
  2322. begin
  2323. LibMaterial :=
  2324. TGLMaterialLibrary(BitBtn.MaterialLibrary).Materials.GetLibMaterialByName(BitBtn.LibMaterialName);
  2325. if LibMaterial <> nil then
  2326. begin
  2327. Material := LibMaterial.Material;
  2328. B := True;
  2329. end;
  2330. end;
  2331. end
  2332. else
  2333. begin
  2334. Material := BitBtn;
  2335. end;
  2336. if B then
  2337. with FRenderStatus[GLAlCenter] do
  2338. begin
  2339. GuiLayout.Material.UnApply(rci);
  2340. BitBtn.Apply(rci);
  2341. TexWidth := Material.Texture.TexWidth;
  2342. if TexWidth = 0 then
  2343. TexWidth := Material.Texture.Image.Width;
  2344. TexHeight := Material.Texture.TexHeight;
  2345. if TexHeight = 0 then
  2346. TexHeight := Material.Texture.Image.Height;
  2347. gl.Begin_(GL_QUADS);
  2348. gl.TexCoord2f(0, 0);
  2349. gl.Vertex2f(X1 - XOffSet, -Y1 + YOffSet);
  2350. gl.TexCoord2f(0, -(LogicHeight - 1) / TexHeight);
  2351. gl.Vertex2f(X1 - XOffSet, -Y1 + YOffset - LogicHeight + 1);
  2352. gl.TexCoord2f((LogicWidth - 1) / TexWidth, -(LogicHeight - 1) /
  2353. TexHeight);
  2354. gl.Vertex2f(X1 - XOffSet + LogicWidth - 1, -Y1 + YOffset - LogicHeight +
  2355. 1);
  2356. gl.TexCoord2f((LogicWidth - 1) / TexWidth, 0);
  2357. gl.Vertex2f(X1 - XOffSet + LogicWidth - 1, -Y1 + YOffSet);
  2358. gl.End_();
  2359. BitBtn.UnApply(rci);
  2360. GuiLayout.Material.Apply(rci);
  2361. end;
  2362. if Assigned(BitmapFont) then
  2363. begin
  2364. if FFocused then
  2365. begin
  2366. TextColor := FFocusedColor;
  2367. end
  2368. else
  2369. begin
  2370. TextColor := FDefaultColor;
  2371. end;
  2372. TextColor.W := AlphaChannel;
  2373. WriteTextAt(rci, FRenderStatus[GLALCenter].X1,
  2374. FRenderStatus[GLALCenter].Y1,
  2375. FRenderStatus[GLALCenter].X2,
  2376. FRenderStatus[GLALCenter].Y2,
  2377. Caption,
  2378. TextColor);
  2379. end;
  2380. end;
  2381. procedure TGLEdit.InternalMouseDown(Shift: TShiftState; Button: TMouseButton;
  2382. X, Y: Integer);
  2383. begin
  2384. if not FReadOnly then
  2385. SetFocus;
  2386. inherited;
  2387. end;
  2388. procedure TGLEdit.InternalKeyPress(var Key: Char);
  2389. begin
  2390. if FReadOnly then
  2391. exit;
  2392. inherited;
  2393. case Key of
  2394. #8:
  2395. begin
  2396. if FSelStart > 1 then
  2397. begin
  2398. system.Delete(FCaption, FSelStart - 1, 1);
  2399. Dec(FSelStart);
  2400. GUIRedraw := True;
  2401. end;
  2402. end;
  2403. else
  2404. begin
  2405. if Key >= #32 then
  2406. begin
  2407. system.Insert(Key, FCaption, SelStart);
  2408. inc(FSelStart);
  2409. GUIRedraw := True;
  2410. end;
  2411. end;
  2412. end;
  2413. end;
  2414. procedure TGLEdit.InternalKeyDown(var Key: Word; Shift: TShiftState);
  2415. begin
  2416. if FReadOnly then
  2417. exit;
  2418. inherited;
  2419. case Key of
  2420. VK_DELETE:
  2421. begin
  2422. if FSelStart <= Length(Caption) then
  2423. begin
  2424. System.Delete(FCaption, FSelStart, 1);
  2425. GUIRedraw := True;
  2426. end;
  2427. end;
  2428. VK_LEFT:
  2429. begin
  2430. if FSelStart > 1 then
  2431. begin
  2432. Dec(FSelStart);
  2433. GUIRedraw := True;
  2434. end;
  2435. end;
  2436. VK_RIGHT:
  2437. begin
  2438. if FSelStart < Length(Caption) + 1 then
  2439. begin
  2440. Inc(FSelStart);
  2441. GUIRedraw := True;
  2442. end;
  2443. end;
  2444. VK_HOME:
  2445. begin
  2446. if FSelStart > 1 then
  2447. begin
  2448. FSelStart := 1;
  2449. GUIRedraw := True;
  2450. end;
  2451. end;
  2452. VK_END:
  2453. begin
  2454. if FSelStart < Length(Caption) + 1 then
  2455. begin
  2456. FSelStart := Length(Caption) + 1;
  2457. GUIRedraw := True;
  2458. end;
  2459. end;
  2460. end;
  2461. end;
  2462. procedure TGLEdit.InternalKeyUp(var Key: Word; Shift: TShiftState);
  2463. begin
  2464. inherited;
  2465. end;
  2466. procedure TGLEdit.SetFocused(Value: Boolean);
  2467. begin
  2468. inherited;
  2469. if Value then
  2470. SelStart := Length(Caption) + 1;
  2471. end;
  2472. procedure TGLEdit.SetSelStart(const Value: Integer);
  2473. begin
  2474. FSelStart := Value;
  2475. GUIRedraw := True;
  2476. end;
  2477. procedure TGLEdit.SetEditChar(const Value: string);
  2478. begin
  2479. FEditChar := Value;
  2480. GUIRedraw := True;
  2481. end;
  2482. constructor TGLEdit.Create(AOwner: TComponent);
  2483. begin
  2484. inherited;
  2485. FEditChar := '*';
  2486. end;
  2487. procedure TGLEdit.InternalRender(var rci: TGLRenderContextInfo; renderSelf,
  2488. renderChildren: Boolean);
  2489. var
  2490. Tekst: UnicodeString;
  2491. pBig: Integer;
  2492. begin
  2493. // Renders the background
  2494. if Assigned(FGuiComponent) then
  2495. begin
  2496. FGuiComponent.RenderToArea(0, 0, Width, Height, FRenderStatus, FReBuildGui);
  2497. end;
  2498. // Renders the text
  2499. if Assigned(FBitmapFont) then
  2500. begin
  2501. Tekst := Caption;
  2502. if FFocused then
  2503. begin
  2504. // First put in the edit character where it should be.
  2505. system.insert(FEditChar, Tekst, SelStart);
  2506. // Next figure out if the string is too long.
  2507. if FBitmapFont.CalcStringWidth(Tekst) > Width - 2 then
  2508. begin
  2509. // if it is then we need to check to see where SelStart is
  2510. if SelStart >= Length(Tekst) - 1 then
  2511. begin
  2512. // SelStart is within close proximity of the end of the string
  2513. // Calculate the % of text that we can use and return it against the length of the string.
  2514. pBig := Trunc(Int(((Width - 2) /
  2515. FBitmapFont.CalcStringWidth(Tekst)) * Length(Tekst)));
  2516. dec(pBig);
  2517. Tekst := Copy(Tekst, Length(Tekst) - pBig + 1, pBig);
  2518. end
  2519. else
  2520. begin
  2521. // SelStart is within close proximity of the end of the string
  2522. // Calculate the % of text that we can use and return it against the length of the string.
  2523. pBig := Trunc(Int(((Width - 2) /
  2524. FBitmapFont.CalcStringWidth(Tekst)) * Length(Tekst)));
  2525. dec(pBig);
  2526. if SelStart + pBig < Length(Tekst) then
  2527. Tekst := Copy(Tekst, SelStart, pBig)
  2528. else
  2529. Tekst := Copy(Tekst, Length(Tekst) - pBig + 1, pBig);
  2530. end;
  2531. end;
  2532. end
  2533. else
  2534. { if FFocused then } if FBitmapFont.CalcStringWidth(Tekst) >
  2535. Width - 2 then
  2536. begin
  2537. // The while loop should never execute more then once, but just in case its here.
  2538. while FBitmapFont.CalcStringWidth(Tekst) > Width - 2 do
  2539. begin
  2540. // Calculate the % of text that we can use and return it against the length of the string.
  2541. pBig := Trunc(Int(((Width - 2) /
  2542. FBitmapFont.CalcStringWidth(Tekst)) * Length(Tekst)));
  2543. Tekst := Copy(Tekst, 1, pBig);
  2544. end;
  2545. end;
  2546. if FFocused then
  2547. begin
  2548. WriteTextAt(rci, FRenderStatus[GLAlLeft].X1, FRenderStatus[GLAlCenter].Y1,
  2549. FRenderStatus[GLALCenter].X2, FRenderStatus[GLALCenter].Y2, Tekst,
  2550. FFocusedColor);
  2551. end
  2552. else
  2553. begin
  2554. WriteTextAt(rci, FRenderStatus[GLAlLeft].X1, FRenderStatus[GLAlCenter].Y1,
  2555. FRenderStatus[GLALCenter].X2, FRenderStatus[GLALCenter].Y2, Tekst,
  2556. FDefaultColor);
  2557. end;
  2558. end;
  2559. end;
  2560. constructor TGLLabel.Create(AOwner: TComponent);
  2561. begin
  2562. inherited;
  2563. FTextLayout := tlCenter;
  2564. end;
  2565. procedure TGLLabel.InternalRender(var rci: TGLRenderContextInfo; renderSelf,
  2566. renderChildren: Boolean);
  2567. var
  2568. TekstPos: TGLVector;
  2569. Tekst: UnicodeString;
  2570. TextColor: TGLColorVector;
  2571. begin
  2572. if Assigned(BitmapFont) then
  2573. begin
  2574. case Alignment of
  2575. taLeftJustify:
  2576. TekstPos.X := 0;
  2577. taCenter:
  2578. TekstPos.X := Width / 2;
  2579. taRightJustify:
  2580. TekstPos.X := Width;
  2581. end;
  2582. case TextLayout of
  2583. tlTop:
  2584. TekstPos.Y := 0;
  2585. tlCenter:
  2586. TekstPos.Y := Round(-Height / 2);
  2587. tlBottom:
  2588. TekstPos.Y := -Height;
  2589. end;
  2590. TekstPos.Z := 0;
  2591. TekstPos.W := 0;
  2592. Tekst := Caption;
  2593. TextColor := FDefaultColor;
  2594. TextColor.W := AlphaChannel;
  2595. BitmapFont.RenderString(rci, Tekst, FAlignment, FTextLayout, TextColor,
  2596. @TekstPos);
  2597. end;
  2598. end;
  2599. procedure TGLLabel.SetAlignment(const Value: TAlignment);
  2600. begin
  2601. if FAlignment <> Value then
  2602. begin
  2603. FAlignment := Value;
  2604. NotifyChange(Self);
  2605. end;
  2606. end;
  2607. procedure TGLLabel.SetTextLayout(const Value: TTextLayout);
  2608. begin
  2609. if FTextLayout <> Value then
  2610. begin
  2611. FTextLayout := Value;
  2612. NotifyChange(Self);
  2613. end;
  2614. end;
  2615. procedure TGLAdvancedLabel.InternalRender(var rci: TGLRenderContextInfo;
  2616. renderSelf, renderChildren: Boolean);
  2617. begin
  2618. if Assigned(BitmapFont) then
  2619. begin
  2620. if Focused then
  2621. begin
  2622. WriteTextAt(rci, 8, -((Height - GetFontHeight) / 2) + 1, Caption,
  2623. FFocusedColor);
  2624. end
  2625. else
  2626. begin
  2627. WriteTextAt(rci, 8, -((Height - GetFontHeight) / 2) + 1, Caption,
  2628. FDefaultColor);
  2629. end;
  2630. end;
  2631. end;
  2632. procedure TGLScrollbar.SetMin(const val: Single);
  2633. begin
  2634. if FMin <> val then
  2635. begin
  2636. FMin := val;
  2637. if FPos < FMin then
  2638. Pos := FMin;
  2639. NotifyChange(Self);
  2640. end;
  2641. end;
  2642. procedure TGLScrollbar.SetMax(const val: Single);
  2643. begin
  2644. if FMax <> val then
  2645. begin
  2646. FMax := val;
  2647. if FMax < FMin then
  2648. FMax := FMin;
  2649. if FPos > (FMax - FPageSize + 1) then
  2650. Pos := (FMax - FPageSize + 1);
  2651. NotifyChange(Self);
  2652. end;
  2653. end;
  2654. procedure TGLScrollbar.SetPos(const val: Single);
  2655. begin
  2656. if FPos <> val then
  2657. begin
  2658. FPos := val;
  2659. if FPos < FMin then
  2660. FPos := FMin;
  2661. if FPos > (FMax - FPageSize + 1) then
  2662. FPos := (FMax - FPageSize + 1);
  2663. NotifyChange(Self);
  2664. if Assigned(FOnChange) then
  2665. FOnChange(Self);
  2666. end;
  2667. end;
  2668. procedure TGLScrollbar.SetPageSize(const val: Single);
  2669. begin
  2670. if FPageSize <> val then
  2671. begin
  2672. FPageSize := val;
  2673. if FPos > (FMax - FPageSize + 1) then
  2674. Pos := (FMax - FPageSize + 1);
  2675. NotifyChange(Self);
  2676. end;
  2677. end;
  2678. procedure TGLScrollbar.SetHorizontal(const val: Boolean);
  2679. begin
  2680. if FHorizontal <> val then
  2681. begin
  2682. FHorizontal := val;
  2683. NotifyChange(Self);
  2684. end;
  2685. end;
  2686. procedure TGLScrollbar.SetGuiLayoutKnobName(const newName: TGLGuiComponentName);
  2687. begin
  2688. if newName <> FGuiLayoutKnobName then
  2689. begin
  2690. FGuiKnobComponent := nil;
  2691. FGuiLayoutKnobName := NewName;
  2692. if Assigned(FGuiLayout) then
  2693. begin
  2694. FGuiKnobComponent :=
  2695. FGuiLayout.GuiComponents.FindItem(FGuiLayoutKnobName);
  2696. FReBuildGui := True;
  2697. GUIRedraw := True;
  2698. end;
  2699. end;
  2700. end;
  2701. procedure TGLScrollbar.SetGuiLayout(NewGui: TGLGuiLayout);
  2702. begin
  2703. FGuiKnobComponent := nil;
  2704. inherited;
  2705. if Assigned(FGuiLayout) then
  2706. begin
  2707. FGuiKnobComponent := FGuiLayout.GuiComponents.FindItem(FGuiLayoutKnobName);
  2708. FReBuildGui := True;
  2709. GUIRedraw := True;
  2710. end;
  2711. end;
  2712. function TGLScrollbar.GetScrollPosY(ScrollPos: Single): Single;
  2713. begin
  2714. with FRenderStatus[GLAlCenter] do
  2715. begin
  2716. Result := (ScrollPos - FMin) / (FMax - FMin) * (Y2 - Y1) + Y1;
  2717. end;
  2718. end;
  2719. function TGLScrollbar.GetYScrollPos(Y: Single): Single;
  2720. begin
  2721. with FRenderStatus[GLAlCenter] do
  2722. begin
  2723. Result := (Y - Y1) / (Y2 - Y1) * (FMax - FMin) + FMin;
  2724. end;
  2725. end;
  2726. function TGLScrollbar.GetScrollPosX(ScrollPos: Single): Single;
  2727. begin
  2728. with FRenderStatus[GLAlCenter] do
  2729. begin
  2730. Result := (ScrollPos - FMin) / (FMax - FMin) * (X2 - X1) + X1;
  2731. end;
  2732. end;
  2733. function TGLScrollbar.GetXScrollPos(X: Single): Single;
  2734. begin
  2735. with FRenderStatus[GLAlCenter] do
  2736. begin
  2737. Result := (X - X1) / (X2 - X1) * (FMax - FMin) + FMin;
  2738. end;
  2739. end;
  2740. procedure TGLScrollbar.InternalMouseDown(Shift: TShiftState; Button:
  2741. TMouseButton; X, Y: Integer);
  2742. var
  2743. Tx, Ty: Single;
  2744. begin
  2745. if (Button = mbLeft)
  2746. and not FLocked then
  2747. begin
  2748. Tx := x - Position.X;
  2749. Ty := y - Position.Y;
  2750. // is in mid area ?
  2751. if IsInRect(FRenderStatus[GLAlCenter], Tx, Ty) then
  2752. begin
  2753. if FHorizontal then
  2754. begin
  2755. Tx := GetxScrollPos(Tx);
  2756. if Tx < FPos then
  2757. PageUp
  2758. else if Tx > FPos + FPageSize - 1 then
  2759. PageDown
  2760. else
  2761. begin
  2762. fScrolling := True;
  2763. FScrollOffs := Tx - FPos;
  2764. RootControl.ActiveControl := Self;
  2765. end;
  2766. end
  2767. else
  2768. begin
  2769. Ty := GetYScrollPos(Ty);
  2770. if Ty < FPos then
  2771. PageUp
  2772. else if Ty > FPos + FPageSize - 1 then
  2773. PageDown
  2774. else
  2775. begin
  2776. fScrolling := True;
  2777. FScrollOffs := Ty - FPos;
  2778. RootControl.ActiveControl := Self;
  2779. end;
  2780. end;
  2781. end
  2782. else
  2783. begin
  2784. // if not, is at end buttons ?
  2785. if horizontal then
  2786. begin
  2787. if IsInRect(FRenderStatus[GLAlLeft], Tx, Ty) then
  2788. StepUp;
  2789. if IsInRect(FRenderStatus[GLAlRight], Tx, Ty) then
  2790. StepDown;
  2791. end
  2792. else
  2793. begin
  2794. if IsInRect(FRenderStatus[GLAlTop], Tx, Ty) then
  2795. StepUp;
  2796. if IsInRect(FRenderStatus[GLAlBottom], Tx, Ty) then
  2797. StepDown;
  2798. end;
  2799. end;
  2800. end;
  2801. inherited;
  2802. end;
  2803. procedure TGLScrollbar.InternalMouseUp(Shift: TShiftState; Button:
  2804. TMouseButton; X, Y: Integer);
  2805. begin
  2806. if fScrolling then
  2807. begin
  2808. fScrolling := False;
  2809. RootControl.ActiveControl := nil;
  2810. end;
  2811. inherited;
  2812. end;
  2813. procedure TGLScrollbar.InternalMouseMove(Shift: TShiftState; X, Y: Integer);
  2814. var
  2815. Tx: Single;
  2816. Ty: Single;
  2817. begin
  2818. if fScrolling then
  2819. if FHorizontal then
  2820. begin
  2821. Tx := GetXScrollPos(x - Position.X) - FScrollOffs;
  2822. Pos := Round(Tx);
  2823. end
  2824. else
  2825. begin
  2826. Ty := GetYScrollPos(y - Position.Y) - FScrollOffs;
  2827. Pos := Round(Ty);
  2828. end;
  2829. inherited;
  2830. end;
  2831. constructor TGLScrollbar.Create(AOwner: TComponent);
  2832. begin
  2833. inherited;
  2834. FGuiKnobComponent := nil;
  2835. FMin := 1;
  2836. FMax := 10;
  2837. FPos := 1;
  2838. FStep := 1;
  2839. FPageSize := 3;
  2840. FOnChange := nil;
  2841. FGuiLayoutKnobName := '';
  2842. FScrollOffs := 0;
  2843. FScrolling := False;
  2844. FHorizontal := False;
  2845. end;
  2846. procedure TGLScrollbar.StepUp;
  2847. begin
  2848. Pos := Pos - FStep;
  2849. end;
  2850. procedure TGLScrollbar.StepDown;
  2851. begin
  2852. Pos := Pos + FStep;
  2853. end;
  2854. procedure TGLScrollbar.PageUp;
  2855. begin
  2856. Pos := Pos - FPageSize;
  2857. end;
  2858. procedure TGLScrollbar.PageDown;
  2859. begin
  2860. Pos := Pos + FPageSize;
  2861. end;
  2862. function TGLScrollbar.MouseUp(Sender: TObject; Button: TMouseButton; Shift:
  2863. TShiftState; X, Y: Integer): Boolean;
  2864. begin
  2865. if (Button = mbLeft) and (FScrolling) then
  2866. begin
  2867. Result := True;
  2868. InternalMouseUp(Shift, Button, X, Y);
  2869. end
  2870. else
  2871. Result := inherited MouseUp(Sender, Button, Shift, X, Y);
  2872. end;
  2873. function TGLScrollbar.MouseMove(Sender: TObject; Shift: TShiftState; X, Y:
  2874. Integer): Boolean;
  2875. begin
  2876. if (FScrolling) then
  2877. begin
  2878. Result := True;
  2879. InternalMouseMove(Shift, X, Y);
  2880. end
  2881. else
  2882. Result := inherited MouseMove(Sender, Shift, X, Y);
  2883. end;
  2884. procedure TGLScrollbar.InternalRender(var rci: TGLRenderContextInfo; renderSelf,
  2885. renderChildren: Boolean);
  2886. var
  2887. Start, Size: Integer;
  2888. begin
  2889. if Assigned(FGuiComponent) then
  2890. begin
  2891. try
  2892. FGuiComponent.RenderToArea(0, 0, Width, Height, FRenderStatus,
  2893. FReBuildGui);
  2894. except
  2895. on E: Exception do
  2896. GLOKMessageBox(E.Message,
  2897. 'Exception in GuiComponents InternalRender function');
  2898. end;
  2899. end;
  2900. if Assigned(FGuiKnobComponent) then
  2901. begin
  2902. try
  2903. with FRenderStatus[GLAlCenter] do
  2904. begin
  2905. if FHorizontal then
  2906. begin
  2907. Start := Round(GetScrollPosX(FPos));
  2908. if FPageSize + FPos > FMax + 1 then
  2909. Size := Round(GetScrollPosX(FMax) - X1)
  2910. else
  2911. Size := Round(GetScrollPosX(FPageSize) - X1);
  2912. FGuiKnobComponent.RenderToArea(Start, Y1, Start + Size, Y2,
  2913. FKnobRenderStatus, True);
  2914. // Tag := start;
  2915. // tagfloat := size;
  2916. end
  2917. else
  2918. begin
  2919. Start := Round(GetScrollPosY(FPos));
  2920. if FPageSize + FPos > FMax + 1 then
  2921. Size := Round(GetScrollPosY(FMax) - Y1)
  2922. else
  2923. Size := Round(GetScrollPosY(FPageSize) - Y1);
  2924. FGuiKnobComponent.RenderToArea(X1, Start, X2, Start + Size,
  2925. FKnobRenderStatus, True);
  2926. // Tag := start;
  2927. // tagfloat := size;
  2928. end;
  2929. end;
  2930. except
  2931. on E: Exception do
  2932. GLOKMessageBox(E.Message,
  2933. 'Exception in GuiComponents InternalRender function');
  2934. end;
  2935. end;
  2936. end;
  2937. function TGLStringGrid.GetCell(X, Y: Integer; out oCol, oRow: Integer): Boolean;
  2938. var
  2939. ClientRect: TRectangle;
  2940. XPos: Integer;
  2941. YPos: Integer;
  2942. XC, YC: Integer;
  2943. begin
  2944. Result := False;
  2945. if Assigned(BitmapFont) then
  2946. begin
  2947. if Assigned(FGuiComponent) then
  2948. begin
  2949. ClientRect.Left := Round(FRenderStatus[GLAlCenter].X1);
  2950. ClientRect.Top := Round(FRenderStatus[GLAlCenter].Y1);
  2951. ClientRect.Width := Round(FRenderStatus[GLAlCenter].X2);
  2952. ClientRect.Height := Round(FRenderStatus[GLAlCenter].Y2);
  2953. end
  2954. else
  2955. begin
  2956. ClientRect.Left := 0;
  2957. ClientRect.Top := 0;
  2958. ClientRect.Width := Round(Width);
  2959. ClientRect.Height := Round(Height);
  2960. end;
  2961. YPos := ClientRect.Top;
  2962. if FDrawHeader then
  2963. YPos := YPos + RowHeight;
  2964. XPos := ClientRect.Left;
  2965. if y < YPos then
  2966. Exit;
  2967. if x < XPos then
  2968. Exit;
  2969. XPos := XPos + MarginSize;
  2970. for XC := 0 to Columns.Count - 1 do
  2971. begin
  2972. XPos := XPos + Integer(Columns.Objects[XC]);
  2973. if x > XPos then
  2974. continue;
  2975. for YC := 0 to RowCount - 1 do
  2976. begin
  2977. YPos := YPos + RowHeight;
  2978. if y < YPos then
  2979. begin
  2980. Result := True;
  2981. if Assigned(Scrollbar) then
  2982. oRow := YC + Round(Scrollbar.Pos) - 1
  2983. else
  2984. oRow := YC;
  2985. oCol := XC;
  2986. Exit;
  2987. end;
  2988. end;
  2989. end;
  2990. end;
  2991. end;
  2992. procedure TGLStringGrid.InternalMouseDown(Shift: TShiftState; Button:
  2993. TMouseButton; X, Y: Integer);
  2994. var
  2995. tRow, tCol: Integer;
  2996. begin
  2997. SetFocus;
  2998. if GetCell(Round(X - Position.X), Round(Y - Position.Y), tCol, tRow) then
  2999. begin
  3000. SelCol := tCol;
  3001. SelRow := tRow;
  3002. end;
  3003. inherited;
  3004. end;
  3005. procedure TGLStringGrid.SetColumns(const val: TStrings);
  3006. var
  3007. XC: Integer;
  3008. begin
  3009. FColumns.Assign(val);
  3010. for XC := 0 to Columns.Count - 1 do
  3011. Columns.Objects[XC] := TObject(ColumnSize);
  3012. end;
  3013. procedure TGLStringGrid.SetColSelect(const val: Boolean);
  3014. begin
  3015. FColSelect := Val;
  3016. NotifyChange(Self);
  3017. end;
  3018. function TGLStringGrid.GetRow(index: Integer): TStringList;
  3019. begin
  3020. if (index >= 0) and (index < FRows.Count) then
  3021. Result := TStringList(FRows[index])
  3022. else
  3023. Result := nil;
  3024. end;
  3025. procedure TGLStringGrid.SetRow(index: Integer; const val: TStringList);
  3026. begin
  3027. if (index >= 0) then
  3028. begin
  3029. if (index >= RowCount) then
  3030. RowCount := index + 1;
  3031. TStringList(FRows[index]).Assign(val);
  3032. end;
  3033. end;
  3034. function TGLStringGrid.GetRowCount: Integer;
  3035. begin
  3036. Result := FRows.count;
  3037. end;
  3038. procedure TGLStringGrid.SetRowCount(const val: Integer);
  3039. var
  3040. XC: Integer;
  3041. begin
  3042. XC := FRows.count;
  3043. if val <> XC then
  3044. begin
  3045. if val > XC then
  3046. begin
  3047. FRows.count := val;
  3048. for XC := XC to val - 1 do
  3049. begin
  3050. FRows[XC] := TStringList.Create;
  3051. TStringList(FRows[XC]).OnChange := OnStringListChange;
  3052. end;
  3053. end
  3054. else
  3055. begin
  3056. for XC := XC - 1 downto val do
  3057. begin
  3058. TStringList(FRows[XC]).Free;
  3059. end;
  3060. FRows.count := val;
  3061. end;
  3062. if Assigned(Scrollbar) then
  3063. Scrollbar.FMax := FRows.Count;
  3064. NotifyChange(Self);
  3065. end;
  3066. end;
  3067. procedure TGLStringGrid.SetSelCol(const val: Integer);
  3068. begin
  3069. if FSelCol <> Val then
  3070. begin
  3071. FSelCol := Val;
  3072. NotifyChange(Self);
  3073. end;
  3074. end;
  3075. procedure TGLStringGrid.SetSelRow(const val: Integer);
  3076. begin
  3077. if FSelRow <> Val then
  3078. begin
  3079. FSelRow := Val;
  3080. NotifyChange(Self);
  3081. end;
  3082. end;
  3083. procedure TGLStringGrid.SetRowSelect(const val: Boolean);
  3084. begin
  3085. FRowSelect := Val;
  3086. NotifyChange(Self);
  3087. end;
  3088. procedure TGLStringGrid.SetDrawHeader(const val: Boolean);
  3089. begin
  3090. FDrawHeader := Val;
  3091. NotifyChange(Self);
  3092. end;
  3093. function TGLStringGrid.GetHeaderColor: TColor;
  3094. begin
  3095. Result := ConvertColorVector(FHeaderColor);
  3096. end;
  3097. procedure TGLStringGrid.SetHeaderColor(const val: TColor);
  3098. begin
  3099. FHeaderColor := ConvertWinColor(val);
  3100. GUIRedraw := True;
  3101. end;
  3102. procedure TGLStringGrid.SetMarginSize(const val: Integer);
  3103. begin
  3104. if FMarginSize <> val then
  3105. begin
  3106. FMarginSize := val;
  3107. GUIRedraw := True;
  3108. end;
  3109. end;
  3110. procedure TGLStringGrid.SetColumnSize(const val: Integer);
  3111. var
  3112. XC: Integer;
  3113. begin
  3114. if FColumnSize <> val then
  3115. begin
  3116. FColumnSize := val;
  3117. for XC := 0 to Columns.Count - 1 do
  3118. Columns.Objects[XC] := TObject(ColumnSize);
  3119. GUIRedraw := True;
  3120. end;
  3121. end;
  3122. procedure TGLStringGrid.SetRowHeight(const val: Integer);
  3123. begin
  3124. if FRowHeight <> val then
  3125. begin
  3126. FRowHeight := val;
  3127. GUIRedraw := True;
  3128. end;
  3129. end;
  3130. procedure TGLStringGrid.SetScrollbar(const val: TGLScrollbar);
  3131. begin
  3132. if FScrollbar <> Val then
  3133. begin
  3134. if Assigned(FScrollbar) then
  3135. FScrollbar.RemoveFreeNotification(Self);
  3136. FScrollbar := Val;
  3137. if Assigned(FScrollbar) then
  3138. FScrollbar.FreeNotification(Self);
  3139. end;
  3140. end;
  3141. procedure TGLStringGrid.SetGuiLayout(NewGui: TGLGuiLayout);
  3142. begin
  3143. inherited;
  3144. if Assigned(Scrollbar) then
  3145. if Scrollbar.GuiLayout <> nil then
  3146. Scrollbar.GuiLayout := NewGui;
  3147. end;
  3148. constructor TGLStringGrid.Create(AOwner: TComponent);
  3149. begin
  3150. inherited;
  3151. FRows := TList.Create;
  3152. FColumns := TStringList.Create;
  3153. TStringList(FColumns).OnChange := OnStringListChange;
  3154. FSelCol := 0;
  3155. FSelRow := 0;
  3156. FRowSelect := True;
  3157. FScrollbar := nil;
  3158. FDrawHeader := True;
  3159. end;
  3160. destructor TGLStringGrid.Destroy;
  3161. begin
  3162. Scrollbar := nil;
  3163. inherited;
  3164. Clear;
  3165. FRows.Free;
  3166. FColumns.Free;
  3167. end;
  3168. procedure TGLStringGrid.Clear;
  3169. begin
  3170. RowCount := 0;
  3171. end;
  3172. procedure TGLStringGrid.Notification(AComponent: TComponent; Operation:
  3173. TOperation);
  3174. begin
  3175. if (AComponent = FScrollbar) and (Operation = opRemove) then
  3176. begin
  3177. FScrollbar := nil;
  3178. end;
  3179. inherited;
  3180. end;
  3181. procedure TGLStringGrid.NotifyChange(Sender: TObject);
  3182. begin
  3183. if Sender = Scrollbar then
  3184. begin
  3185. ReBuildGui := True;
  3186. GUIRedraw := True;
  3187. end;
  3188. inherited;
  3189. end;
  3190. procedure TGLStringGrid.InternalRender(var rci: TGLRenderContextInfo; renderSelf,
  3191. renderChildren: Boolean);
  3192. function CellSelected(X, Y: Integer): Boolean;
  3193. begin
  3194. if (RowSelect and ColSelect) then
  3195. Result := (Y = SelRow) or (x = SelCol)
  3196. else if RowSelect then
  3197. Result := Y = SelRow
  3198. else if ColSelect then
  3199. Result := X = SelCol
  3200. else
  3201. Result := (Y = SelRow) and (x = SelCol);
  3202. end;
  3203. function CellText(X, Y: Integer): string;
  3204. begin
  3205. with Row[y] do
  3206. if (X >= 0) and (X < Count) then
  3207. Result := strings[x]
  3208. else
  3209. Result := '';
  3210. end;
  3211. var
  3212. ClientRect: TRectangle;
  3213. XPos: Integer;
  3214. YPos: Integer;
  3215. XC, YC: Integer;
  3216. From, Till: Integer;
  3217. begin
  3218. if Assigned(FGuiComponent) then
  3219. begin
  3220. try
  3221. FGuiComponent.RenderToArea(0, 0, Width, Height, FRenderStatus,
  3222. FReBuildGui);
  3223. ClientRect.Left := Round(FRenderStatus[GLAlCenter].X1);
  3224. ClientRect.Top := Round(FRenderStatus[GLAlCenter].Y1);
  3225. ClientRect.Width := Round(FRenderStatus[GLAlCenter].X2);
  3226. ClientRect.Height := Round(FRenderStatus[GLAlCenter].Y2);
  3227. except
  3228. on E: Exception do
  3229. GLOKMessageBox(E.Message,
  3230. 'Exception in GuiComponents InternalRender function');
  3231. end;
  3232. end
  3233. else
  3234. begin
  3235. ClientRect.Left := 0;
  3236. ClientRect.Top := 0;
  3237. ClientRect.Width := Round(Width);
  3238. ClientRect.Height := Round(Height);
  3239. end;
  3240. if Assigned(BitmapFont) then
  3241. begin
  3242. XPos := ClientRect.Left + MarginSize;
  3243. if Assigned(Scrollbar) then
  3244. begin
  3245. Scrollbar.Position.X := Position.X + FRenderStatus[GLAlCenter].X2 -
  3246. Scrollbar.Width;
  3247. Scrollbar.Position.Y := Position.Y + FRenderStatus[GLAlCenter].Y1;
  3248. Scrollbar.Height := FRenderStatus[GLAlCenter].Y2 -
  3249. FRenderStatus[GLAlCenter].Y1;
  3250. XC := (ClientRect.Height - ClientRect.Top);
  3251. if FDrawHeader then
  3252. YC := (XC div RowHeight) - 1
  3253. else
  3254. YC := (XC div RowHeight);
  3255. Scrollbar.PageSize := YC;
  3256. From := Round(Scrollbar.pos - 1);
  3257. Till := Round(Scrollbar.pageSize + From - 1);
  3258. if Till > RowCount - 1 then
  3259. Till := RowCount - 1;
  3260. end
  3261. else
  3262. begin
  3263. From := 0;
  3264. Till := RowCount - 1;
  3265. end;
  3266. for XC := 0 to Columns.Count - 1 do
  3267. begin
  3268. YPos := -ClientRect.Top;
  3269. if FDrawHeader then
  3270. begin
  3271. WriteTextAt(rci, XPos, YPos, Columns[XC], FHeaderColor);
  3272. YPos := YPos - RowHeight;
  3273. end;
  3274. for YC := From to Till do
  3275. begin
  3276. if CellSelected(XC, YC) then
  3277. WriteTextAt(rci, XPos, YPos, CellText(XC, YC), FFocusedColor)
  3278. else
  3279. WriteTextAt(rci, XPos, YPos, CellText(XC, YC), FDefaultColor);
  3280. YPos := YPos - RowHeight;
  3281. end;
  3282. XPos := XPos + Integer(Columns.Objects[XC]);
  3283. end;
  3284. end;
  3285. end;
  3286. procedure TGLStringGrid.OnStringListChange(Sender: TObject);
  3287. begin
  3288. NotifyChange(Self);
  3289. end;
  3290. function TGLStringGrid.Add(const Data: array of string): Integer;
  3291. var
  3292. XC: Integer;
  3293. begin
  3294. Result := RowCount;
  3295. RowCount := RowCount + 1;
  3296. for XC := 0 to Length(Data) - 1 do
  3297. Row[Result].Add(Data[XC]);
  3298. end;
  3299. function TGLStringGrid.Add(const Data: string): Integer;
  3300. begin
  3301. Result := Add([Data]);
  3302. if Assigned(Scrollbar) then
  3303. begin
  3304. if Result > Round(Scrollbar.pageSize + Scrollbar.pos - 2) then
  3305. Scrollbar.pos := Result - Scrollbar.pageSize + 2;
  3306. end;
  3307. end;
  3308. procedure TGLStringGrid.SetText(Data: string);
  3309. var
  3310. Posi: Integer;
  3311. begin
  3312. Clear;
  3313. while Data <> '' do
  3314. begin
  3315. Posi := Pos(#13#10, Data);
  3316. if Posi > 0 then
  3317. begin
  3318. Add(Copy(Data, 1, Posi - 1));
  3319. Delete(Data, 1, Posi + 1);
  3320. end
  3321. else
  3322. begin
  3323. Add(Data);
  3324. Data := '';
  3325. end;
  3326. end;
  3327. end;
  3328. destructor TGLFocusControl.Destroy;
  3329. begin
  3330. if Focused then
  3331. RootControl.FocusedControl := nil;
  3332. inherited;
  3333. end;
  3334. procedure TGLBaseComponent.DoProgress(const progressTime: TGLProgressTimes);
  3335. begin
  3336. inherited;
  3337. if FDoChangesOnProgress then
  3338. DoChanges;
  3339. end;
  3340. procedure TGLBaseComponent.SetDoChangesOnProgress(const Value: Boolean);
  3341. begin
  3342. FDoChangesOnProgress := Value;
  3343. end;
  3344. procedure TGLFocusControl.MoveTo(newParent: TGLBaseSceneObject);
  3345. begin
  3346. inherited;
  3347. ReGetRootControl;
  3348. end;
  3349. initialization //------------------------------------------------------------
  3350. RegisterClasses([TGLBaseControl, TGLPopupMenu, TGLForm, TGLPanel, TGLButton,
  3351. TGLCheckBox, TGLEdit, TGLLabel, TGLAdvancedLabel, TGLScrollbar, TGLStringGrid,
  3352. TGLCustomControl]);
  3353. end.