GXS.Windows.pas 94 KB

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