GLS.Windows.pas 94 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637
  1. //
  2. // The multimedia graphics platform GLScene https://github.com/glscene
  3. //
  4. unit GLS.Windows;
  5. (* OpenGL windows management classes and structures *)
  6. interface
  7. {$I GLScene.inc}
  8. uses
  9. Winapi.OpenGL,
  10. Winapi.Windows,
  11. System.Classes,
  12. System.SysUtils,
  13. System.Math,
  14. Vcl.StdCtrls,
  15. Vcl.Controls,
  16. Vcl.Graphics,
  17. GLS.OpenGLTokens,
  18. GLS.PersistentClasses,
  19. GLS.Strings,
  20. GLS.Coordinates,
  21. GLS.VectorTypes,
  22. GLS.Objects,
  23. GLS.State,
  24. GLS.Utils,
  25. GLS.Scene,
  26. GLS.HudObjects,
  27. GLS.Material,
  28. GLS.Context,
  29. GLS.BitmapFont,
  30. GLS.WindowsFont,
  31. GLS.VectorGeometry,
  32. GLS.Gui,
  33. GLS.Color,
  34. GLS.Texture,
  35. GLS.RenderContextInfo,
  36. GLS.BaseClasses;
  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: TMouseEvent;
  111. FOnMouseMove: TMouseMoveEvent;
  112. FOnMouseUp: TMouseEvent;
  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: TMouseEvent read FOnMouseDown write FOnMouseDown;
  144. property OnMouseMove: TMouseMoveEvent read FOnMouseMove write FOnMouseMove;
  145. property OnMouseUp: TMouseEvent 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: TGLColorVector;
  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: TGLColorVector); overload;
  161. procedure WriteTextAt(var rci: TGLRenderContextInfo; const X1, Y1, X2, Y2:
  162. TGLFloat; const Data: UnicodeString; const Color: TGLColorVector); 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: TGLColorVector;
  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: TGLColorVector;
  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: TGLColorVector;
  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: TGLColorVector);
  1529. var
  1530. Position: TGLVector;
  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: TGLColorVector);
  1543. var
  1544. Position: TGLVector;
  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: TGLColorVector;
  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: TGLColorVector;
  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: TGLVector;
  2568. Tekst: UnicodeString;
  2569. TextColor: TGLColorVector;
  2570. begin
  2571. if Assigned(BitmapFont) then
  2572. begin
  2573. case Alignment of
  2574. taLeftJustify:
  2575. TekstPos.X := 0;
  2576. taCenter:
  2577. TekstPos.X := Width / 2;
  2578. taRightJustify:
  2579. TekstPos.X := Width;
  2580. end;
  2581. case TextLayout of
  2582. tlTop:
  2583. TekstPos.Y := 0;
  2584. tlCenter:
  2585. TekstPos.Y := Round(-Height / 2);
  2586. tlBottom:
  2587. TekstPos.Y := -Height;
  2588. end;
  2589. TekstPos.Z := 0;
  2590. TekstPos.W := 0;
  2591. Tekst := Caption;
  2592. TextColor := FDefaultColor;
  2593. TextColor.W := AlphaChannel;
  2594. BitmapFont.RenderString(rci, Tekst, FAlignment, FTextLayout, TextColor,
  2595. @TekstPos);
  2596. end;
  2597. end;
  2598. procedure TGLLabel.SetAlignment(const Value: TAlignment);
  2599. begin
  2600. if FAlignment <> Value then
  2601. begin
  2602. FAlignment := Value;
  2603. NotifyChange(Self);
  2604. end;
  2605. end;
  2606. procedure TGLLabel.SetTextLayout(const Value: TTextLayout);
  2607. begin
  2608. if FTextLayout <> Value then
  2609. begin
  2610. FTextLayout := Value;
  2611. NotifyChange(Self);
  2612. end;
  2613. end;
  2614. procedure TGLAdvancedLabel.InternalRender(var rci: TGLRenderContextInfo;
  2615. renderSelf, renderChildren: Boolean);
  2616. begin
  2617. if Assigned(BitmapFont) then
  2618. begin
  2619. if Focused then
  2620. begin
  2621. WriteTextAt(rci, 8, -((Height - GetFontHeight) / 2) + 1, Caption,
  2622. FFocusedColor);
  2623. end
  2624. else
  2625. begin
  2626. WriteTextAt(rci, 8, -((Height - GetFontHeight) / 2) + 1, Caption,
  2627. FDefaultColor);
  2628. end;
  2629. end;
  2630. end;
  2631. procedure TGLScrollbar.SetMin(const val: Single);
  2632. begin
  2633. if FMin <> val then
  2634. begin
  2635. FMin := val;
  2636. if FPos < FMin then
  2637. Pos := FMin;
  2638. NotifyChange(Self);
  2639. end;
  2640. end;
  2641. procedure TGLScrollbar.SetMax(const val: Single);
  2642. begin
  2643. if FMax <> val then
  2644. begin
  2645. FMax := val;
  2646. if FMax < FMin then
  2647. FMax := FMin;
  2648. if FPos > (FMax - FPageSize + 1) then
  2649. Pos := (FMax - FPageSize + 1);
  2650. NotifyChange(Self);
  2651. end;
  2652. end;
  2653. procedure TGLScrollbar.SetPos(const val: Single);
  2654. begin
  2655. if FPos <> val then
  2656. begin
  2657. FPos := val;
  2658. if FPos < FMin then
  2659. FPos := FMin;
  2660. if FPos > (FMax - FPageSize + 1) then
  2661. FPos := (FMax - FPageSize + 1);
  2662. NotifyChange(Self);
  2663. if Assigned(FOnChange) then
  2664. FOnChange(Self);
  2665. end;
  2666. end;
  2667. procedure TGLScrollbar.SetPageSize(const val: Single);
  2668. begin
  2669. if FPageSize <> val then
  2670. begin
  2671. FPageSize := val;
  2672. if FPos > (FMax - FPageSize + 1) then
  2673. Pos := (FMax - FPageSize + 1);
  2674. NotifyChange(Self);
  2675. end;
  2676. end;
  2677. procedure TGLScrollbar.SetHorizontal(const val: Boolean);
  2678. begin
  2679. if FHorizontal <> val then
  2680. begin
  2681. FHorizontal := val;
  2682. NotifyChange(Self);
  2683. end;
  2684. end;
  2685. procedure TGLScrollbar.SetGuiLayoutKnobName(const newName: TGLGuiComponentName);
  2686. begin
  2687. if newName <> FGuiLayoutKnobName then
  2688. begin
  2689. FGuiKnobComponent := nil;
  2690. FGuiLayoutKnobName := NewName;
  2691. if Assigned(FGuiLayout) then
  2692. begin
  2693. FGuiKnobComponent :=
  2694. FGuiLayout.GuiComponents.FindItem(FGuiLayoutKnobName);
  2695. FReBuildGui := True;
  2696. GUIRedraw := True;
  2697. end;
  2698. end;
  2699. end;
  2700. procedure TGLScrollbar.SetGuiLayout(NewGui: TGLGuiLayout);
  2701. begin
  2702. FGuiKnobComponent := nil;
  2703. inherited;
  2704. if Assigned(FGuiLayout) then
  2705. begin
  2706. FGuiKnobComponent := FGuiLayout.GuiComponents.FindItem(FGuiLayoutKnobName);
  2707. FReBuildGui := True;
  2708. GUIRedraw := True;
  2709. end;
  2710. end;
  2711. function TGLScrollbar.GetScrollPosY(ScrollPos: Single): Single;
  2712. begin
  2713. with FRenderStatus[GLAlCenter] do
  2714. begin
  2715. Result := (ScrollPos - FMin) / (FMax - FMin) * (Y2 - Y1) + Y1;
  2716. end;
  2717. end;
  2718. function TGLScrollbar.GetYScrollPos(Y: Single): Single;
  2719. begin
  2720. with FRenderStatus[GLAlCenter] do
  2721. begin
  2722. Result := (Y - Y1) / (Y2 - Y1) * (FMax - FMin) + FMin;
  2723. end;
  2724. end;
  2725. function TGLScrollbar.GetScrollPosX(ScrollPos: Single): Single;
  2726. begin
  2727. with FRenderStatus[GLAlCenter] do
  2728. begin
  2729. Result := (ScrollPos - FMin) / (FMax - FMin) * (X2 - X1) + X1;
  2730. end;
  2731. end;
  2732. function TGLScrollbar.GetXScrollPos(X: Single): Single;
  2733. begin
  2734. with FRenderStatus[GLAlCenter] do
  2735. begin
  2736. Result := (X - X1) / (X2 - X1) * (FMax - FMin) + FMin;
  2737. end;
  2738. end;
  2739. procedure TGLScrollbar.InternalMouseDown(Shift: TShiftState; Button:
  2740. TMouseButton; X, Y: Integer);
  2741. var
  2742. Tx, Ty: Single;
  2743. begin
  2744. if (Button = mbLeft)
  2745. and not FLocked then
  2746. begin
  2747. Tx := x - Position.X;
  2748. Ty := y - Position.Y;
  2749. // is in mid area ?
  2750. if IsInRect(FRenderStatus[GLAlCenter], Tx, Ty) then
  2751. begin
  2752. if FHorizontal then
  2753. begin
  2754. Tx := GetxScrollPos(Tx);
  2755. if Tx < FPos then
  2756. PageUp
  2757. else if Tx > FPos + FPageSize - 1 then
  2758. PageDown
  2759. else
  2760. begin
  2761. fScrolling := True;
  2762. FScrollOffs := Tx - FPos;
  2763. RootControl.ActiveControl := Self;
  2764. end;
  2765. end
  2766. else
  2767. begin
  2768. Ty := GetYScrollPos(Ty);
  2769. if Ty < FPos then
  2770. PageUp
  2771. else if Ty > FPos + FPageSize - 1 then
  2772. PageDown
  2773. else
  2774. begin
  2775. fScrolling := True;
  2776. FScrollOffs := Ty - FPos;
  2777. RootControl.ActiveControl := Self;
  2778. end;
  2779. end;
  2780. end
  2781. else
  2782. begin
  2783. // if not, is at end buttons ?
  2784. if horizontal then
  2785. begin
  2786. if IsInRect(FRenderStatus[GLAlLeft], Tx, Ty) then
  2787. StepUp;
  2788. if IsInRect(FRenderStatus[GLAlRight], Tx, Ty) then
  2789. StepDown;
  2790. end
  2791. else
  2792. begin
  2793. if IsInRect(FRenderStatus[GLAlTop], Tx, Ty) then
  2794. StepUp;
  2795. if IsInRect(FRenderStatus[GLAlBottom], Tx, Ty) then
  2796. StepDown;
  2797. end;
  2798. end;
  2799. end;
  2800. inherited;
  2801. end;
  2802. procedure TGLScrollbar.InternalMouseUp(Shift: TShiftState; Button:
  2803. TMouseButton; X, Y: Integer);
  2804. begin
  2805. if fScrolling then
  2806. begin
  2807. fScrolling := False;
  2808. RootControl.ActiveControl := nil;
  2809. end;
  2810. inherited;
  2811. end;
  2812. procedure TGLScrollbar.InternalMouseMove(Shift: TShiftState; X, Y: Integer);
  2813. var
  2814. Tx: Single;
  2815. Ty: Single;
  2816. begin
  2817. if fScrolling then
  2818. if FHorizontal then
  2819. begin
  2820. Tx := GetXScrollPos(x - Position.X) - FScrollOffs;
  2821. Pos := Round(Tx);
  2822. end
  2823. else
  2824. begin
  2825. Ty := GetYScrollPos(y - Position.Y) - FScrollOffs;
  2826. Pos := Round(Ty);
  2827. end;
  2828. inherited;
  2829. end;
  2830. constructor TGLScrollbar.Create(AOwner: TComponent);
  2831. begin
  2832. inherited;
  2833. FGuiKnobComponent := nil;
  2834. FMin := 1;
  2835. FMax := 10;
  2836. FPos := 1;
  2837. FStep := 1;
  2838. FPageSize := 3;
  2839. FOnChange := nil;
  2840. FGuiLayoutKnobName := '';
  2841. FScrollOffs := 0;
  2842. FScrolling := False;
  2843. FHorizontal := False;
  2844. end;
  2845. procedure TGLScrollbar.StepUp;
  2846. begin
  2847. Pos := Pos - FStep;
  2848. end;
  2849. procedure TGLScrollbar.StepDown;
  2850. begin
  2851. Pos := Pos + FStep;
  2852. end;
  2853. procedure TGLScrollbar.PageUp;
  2854. begin
  2855. Pos := Pos - FPageSize;
  2856. end;
  2857. procedure TGLScrollbar.PageDown;
  2858. begin
  2859. Pos := Pos + FPageSize;
  2860. end;
  2861. function TGLScrollbar.MouseUp(Sender: TObject; Button: TMouseButton; Shift:
  2862. TShiftState; X, Y: Integer): Boolean;
  2863. begin
  2864. if (Button = mbLeft) and (FScrolling) then
  2865. begin
  2866. Result := True;
  2867. InternalMouseUp(Shift, Button, X, Y);
  2868. end
  2869. else
  2870. Result := inherited MouseUp(Sender, Button, Shift, X, Y);
  2871. end;
  2872. function TGLScrollbar.MouseMove(Sender: TObject; Shift: TShiftState; X, Y:
  2873. Integer): Boolean;
  2874. begin
  2875. if (FScrolling) then
  2876. begin
  2877. Result := True;
  2878. InternalMouseMove(Shift, X, Y);
  2879. end
  2880. else
  2881. Result := inherited MouseMove(Sender, Shift, X, Y);
  2882. end;
  2883. procedure TGLScrollbar.InternalRender(var rci: TGLRenderContextInfo; renderSelf,
  2884. renderChildren: Boolean);
  2885. var
  2886. Start, Size: Integer;
  2887. begin
  2888. if Assigned(FGuiComponent) then
  2889. begin
  2890. try
  2891. FGuiComponent.RenderToArea(0, 0, Width, Height, FRenderStatus,
  2892. FReBuildGui);
  2893. except
  2894. on E: Exception do
  2895. GLOKMessageBox(E.Message,
  2896. 'Exception in GuiComponents InternalRender function');
  2897. end;
  2898. end;
  2899. if Assigned(FGuiKnobComponent) then
  2900. begin
  2901. try
  2902. with FRenderStatus[GLAlCenter] do
  2903. begin
  2904. if FHorizontal then
  2905. begin
  2906. Start := Round(GetScrollPosX(FPos));
  2907. if FPageSize + FPos > FMax + 1 then
  2908. Size := Round(GetScrollPosX(FMax) - X1)
  2909. else
  2910. Size := Round(GetScrollPosX(FPageSize) - X1);
  2911. FGuiKnobComponent.RenderToArea(Start, Y1, Start + Size, Y2,
  2912. FKnobRenderStatus, True);
  2913. // Tag := start;
  2914. // tagfloat := size;
  2915. end
  2916. else
  2917. begin
  2918. Start := Round(GetScrollPosY(FPos));
  2919. if FPageSize + FPos > FMax + 1 then
  2920. Size := Round(GetScrollPosY(FMax) - Y1)
  2921. else
  2922. Size := Round(GetScrollPosY(FPageSize) - Y1);
  2923. FGuiKnobComponent.RenderToArea(X1, Start, X2, Start + Size,
  2924. FKnobRenderStatus, True);
  2925. // Tag := start;
  2926. // tagfloat := size;
  2927. end;
  2928. end;
  2929. except
  2930. on E: Exception do
  2931. GLOKMessageBox(E.Message,
  2932. 'Exception in GuiComponents InternalRender function');
  2933. end;
  2934. end;
  2935. end;
  2936. function TGLStringGrid.GetCell(X, Y: Integer; out oCol, oRow: Integer): Boolean;
  2937. var
  2938. ClientRect: TRectangle;
  2939. XPos: Integer;
  2940. YPos: Integer;
  2941. XC, YC: Integer;
  2942. begin
  2943. Result := False;
  2944. if Assigned(BitmapFont) then
  2945. begin
  2946. if Assigned(FGuiComponent) then
  2947. begin
  2948. ClientRect.Left := Round(FRenderStatus[GLAlCenter].X1);
  2949. ClientRect.Top := Round(FRenderStatus[GLAlCenter].Y1);
  2950. ClientRect.Width := Round(FRenderStatus[GLAlCenter].X2);
  2951. ClientRect.Height := Round(FRenderStatus[GLAlCenter].Y2);
  2952. end
  2953. else
  2954. begin
  2955. ClientRect.Left := 0;
  2956. ClientRect.Top := 0;
  2957. ClientRect.Width := Round(Width);
  2958. ClientRect.Height := Round(Height);
  2959. end;
  2960. YPos := ClientRect.Top;
  2961. if FDrawHeader then
  2962. YPos := YPos + RowHeight;
  2963. XPos := ClientRect.Left;
  2964. if y < YPos then
  2965. Exit;
  2966. if x < XPos then
  2967. Exit;
  2968. XPos := XPos + MarginSize;
  2969. for XC := 0 to Columns.Count - 1 do
  2970. begin
  2971. XPos := XPos + Integer(Columns.Objects[XC]);
  2972. if x > XPos then
  2973. continue;
  2974. for YC := 0 to RowCount - 1 do
  2975. begin
  2976. YPos := YPos + RowHeight;
  2977. if y < YPos then
  2978. begin
  2979. Result := True;
  2980. if Assigned(Scrollbar) then
  2981. oRow := YC + Round(Scrollbar.Pos) - 1
  2982. else
  2983. oRow := YC;
  2984. oCol := XC;
  2985. Exit;
  2986. end;
  2987. end;
  2988. end;
  2989. end;
  2990. end;
  2991. procedure TGLStringGrid.InternalMouseDown(Shift: TShiftState; Button:
  2992. TMouseButton; X, Y: Integer);
  2993. var
  2994. tRow, tCol: Integer;
  2995. begin
  2996. SetFocus;
  2997. if GetCell(Round(X - Position.X), Round(Y - Position.Y), tCol, tRow) then
  2998. begin
  2999. SelCol := tCol;
  3000. SelRow := tRow;
  3001. end;
  3002. inherited;
  3003. end;
  3004. procedure TGLStringGrid.SetColumns(const val: TStrings);
  3005. var
  3006. XC: Integer;
  3007. begin
  3008. FColumns.Assign(val);
  3009. for XC := 0 to Columns.Count - 1 do
  3010. Columns.Objects[XC] := TObject(ColumnSize);
  3011. end;
  3012. procedure TGLStringGrid.SetColSelect(const val: Boolean);
  3013. begin
  3014. FColSelect := Val;
  3015. NotifyChange(Self);
  3016. end;
  3017. function TGLStringGrid.GetRow(index: Integer): TStringList;
  3018. begin
  3019. if (index >= 0) and (index < FRows.Count) then
  3020. Result := TStringList(FRows[index])
  3021. else
  3022. Result := nil;
  3023. end;
  3024. procedure TGLStringGrid.SetRow(index: Integer; const val: TStringList);
  3025. begin
  3026. if (index >= 0) then
  3027. begin
  3028. if (index >= RowCount) then
  3029. RowCount := index + 1;
  3030. TStringList(FRows[index]).Assign(val);
  3031. end;
  3032. end;
  3033. function TGLStringGrid.GetRowCount: Integer;
  3034. begin
  3035. Result := FRows.count;
  3036. end;
  3037. procedure TGLStringGrid.SetRowCount(const val: Integer);
  3038. var
  3039. XC: Integer;
  3040. begin
  3041. XC := FRows.count;
  3042. if val <> XC then
  3043. begin
  3044. if val > XC then
  3045. begin
  3046. FRows.count := val;
  3047. for XC := XC to val - 1 do
  3048. begin
  3049. FRows[XC] := TStringList.Create;
  3050. TStringList(FRows[XC]).OnChange := OnStringListChange;
  3051. end;
  3052. end
  3053. else
  3054. begin
  3055. for XC := XC - 1 downto val do
  3056. begin
  3057. TStringList(FRows[XC]).Free;
  3058. end;
  3059. FRows.count := val;
  3060. end;
  3061. if Assigned(Scrollbar) then
  3062. Scrollbar.FMax := FRows.Count;
  3063. NotifyChange(Self);
  3064. end;
  3065. end;
  3066. procedure TGLStringGrid.SetSelCol(const val: Integer);
  3067. begin
  3068. if FSelCol <> Val then
  3069. begin
  3070. FSelCol := Val;
  3071. NotifyChange(Self);
  3072. end;
  3073. end;
  3074. procedure TGLStringGrid.SetSelRow(const val: Integer);
  3075. begin
  3076. if FSelRow <> Val then
  3077. begin
  3078. FSelRow := Val;
  3079. NotifyChange(Self);
  3080. end;
  3081. end;
  3082. procedure TGLStringGrid.SetRowSelect(const val: Boolean);
  3083. begin
  3084. FRowSelect := Val;
  3085. NotifyChange(Self);
  3086. end;
  3087. procedure TGLStringGrid.SetDrawHeader(const val: Boolean);
  3088. begin
  3089. FDrawHeader := Val;
  3090. NotifyChange(Self);
  3091. end;
  3092. function TGLStringGrid.GetHeaderColor: TColor;
  3093. begin
  3094. Result := ConvertColorVector(FHeaderColor);
  3095. end;
  3096. procedure TGLStringGrid.SetHeaderColor(const val: TColor);
  3097. begin
  3098. FHeaderColor := ConvertWinColor(val);
  3099. GUIRedraw := True;
  3100. end;
  3101. procedure TGLStringGrid.SetMarginSize(const val: Integer);
  3102. begin
  3103. if FMarginSize <> val then
  3104. begin
  3105. FMarginSize := val;
  3106. GUIRedraw := True;
  3107. end;
  3108. end;
  3109. procedure TGLStringGrid.SetColumnSize(const val: Integer);
  3110. var
  3111. XC: Integer;
  3112. begin
  3113. if FColumnSize <> val then
  3114. begin
  3115. FColumnSize := val;
  3116. for XC := 0 to Columns.Count - 1 do
  3117. Columns.Objects[XC] := TObject(ColumnSize);
  3118. GUIRedraw := True;
  3119. end;
  3120. end;
  3121. procedure TGLStringGrid.SetRowHeight(const val: Integer);
  3122. begin
  3123. if FRowHeight <> val then
  3124. begin
  3125. FRowHeight := val;
  3126. GUIRedraw := True;
  3127. end;
  3128. end;
  3129. procedure TGLStringGrid.SetScrollbar(const val: TGLScrollbar);
  3130. begin
  3131. if FScrollbar <> Val then
  3132. begin
  3133. if Assigned(FScrollbar) then
  3134. FScrollbar.RemoveFreeNotification(Self);
  3135. FScrollbar := Val;
  3136. if Assigned(FScrollbar) then
  3137. FScrollbar.FreeNotification(Self);
  3138. end;
  3139. end;
  3140. procedure TGLStringGrid.SetGuiLayout(NewGui: TGLGuiLayout);
  3141. begin
  3142. inherited;
  3143. if Assigned(Scrollbar) then
  3144. if Scrollbar.GuiLayout <> nil then
  3145. Scrollbar.GuiLayout := NewGui;
  3146. end;
  3147. constructor TGLStringGrid.Create(AOwner: TComponent);
  3148. begin
  3149. inherited;
  3150. FRows := TList.Create;
  3151. FColumns := TStringList.Create;
  3152. TStringList(FColumns).OnChange := OnStringListChange;
  3153. FSelCol := 0;
  3154. FSelRow := 0;
  3155. FRowSelect := True;
  3156. FScrollbar := nil;
  3157. FDrawHeader := True;
  3158. end;
  3159. destructor TGLStringGrid.Destroy;
  3160. begin
  3161. Scrollbar := nil;
  3162. inherited;
  3163. Clear;
  3164. FRows.Free;
  3165. FColumns.Free;
  3166. end;
  3167. procedure TGLStringGrid.Clear;
  3168. begin
  3169. RowCount := 0;
  3170. end;
  3171. procedure TGLStringGrid.Notification(AComponent: TComponent; Operation:
  3172. TOperation);
  3173. begin
  3174. if (AComponent = FScrollbar) and (Operation = opRemove) then
  3175. begin
  3176. FScrollbar := nil;
  3177. end;
  3178. inherited;
  3179. end;
  3180. procedure TGLStringGrid.NotifyChange(Sender: TObject);
  3181. begin
  3182. if Sender = Scrollbar then
  3183. begin
  3184. ReBuildGui := True;
  3185. GUIRedraw := True;
  3186. end;
  3187. inherited;
  3188. end;
  3189. procedure TGLStringGrid.InternalRender(var rci: TGLRenderContextInfo; renderSelf,
  3190. renderChildren: Boolean);
  3191. function CellSelected(X, Y: Integer): Boolean;
  3192. begin
  3193. if (RowSelect and ColSelect) then
  3194. Result := (Y = SelRow) or (x = SelCol)
  3195. else if RowSelect then
  3196. Result := Y = SelRow
  3197. else if ColSelect then
  3198. Result := X = SelCol
  3199. else
  3200. Result := (Y = SelRow) and (x = SelCol);
  3201. end;
  3202. function CellText(X, Y: Integer): string;
  3203. begin
  3204. with Row[y] do
  3205. if (X >= 0) and (X < Count) then
  3206. Result := strings[x]
  3207. else
  3208. Result := '';
  3209. end;
  3210. var
  3211. ClientRect: TRectangle;
  3212. XPos: Integer;
  3213. YPos: Integer;
  3214. XC, YC: Integer;
  3215. From, Till: Integer;
  3216. begin
  3217. if Assigned(FGuiComponent) then
  3218. begin
  3219. try
  3220. FGuiComponent.RenderToArea(0, 0, Width, Height, FRenderStatus,
  3221. FReBuildGui);
  3222. ClientRect.Left := Round(FRenderStatus[GLAlCenter].X1);
  3223. ClientRect.Top := Round(FRenderStatus[GLAlCenter].Y1);
  3224. ClientRect.Width := Round(FRenderStatus[GLAlCenter].X2);
  3225. ClientRect.Height := Round(FRenderStatus[GLAlCenter].Y2);
  3226. except
  3227. on E: Exception do
  3228. GLOKMessageBox(E.Message,
  3229. 'Exception in GuiComponents InternalRender function');
  3230. end;
  3231. end
  3232. else
  3233. begin
  3234. ClientRect.Left := 0;
  3235. ClientRect.Top := 0;
  3236. ClientRect.Width := Round(Width);
  3237. ClientRect.Height := Round(Height);
  3238. end;
  3239. if Assigned(BitmapFont) then
  3240. begin
  3241. XPos := ClientRect.Left + MarginSize;
  3242. if Assigned(Scrollbar) then
  3243. begin
  3244. Scrollbar.Position.X := Position.X + FRenderStatus[GLAlCenter].X2 -
  3245. Scrollbar.Width;
  3246. Scrollbar.Position.Y := Position.Y + FRenderStatus[GLAlCenter].Y1;
  3247. Scrollbar.Height := FRenderStatus[GLAlCenter].Y2 -
  3248. FRenderStatus[GLAlCenter].Y1;
  3249. XC := (ClientRect.Height - ClientRect.Top);
  3250. if FDrawHeader then
  3251. YC := (XC div RowHeight) - 1
  3252. else
  3253. YC := (XC div RowHeight);
  3254. Scrollbar.PageSize := YC;
  3255. From := Round(Scrollbar.pos - 1);
  3256. Till := Round(Scrollbar.pageSize + From - 1);
  3257. if Till > RowCount - 1 then
  3258. Till := RowCount - 1;
  3259. end
  3260. else
  3261. begin
  3262. From := 0;
  3263. Till := RowCount - 1;
  3264. end;
  3265. for XC := 0 to Columns.Count - 1 do
  3266. begin
  3267. YPos := -ClientRect.Top;
  3268. if FDrawHeader then
  3269. begin
  3270. WriteTextAt(rci, XPos, YPos, Columns[XC], FHeaderColor);
  3271. YPos := YPos - RowHeight;
  3272. end;
  3273. for YC := From to Till do
  3274. begin
  3275. if CellSelected(XC, YC) then
  3276. WriteTextAt(rci, XPos, YPos, CellText(XC, YC), FFocusedColor)
  3277. else
  3278. WriteTextAt(rci, XPos, YPos, CellText(XC, YC), FDefaultColor);
  3279. YPos := YPos - RowHeight;
  3280. end;
  3281. XPos := XPos + Integer(Columns.Objects[XC]);
  3282. end;
  3283. end;
  3284. end;
  3285. procedure TGLStringGrid.OnStringListChange(Sender: TObject);
  3286. begin
  3287. NotifyChange(Self);
  3288. end;
  3289. function TGLStringGrid.Add(const Data: array of string): Integer;
  3290. var
  3291. XC: Integer;
  3292. begin
  3293. Result := RowCount;
  3294. RowCount := RowCount + 1;
  3295. for XC := 0 to Length(Data) - 1 do
  3296. Row[Result].Add(Data[XC]);
  3297. end;
  3298. function TGLStringGrid.Add(const Data: string): Integer;
  3299. begin
  3300. Result := Add([Data]);
  3301. if Assigned(Scrollbar) then
  3302. begin
  3303. if Result > Round(Scrollbar.pageSize + Scrollbar.pos - 2) then
  3304. Scrollbar.pos := Result - Scrollbar.pageSize + 2;
  3305. end;
  3306. end;
  3307. procedure TGLStringGrid.SetText(Data: string);
  3308. var
  3309. Posi: Integer;
  3310. begin
  3311. Clear;
  3312. while Data <> '' do
  3313. begin
  3314. Posi := Pos(#13#10, Data);
  3315. if Posi > 0 then
  3316. begin
  3317. Add(Copy(Data, 1, Posi - 1));
  3318. Delete(Data, 1, Posi + 1);
  3319. end
  3320. else
  3321. begin
  3322. Add(Data);
  3323. Data := '';
  3324. end;
  3325. end;
  3326. end;
  3327. destructor TGLFocusControl.Destroy;
  3328. begin
  3329. if Focused then
  3330. RootControl.FocusedControl := nil;
  3331. inherited;
  3332. end;
  3333. procedure TGLBaseComponent.DoProgress(const progressTime: TGLProgressTimes);
  3334. begin
  3335. inherited;
  3336. if FDoChangesOnProgress then
  3337. DoChanges;
  3338. end;
  3339. procedure TGLBaseComponent.SetDoChangesOnProgress(const Value: Boolean);
  3340. begin
  3341. FDoChangesOnProgress := Value;
  3342. end;
  3343. procedure TGLFocusControl.MoveTo(newParent: TGLBaseSceneObject);
  3344. begin
  3345. inherited;
  3346. ReGetRootControl;
  3347. end;
  3348. //--------------------------------------------
  3349. initialization
  3350. //--------------------------------------------
  3351. RegisterClasses([TGLBaseControl, TGLPopupMenu, TGLForm, TGLPanel, TGLButton,
  3352. TGLCheckBox, TGLEdit, TGLLabel, TGLAdvancedLabel, TGLScrollbar, TGLStringGrid,
  3353. TGLCustomControl]);
  3354. end.