GLWindows.pas 98 KB

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