GLWindows.pas 98 KB

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