raygui.h 214 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491
  1. /*******************************************************************************************
  2. *
  3. * raygui v3.2 - A simple and easy-to-use immediate-mode gui library
  4. *
  5. * DESCRIPTION:
  6. *
  7. * raygui is a tools-dev-focused immediate-mode-gui library based on raylib but also
  8. * available as a standalone library, as long as input and drawing functions are provided.
  9. *
  10. * Controls provided:
  11. *
  12. * # Container/separators Controls
  13. * - WindowBox --> StatusBar, Panel
  14. * - GroupBox --> Line
  15. * - Line
  16. * - Panel --> StatusBar
  17. * - ScrollPanel --> StatusBar
  18. *
  19. * # Basic Controls
  20. * - Label
  21. * - Button
  22. * - LabelButton --> Label
  23. * - Toggle
  24. * - ToggleGroup --> Toggle
  25. * - CheckBox
  26. * - ComboBox
  27. * - DropdownBox
  28. * - TextBox
  29. * - TextBoxMulti
  30. * - ValueBox --> TextBox
  31. * - Spinner --> Button, ValueBox
  32. * - Slider
  33. * - SliderBar --> Slider
  34. * - ProgressBar
  35. * - StatusBar
  36. * - DummyRec
  37. * - Grid
  38. *
  39. * # Advance Controls
  40. * - ListView
  41. * - ColorPicker --> ColorPanel, ColorBarHue
  42. * - MessageBox --> Window, Label, Button
  43. * - TextInputBox --> Window, Label, TextBox, Button
  44. *
  45. * It also provides a set of functions for styling the controls based on its properties (size, color).
  46. *
  47. *
  48. * RAYGUI STYLE (guiStyle):
  49. *
  50. * raygui uses a global data array for all gui style properties (allocated on data segment by default),
  51. * when a new style is loaded, it is loaded over the global style... but a default gui style could always be
  52. * recovered with GuiLoadStyleDefault() function, that overwrites the current style to the default one
  53. *
  54. * The global style array size is fixed and depends on the number of controls and properties:
  55. *
  56. * static unsigned int guiStyle[RAYGUI_MAX_CONTROLS*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED)];
  57. *
  58. * guiStyle size is by default: 16*(16 + 8) = 384*4 = 1536 bytes = 1.5 KB
  59. *
  60. * Note that the first set of BASE properties (by default guiStyle[0..15]) belong to the generic style
  61. * used for all controls, when any of those base values is set, it is automatically populated to all
  62. * controls, so, specific control values overwriting generic style should be set after base values.
  63. *
  64. * After the first BASE set we have the EXTENDED properties (by default guiStyle[16..23]), those
  65. * properties are actually common to all controls and can not be overwritten individually (like BASE ones)
  66. * Some of those properties are: TEXT_SIZE, TEXT_SPACING, LINE_COLOR, BACKGROUND_COLOR
  67. *
  68. * Custom control properties can be defined using the EXTENDED properties for each independent control.
  69. *
  70. * TOOL: rGuiStyler is a visual tool to customize raygui style.
  71. *
  72. *
  73. * RAYGUI ICONS (guiIcons):
  74. *
  75. * raygui could use a global array containing icons data (allocated on data segment by default),
  76. * a custom icons set could be loaded over this array using GuiLoadIcons(), but loaded icons set
  77. * must be same RAYGUI_ICON_SIZE and no more than RAYGUI_ICON_MAX_ICONS will be loaded
  78. *
  79. * Every icon is codified in binary form, using 1 bit per pixel, so, every 16x16 icon
  80. * requires 8 integers (16*16/32) to be stored in memory.
  81. *
  82. * When the icon is draw, actually one quad per pixel is drawn if the bit for that pixel is set.
  83. *
  84. * The global icons array size is fixed and depends on the number of icons and size:
  85. *
  86. * static unsigned int guiIcons[RAYGUI_ICON_MAX_ICONS*RAYGUI_ICON_DATA_ELEMENTS];
  87. *
  88. * guiIcons size is by default: 256*(16*16/32) = 2048*4 = 8192 bytes = 8 KB
  89. *
  90. * TOOL: rGuiIcons is a visual tool to customize raygui icons.
  91. *
  92. *
  93. * CONFIGURATION:
  94. *
  95. * #define RAYGUI_IMPLEMENTATION
  96. * Generates the implementation of the library into the included file.
  97. * If not defined, the library is in header only mode and can be included in other headers
  98. * or source files without problems. But only ONE file should hold the implementation.
  99. *
  100. * #define RAYGUI_STANDALONE
  101. * Avoid raylib.h header inclusion in this file. Data types defined on raylib are defined
  102. * internally in the library and input management and drawing functions must be provided by
  103. * the user (check library implementation for further details).
  104. *
  105. * #define RAYGUI_NO_ICONS
  106. * Avoid including embedded ricons data (256 icons, 16x16 pixels, 1-bit per pixel, 2KB)
  107. *
  108. * #define RAYGUI_CUSTOM_ICONS
  109. * Includes custom ricons.h header defining a set of custom icons,
  110. * this file can be generated using rGuiIcons tool
  111. *
  112. *
  113. * VERSIONS HISTORY:
  114. * 3.2 (22-May-2022) RENAMED: Some enum values, for unification, avoiding prefixes
  115. * REMOVED: GuiScrollBar(), only internal
  116. * REDESIGNED: GuiPanel() to support text parameter
  117. * REDESIGNED: GuiScrollPanel() to support text parameter
  118. * REDESIGNED: GuiColorPicker() to support text parameter
  119. * REDESIGNED: GuiColorPanel() to support text parameter
  120. * REDESIGNED: GuiColorBarAlpha() to support text parameter
  121. * REDESIGNED: GuiColorBarHue() to support text parameter
  122. * REDESIGNED: GuiTextInputBox() to support password
  123. * 3.1 (12-Jan-2022) REVIEWED: Default style for consistency (aligned with rGuiLayout v2.5 tool)
  124. * REVIEWED: GuiLoadStyle() to support compressed font atlas image data and unload previous textures
  125. * REVIEWED: External icons usage logic
  126. * REVIEWED: GuiLine() for centered alignment when including text
  127. * RENAMED: Multiple controls properties definitions to prepend RAYGUI_
  128. * RENAMED: RICON_ references to RAYGUI_ICON_ for library consistency
  129. * Projects updated and multiple tweaks
  130. * 3.0 (04-Nov-2021) Integrated ricons data to avoid external file
  131. * REDESIGNED: GuiTextBoxMulti()
  132. * REMOVED: GuiImageButton*()
  133. * Multiple minor tweaks and bugs corrected
  134. * 2.9 (17-Mar-2021) REMOVED: Tooltip API
  135. * 2.8 (03-May-2020) Centralized rectangles drawing to GuiDrawRectangle()
  136. * 2.7 (20-Feb-2020) ADDED: Possible tooltips API
  137. * 2.6 (09-Sep-2019) ADDED: GuiTextInputBox()
  138. * REDESIGNED: GuiListView*(), GuiDropdownBox(), GuiSlider*(), GuiProgressBar(), GuiMessageBox()
  139. * REVIEWED: GuiTextBox(), GuiSpinner(), GuiValueBox(), GuiLoadStyle()
  140. * Replaced property INNER_PADDING by TEXT_PADDING, renamed some properties
  141. * ADDED: 8 new custom styles ready to use
  142. * Multiple minor tweaks and bugs corrected
  143. * 2.5 (28-May-2019) Implemented extended GuiTextBox(), GuiValueBox(), GuiSpinner()
  144. * 2.3 (29-Apr-2019) ADDED: rIcons auxiliar library and support for it, multiple controls reviewed
  145. * Refactor all controls drawing mechanism to use control state
  146. * 2.2 (05-Feb-2019) ADDED: GuiScrollBar(), GuiScrollPanel(), reviewed GuiListView(), removed Gui*Ex() controls
  147. * 2.1 (26-Dec-2018) REDESIGNED: GuiCheckBox(), GuiComboBox(), GuiDropdownBox(), GuiToggleGroup() > Use combined text string
  148. * REDESIGNED: Style system (breaking change)
  149. * 2.0 (08-Nov-2018) ADDED: Support controls guiLock and custom fonts
  150. * REVIEWED: GuiComboBox(), GuiListView()...
  151. * 1.9 (09-Oct-2018) REVIEWED: GuiGrid(), GuiTextBox(), GuiTextBoxMulti(), GuiValueBox()...
  152. * 1.8 (01-May-2018) Lot of rework and redesign to align with rGuiStyler and rGuiLayout
  153. * 1.5 (21-Jun-2017) Working in an improved styles system
  154. * 1.4 (15-Jun-2017) Rewritten all GUI functions (removed useless ones)
  155. * 1.3 (12-Jun-2017) Complete redesign of style system
  156. * 1.1 (01-Jun-2017) Complete review of the library
  157. * 1.0 (07-Jun-2016) Converted to header-only by Ramon Santamaria.
  158. * 0.9 (07-Mar-2016) Reviewed and tested by Albert Martos, Ian Eito, Sergio Martinez and Ramon Santamaria.
  159. * 0.8 (27-Aug-2015) Initial release. Implemented by Kevin Gato, Daniel Nicolás and Ramon Santamaria.
  160. *
  161. *
  162. * CONTRIBUTORS:
  163. *
  164. * Ramon Santamaria: Supervision, review, redesign, update and maintenance
  165. * Vlad Adrian: Complete rewrite of GuiTextBox() to support extended features (2019)
  166. * Sergio Martinez: Review, testing (2015) and redesign of multiple controls (2018)
  167. * Adria Arranz: Testing and Implementation of additional controls (2018)
  168. * Jordi Jorba: Testing and Implementation of additional controls (2018)
  169. * Albert Martos: Review and testing of the library (2015)
  170. * Ian Eito: Review and testing of the library (2015)
  171. * Kevin Gato: Initial implementation of basic components (2014)
  172. * Daniel Nicolas: Initial implementation of basic components (2014)
  173. *
  174. *
  175. * LICENSE: zlib/libpng
  176. *
  177. * Copyright (c) 2014-2022 Ramon Santamaria (@raysan5)
  178. *
  179. * This software is provided "as-is", without any express or implied warranty. In no event
  180. * will the authors be held liable for any damages arising from the use of this software.
  181. *
  182. * Permission is granted to anyone to use this software for any purpose, including commercial
  183. * applications, and to alter it and redistribute it freely, subject to the following restrictions:
  184. *
  185. * 1. The origin of this software must not be misrepresented; you must not claim that you
  186. * wrote the original software. If you use this software in a product, an acknowledgment
  187. * in the product documentation would be appreciated but is not required.
  188. *
  189. * 2. Altered source versions must be plainly marked as such, and must not be misrepresented
  190. * as being the original software.
  191. *
  192. * 3. This notice may not be removed or altered from any source distribution.
  193. *
  194. **********************************************************************************************/
  195. #ifndef RAYGUI_H
  196. #define RAYGUI_H
  197. #define RAYGUI_VERSION "3.2"
  198. #if !defined(RAYGUI_STANDALONE)
  199. #include "raylib.h"
  200. #endif
  201. // Function specifiers in case library is build/used as a shared library (Windows)
  202. // NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
  203. #if defined(_WIN32)
  204. #if defined(BUILD_LIBTYPE_SHARED)
  205. #define RAYGUIAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll)
  206. #elif defined(USE_LIBTYPE_SHARED)
  207. #define RAYGUIAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll)
  208. #endif
  209. #endif
  210. // Function specifiers definition
  211. #ifndef RAYGUIAPI
  212. #define RAYGUIAPI // Functions defined as 'extern' by default (implicit specifiers)
  213. #endif
  214. //----------------------------------------------------------------------------------
  215. // Defines and Macros
  216. //----------------------------------------------------------------------------------
  217. // Allow custom memory allocators
  218. #ifndef RAYGUI_MALLOC
  219. #define RAYGUI_MALLOC(sz) malloc(sz)
  220. #endif
  221. #ifndef RAYGUI_CALLOC
  222. #define RAYGUI_CALLOC(n,sz) calloc(n,sz)
  223. #endif
  224. #ifndef RAYGUI_FREE
  225. #define RAYGUI_FREE(p) free(p)
  226. #endif
  227. // Simple log system to avoid printf() calls if required
  228. // NOTE: Avoiding those calls, also avoids const strings memory usage
  229. #define RAYGUI_SUPPORT_LOG_INFO
  230. #if defined(RAYGUI_SUPPORT_LOG_INFO)
  231. #define RAYGUI_LOG(...) printf(__VA_ARGS__)
  232. #else
  233. #define RAYGUI_LOG(...)
  234. #endif
  235. //----------------------------------------------------------------------------------
  236. // Types and Structures Definition
  237. // NOTE: Some types are required for RAYGUI_STANDALONE usage
  238. //----------------------------------------------------------------------------------
  239. #if defined(RAYGUI_STANDALONE)
  240. #ifndef __cplusplus
  241. // Boolean type
  242. #ifndef true
  243. typedef enum { false, true } bool;
  244. #endif
  245. #endif
  246. // Vector2 type
  247. typedef struct Vector2 {
  248. float x;
  249. float y;
  250. } Vector2;
  251. // Vector3 type // -- ConvertHSVtoRGB(), ConvertRGBtoHSV()
  252. typedef struct Vector3 {
  253. float x;
  254. float y;
  255. float z;
  256. } Vector3;
  257. // Color type, RGBA (32bit)
  258. typedef struct Color {
  259. unsigned char r;
  260. unsigned char g;
  261. unsigned char b;
  262. unsigned char a;
  263. } Color;
  264. // Rectangle type
  265. typedef struct Rectangle {
  266. float x;
  267. float y;
  268. float width;
  269. float height;
  270. } Rectangle;
  271. // TODO: Texture2D type is very coupled to raylib, required by Font type
  272. // It should be redesigned to be provided by user
  273. typedef struct Texture2D {
  274. unsigned int id; // OpenGL texture id
  275. int width; // Texture base width
  276. int height; // Texture base height
  277. int mipmaps; // Mipmap levels, 1 by default
  278. int format; // Data format (PixelFormat type)
  279. } Texture2D;
  280. // GlyphInfo, font characters glyphs info
  281. typedef struct GlyphInfo {
  282. int value; // Character value (Unicode)
  283. int offsetX; // Character offset X when drawing
  284. int offsetY; // Character offset Y when drawing
  285. int advanceX; // Character advance position X
  286. Image image; // Character image data
  287. } GlyphInfo;
  288. // TODO: Font type is very coupled to raylib, mostly required by GuiLoadStyle()
  289. // It should be redesigned to be provided by user
  290. typedef struct Font {
  291. int baseSize; // Base size (default chars height)
  292. int glyphCount; // Number of characters
  293. Texture2D texture; // Characters texture atlas
  294. Rectangle *recs; // Characters rectangles in texture
  295. GlyphInfo *chars; // Characters info data
  296. } Font;
  297. #endif
  298. // Style property
  299. typedef struct GuiStyleProp {
  300. unsigned short controlId;
  301. unsigned short propertyId;
  302. unsigned int propertyValue;
  303. } GuiStyleProp;
  304. // Gui control state
  305. typedef enum {
  306. STATE_NORMAL = 0,
  307. STATE_FOCUSED,
  308. STATE_PRESSED,
  309. STATE_DISABLED,
  310. } GuiState;
  311. // Gui control text alignment
  312. typedef enum {
  313. TEXT_ALIGN_LEFT = 0,
  314. TEXT_ALIGN_CENTER,
  315. TEXT_ALIGN_RIGHT,
  316. } GuiTextAlignment;
  317. // Gui controls
  318. typedef enum {
  319. // Default -> populates to all controls when set
  320. DEFAULT = 0,
  321. // Basic controls
  322. LABEL, // Used also for: LABELBUTTON
  323. BUTTON,
  324. TOGGLE, // Used also for: TOGGLEGROUP
  325. SLIDER, // Used also for: SLIDERBAR
  326. PROGRESSBAR,
  327. CHECKBOX,
  328. COMBOBOX,
  329. DROPDOWNBOX,
  330. TEXTBOX, // Used also for: TEXTBOXMULTI
  331. VALUEBOX,
  332. SPINNER, // Uses: BUTTON, VALUEBOX
  333. LISTVIEW,
  334. COLORPICKER,
  335. SCROLLBAR,
  336. STATUSBAR
  337. } GuiControl;
  338. // Gui base properties for every control
  339. // NOTE: RAYGUI_MAX_PROPS_BASE properties (by default 16 properties)
  340. typedef enum {
  341. BORDER_COLOR_NORMAL = 0,
  342. BASE_COLOR_NORMAL,
  343. TEXT_COLOR_NORMAL,
  344. BORDER_COLOR_FOCUSED,
  345. BASE_COLOR_FOCUSED,
  346. TEXT_COLOR_FOCUSED,
  347. BORDER_COLOR_PRESSED,
  348. BASE_COLOR_PRESSED,
  349. TEXT_COLOR_PRESSED,
  350. BORDER_COLOR_DISABLED,
  351. BASE_COLOR_DISABLED,
  352. TEXT_COLOR_DISABLED,
  353. BORDER_WIDTH,
  354. TEXT_PADDING,
  355. TEXT_ALIGNMENT,
  356. RESERVED
  357. } GuiControlProperty;
  358. // Gui extended properties depend on control
  359. // NOTE: RAYGUI_MAX_PROPS_EXTENDED properties (by default 8 properties)
  360. //----------------------------------------------------------------------------------
  361. // DEFAULT extended properties
  362. // NOTE: Those properties are common to all controls or global
  363. typedef enum {
  364. TEXT_SIZE = 16, // Text size (glyphs max height)
  365. TEXT_SPACING, // Text spacing between glyphs
  366. LINE_COLOR, // Line control color
  367. BACKGROUND_COLOR, // Background color
  368. } GuiDefaultProperty;
  369. // Label
  370. //typedef enum { } GuiLabelProperty;
  371. // Button/Spinner
  372. //typedef enum { } GuiButtonProperty;
  373. // Toggle/ToggleGroup
  374. typedef enum {
  375. GROUP_PADDING = 16, // ToggleGroup separation between toggles
  376. } GuiToggleProperty;
  377. // Slider/SliderBar
  378. typedef enum {
  379. SLIDER_WIDTH = 16, // Slider size of internal bar
  380. SLIDER_PADDING // Slider/SliderBar internal bar padding
  381. } GuiSliderProperty;
  382. // ProgressBar
  383. typedef enum {
  384. PROGRESS_PADDING = 16, // ProgressBar internal padding
  385. } GuiProgressBarProperty;
  386. // ScrollBar
  387. typedef enum {
  388. ARROWS_SIZE = 16,
  389. ARROWS_VISIBLE,
  390. SCROLL_SLIDER_PADDING, // (SLIDERBAR, SLIDER_PADDING)
  391. SCROLL_SLIDER_SIZE,
  392. SCROLL_PADDING,
  393. SCROLL_SPEED,
  394. } GuiScrollBarProperty;
  395. // CheckBox
  396. typedef enum {
  397. CHECK_PADDING = 16 // CheckBox internal check padding
  398. } GuiCheckBoxProperty;
  399. // ComboBox
  400. typedef enum {
  401. COMBO_BUTTON_WIDTH = 16, // ComboBox right button width
  402. COMBO_BUTTON_SPACING // ComboBox button separation
  403. } GuiComboBoxProperty;
  404. // DropdownBox
  405. typedef enum {
  406. ARROW_PADDING = 16, // DropdownBox arrow separation from border and items
  407. DROPDOWN_ITEMS_SPACING // DropdownBox items separation
  408. } GuiDropdownBoxProperty;
  409. // TextBox/TextBoxMulti/ValueBox/Spinner
  410. typedef enum {
  411. TEXT_INNER_PADDING = 16, // TextBox/TextBoxMulti/ValueBox/Spinner inner text padding
  412. TEXT_LINES_SPACING, // TextBoxMulti lines separation
  413. } GuiTextBoxProperty;
  414. // Spinner
  415. typedef enum {
  416. SPIN_BUTTON_WIDTH = 16, // Spinner left/right buttons width
  417. SPIN_BUTTON_SPACING, // Spinner buttons separation
  418. } GuiSpinnerProperty;
  419. // ListView
  420. typedef enum {
  421. LIST_ITEMS_HEIGHT = 16, // ListView items height
  422. LIST_ITEMS_SPACING, // ListView items separation
  423. SCROLLBAR_WIDTH, // ListView scrollbar size (usually width)
  424. SCROLLBAR_SIDE, // ListView scrollbar side (0-left, 1-right)
  425. } GuiListViewProperty;
  426. // ColorPicker
  427. typedef enum {
  428. COLOR_SELECTOR_SIZE = 16,
  429. HUEBAR_WIDTH, // ColorPicker right hue bar width
  430. HUEBAR_PADDING, // ColorPicker right hue bar separation from panel
  431. HUEBAR_SELECTOR_HEIGHT, // ColorPicker right hue bar selector height
  432. HUEBAR_SELECTOR_OVERFLOW // ColorPicker right hue bar selector overflow
  433. } GuiColorPickerProperty;
  434. #define SCROLLBAR_LEFT_SIDE 0
  435. #define SCROLLBAR_RIGHT_SIDE 1
  436. //----------------------------------------------------------------------------------
  437. // Global Variables Definition
  438. //----------------------------------------------------------------------------------
  439. // ...
  440. //----------------------------------------------------------------------------------
  441. // Module Functions Declaration
  442. //----------------------------------------------------------------------------------
  443. #if defined(__cplusplus)
  444. extern "C" { // Prevents name mangling of functions
  445. #endif
  446. // Global gui state control functions
  447. RAYGUIAPI void GuiEnable(void); // Enable gui controls (global state)
  448. RAYGUIAPI void GuiDisable(void); // Disable gui controls (global state)
  449. RAYGUIAPI void GuiLock(void); // Lock gui controls (global state)
  450. RAYGUIAPI void GuiUnlock(void); // Unlock gui controls (global state)
  451. RAYGUIAPI bool GuiIsLocked(void); // Check if gui is locked (global state)
  452. RAYGUIAPI void GuiFade(float alpha); // Set gui controls alpha (global state), alpha goes from 0.0f to 1.0f
  453. RAYGUIAPI void GuiSetState(int state); // Set gui state (global state)
  454. RAYGUIAPI int GuiGetState(void); // Get gui state (global state)
  455. // Font set/get functions
  456. RAYGUIAPI void GuiSetFont(Font font); // Set gui custom font (global state)
  457. RAYGUIAPI Font GuiGetFont(void); // Get gui custom font (global state)
  458. // Style set/get functions
  459. RAYGUIAPI void GuiSetStyle(int control, int property, int value); // Set one style property
  460. RAYGUIAPI int GuiGetStyle(int control, int property); // Get one style property
  461. // Container/separator controls, useful for controls organization
  462. RAYGUIAPI bool GuiWindowBox(Rectangle bounds, const char *title); // Window Box control, shows a window that can be closed
  463. RAYGUIAPI void GuiGroupBox(Rectangle bounds, const char *text); // Group Box control with text name
  464. RAYGUIAPI void GuiLine(Rectangle bounds, const char *text); // Line separator control, could contain text
  465. RAYGUIAPI void GuiPanel(Rectangle bounds, const char *text); // Panel control, useful to group controls
  466. RAYGUIAPI Rectangle GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector2 *scroll); // Scroll Panel control
  467. // Basic controls set
  468. RAYGUIAPI void GuiLabel(Rectangle bounds, const char *text); // Label control, shows text
  469. RAYGUIAPI bool GuiButton(Rectangle bounds, const char *text); // Button control, returns true when clicked
  470. RAYGUIAPI bool GuiLabelButton(Rectangle bounds, const char *text); // Label button control, show true when clicked
  471. RAYGUIAPI bool GuiToggle(Rectangle bounds, const char *text, bool active); // Toggle Button control, returns true when active
  472. RAYGUIAPI int GuiToggleGroup(Rectangle bounds, const char *text, int active); // Toggle Group control, returns active toggle index
  473. RAYGUIAPI bool GuiCheckBox(Rectangle bounds, const char *text, bool checked); // Check Box control, returns true when active
  474. RAYGUIAPI int GuiComboBox(Rectangle bounds, const char *text, int active); // Combo Box control, returns selected item index
  475. RAYGUIAPI bool GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMode); // Dropdown Box control, returns selected item
  476. RAYGUIAPI bool GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int maxValue, bool editMode); // Spinner control, returns selected value
  477. RAYGUIAPI bool GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, int maxValue, bool editMode); // Value Box control, updates input text with numbers
  478. RAYGUIAPI bool GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode); // Text Box control, updates input text
  479. RAYGUIAPI bool GuiTextBoxMulti(Rectangle bounds, char *text, int textSize, bool editMode); // Text Box control with multiple lines
  480. RAYGUIAPI float GuiSlider(Rectangle bounds, const char *textLeft, const char *textRight, float value, float minValue, float maxValue); // Slider control, returns selected value
  481. RAYGUIAPI float GuiSliderBar(Rectangle bounds, const char *textLeft, const char *textRight, float value, float minValue, float maxValue); // Slider Bar control, returns selected value
  482. RAYGUIAPI float GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight, float value, float minValue, float maxValue); // Progress Bar control, shows current progress value
  483. RAYGUIAPI void GuiStatusBar(Rectangle bounds, const char *text); // Status Bar control, shows info text
  484. RAYGUIAPI void GuiDummyRec(Rectangle bounds, const char *text); // Dummy control for placeholders
  485. RAYGUIAPI Vector2 GuiGrid(Rectangle bounds, const char *text, float spacing, int subdivs); // Grid control, returns mouse cell position
  486. // Advance controls set
  487. RAYGUIAPI int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int active); // List View control, returns selected list item index
  488. RAYGUIAPI int GuiListViewEx(Rectangle bounds, const char **text, int count, int *focus, int *scrollIndex, int active); // List View with extended parameters
  489. RAYGUIAPI int GuiMessageBox(Rectangle bounds, const char *title, const char *message, const char *buttons); // Message Box control, displays a message
  490. RAYGUIAPI int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, const char *buttons, char *text, int textMaxSize, int *secretViewActive); // Text Input Box control, ask for text, supports secret
  491. RAYGUIAPI Color GuiColorPicker(Rectangle bounds, const char *text, Color color); // Color Picker control (multiple color controls)
  492. RAYGUIAPI Color GuiColorPanel(Rectangle bounds, const char *text, Color color); // Color Panel control
  493. RAYGUIAPI float GuiColorBarAlpha(Rectangle bounds, const char *text, float alpha); // Color Bar Alpha control
  494. RAYGUIAPI float GuiColorBarHue(Rectangle bounds, const char *text, float value); // Color Bar Hue control
  495. // Styles loading functions
  496. RAYGUIAPI void GuiLoadStyle(const char *fileName); // Load style file over global style variable (.rgs)
  497. RAYGUIAPI void GuiLoadStyleDefault(void); // Load style default over global style
  498. // Icons functionality
  499. RAYGUIAPI const char *GuiIconText(int iconId, const char *text); // Get text with icon id prepended (if supported)
  500. #if !defined(RAYGUI_NO_ICONS)
  501. RAYGUIAPI void GuiDrawIcon(int iconId, int posX, int posY, int pixelSize, Color color);
  502. RAYGUIAPI unsigned int *GuiGetIcons(void); // Get full icons data pointer
  503. RAYGUIAPI unsigned int *GuiGetIconData(int iconId); // Get icon bit data
  504. RAYGUIAPI void GuiSetIconData(int iconId, unsigned int *data); // Set icon bit data
  505. RAYGUIAPI void GuiSetIconScale(unsigned int scale); // Set icon scale (1 by default)
  506. RAYGUIAPI void GuiSetIconPixel(int iconId, int x, int y); // Set icon pixel value
  507. RAYGUIAPI void GuiClearIconPixel(int iconId, int x, int y); // Clear icon pixel value
  508. RAYGUIAPI bool GuiCheckIconPixel(int iconId, int x, int y); // Check icon pixel value
  509. #if !defined(RAYGUI_CUSTOM_ICONS)
  510. //----------------------------------------------------------------------------------
  511. // Icons enumeration
  512. //----------------------------------------------------------------------------------
  513. typedef enum {
  514. ICON_NONE = 0,
  515. ICON_FOLDER_FILE_OPEN = 1,
  516. ICON_FILE_SAVE_CLASSIC = 2,
  517. ICON_FOLDER_OPEN = 3,
  518. ICON_FOLDER_SAVE = 4,
  519. ICON_FILE_OPEN = 5,
  520. ICON_FILE_SAVE = 6,
  521. ICON_FILE_EXPORT = 7,
  522. ICON_FILE_ADD = 8,
  523. ICON_FILE_DELETE = 9,
  524. ICON_FILETYPE_TEXT = 10,
  525. ICON_FILETYPE_AUDIO = 11,
  526. ICON_FILETYPE_IMAGE = 12,
  527. ICON_FILETYPE_PLAY = 13,
  528. ICON_FILETYPE_VIDEO = 14,
  529. ICON_FILETYPE_INFO = 15,
  530. ICON_FILE_COPY = 16,
  531. ICON_FILE_CUT = 17,
  532. ICON_FILE_PASTE = 18,
  533. ICON_CURSOR_HAND = 19,
  534. ICON_CURSOR_POINTER = 20,
  535. ICON_CURSOR_CLASSIC = 21,
  536. ICON_PENCIL = 22,
  537. ICON_PENCIL_BIG = 23,
  538. ICON_BRUSH_CLASSIC = 24,
  539. ICON_BRUSH_PAINTER = 25,
  540. ICON_WATER_DROP = 26,
  541. ICON_COLOR_PICKER = 27,
  542. ICON_RUBBER = 28,
  543. ICON_COLOR_BUCKET = 29,
  544. ICON_TEXT_T = 30,
  545. ICON_TEXT_A = 31,
  546. ICON_SCALE = 32,
  547. ICON_RESIZE = 33,
  548. ICON_FILTER_POINT = 34,
  549. ICON_FILTER_BILINEAR = 35,
  550. ICON_CROP = 36,
  551. ICON_CROP_ALPHA = 37,
  552. ICON_SQUARE_TOGGLE = 38,
  553. ICON_SYMMETRY = 39,
  554. ICON_SYMMETRY_HORIZONTAL = 40,
  555. ICON_SYMMETRY_VERTICAL = 41,
  556. ICON_LENS = 42,
  557. ICON_LENS_BIG = 43,
  558. ICON_EYE_ON = 44,
  559. ICON_EYE_OFF = 45,
  560. ICON_FILTER_TOP = 46,
  561. ICON_FILTER = 47,
  562. ICON_TARGET_POINT = 48,
  563. ICON_TARGET_SMALL = 49,
  564. ICON_TARGET_BIG = 50,
  565. ICON_TARGET_MOVE = 51,
  566. ICON_CURSOR_MOVE = 52,
  567. ICON_CURSOR_SCALE = 53,
  568. ICON_CURSOR_SCALE_RIGHT = 54,
  569. ICON_CURSOR_SCALE_LEFT = 55,
  570. ICON_UNDO = 56,
  571. ICON_REDO = 57,
  572. ICON_REREDO = 58,
  573. ICON_MUTATE = 59,
  574. ICON_ROTATE = 60,
  575. ICON_REPEAT = 61,
  576. ICON_SHUFFLE = 62,
  577. ICON_EMPTYBOX = 63,
  578. ICON_TARGET = 64,
  579. ICON_TARGET_SMALL_FILL = 65,
  580. ICON_TARGET_BIG_FILL = 66,
  581. ICON_TARGET_MOVE_FILL = 67,
  582. ICON_CURSOR_MOVE_FILL = 68,
  583. ICON_CURSOR_SCALE_FILL = 69,
  584. ICON_CURSOR_SCALE_RIGHT_FILL = 70,
  585. ICON_CURSOR_SCALE_LEFT_FILL = 71,
  586. ICON_UNDO_FILL = 72,
  587. ICON_REDO_FILL = 73,
  588. ICON_REREDO_FILL = 74,
  589. ICON_MUTATE_FILL = 75,
  590. ICON_ROTATE_FILL = 76,
  591. ICON_REPEAT_FILL = 77,
  592. ICON_SHUFFLE_FILL = 78,
  593. ICON_EMPTYBOX_SMALL = 79,
  594. ICON_BOX = 80,
  595. ICON_BOX_TOP = 81,
  596. ICON_BOX_TOP_RIGHT = 82,
  597. ICON_BOX_RIGHT = 83,
  598. ICON_BOX_BOTTOM_RIGHT = 84,
  599. ICON_BOX_BOTTOM = 85,
  600. ICON_BOX_BOTTOM_LEFT = 86,
  601. ICON_BOX_LEFT = 87,
  602. ICON_BOX_TOP_LEFT = 88,
  603. ICON_BOX_CENTER = 89,
  604. ICON_BOX_CIRCLE_MASK = 90,
  605. ICON_POT = 91,
  606. ICON_ALPHA_MULTIPLY = 92,
  607. ICON_ALPHA_CLEAR = 93,
  608. ICON_DITHERING = 94,
  609. ICON_MIPMAPS = 95,
  610. ICON_BOX_GRID = 96,
  611. ICON_GRID = 97,
  612. ICON_BOX_CORNERS_SMALL = 98,
  613. ICON_BOX_CORNERS_BIG = 99,
  614. ICON_FOUR_BOXES = 100,
  615. ICON_GRID_FILL = 101,
  616. ICON_BOX_MULTISIZE = 102,
  617. ICON_ZOOM_SMALL = 103,
  618. ICON_ZOOM_MEDIUM = 104,
  619. ICON_ZOOM_BIG = 105,
  620. ICON_ZOOM_ALL = 106,
  621. ICON_ZOOM_CENTER = 107,
  622. ICON_BOX_DOTS_SMALL = 108,
  623. ICON_BOX_DOTS_BIG = 109,
  624. ICON_BOX_CONCENTRIC = 110,
  625. ICON_BOX_GRID_BIG = 111,
  626. ICON_OK_TICK = 112,
  627. ICON_CROSS = 113,
  628. ICON_ARROW_LEFT = 114,
  629. ICON_ARROW_RIGHT = 115,
  630. ICON_ARROW_DOWN = 116,
  631. ICON_ARROW_UP = 117,
  632. ICON_ARROW_LEFT_FILL = 118,
  633. ICON_ARROW_RIGHT_FILL = 119,
  634. ICON_ARROW_DOWN_FILL = 120,
  635. ICON_ARROW_UP_FILL = 121,
  636. ICON_AUDIO = 122,
  637. ICON_FX = 123,
  638. ICON_WAVE = 124,
  639. ICON_WAVE_SINUS = 125,
  640. ICON_WAVE_SQUARE = 126,
  641. ICON_WAVE_TRIANGULAR = 127,
  642. ICON_CROSS_SMALL = 128,
  643. ICON_PLAYER_PREVIOUS = 129,
  644. ICON_PLAYER_PLAY_BACK = 130,
  645. ICON_PLAYER_PLAY = 131,
  646. ICON_PLAYER_PAUSE = 132,
  647. ICON_PLAYER_STOP = 133,
  648. ICON_PLAYER_NEXT = 134,
  649. ICON_PLAYER_RECORD = 135,
  650. ICON_MAGNET = 136,
  651. ICON_LOCK_CLOSE = 137,
  652. ICON_LOCK_OPEN = 138,
  653. ICON_CLOCK = 139,
  654. ICON_TOOLS = 140,
  655. ICON_GEAR = 141,
  656. ICON_GEAR_BIG = 142,
  657. ICON_BIN = 143,
  658. ICON_HAND_POINTER = 144,
  659. ICON_LASER = 145,
  660. ICON_COIN = 146,
  661. ICON_EXPLOSION = 147,
  662. ICON_1UP = 148,
  663. ICON_PLAYER = 149,
  664. ICON_PLAYER_JUMP = 150,
  665. ICON_KEY = 151,
  666. ICON_DEMON = 152,
  667. ICON_TEXT_POPUP = 153,
  668. ICON_GEAR_EX = 154,
  669. ICON_CRACK = 155,
  670. ICON_CRACK_POINTS = 156,
  671. ICON_STAR = 157,
  672. ICON_DOOR = 158,
  673. ICON_EXIT = 159,
  674. ICON_MODE_2D = 160,
  675. ICON_MODE_3D = 161,
  676. ICON_CUBE = 162,
  677. ICON_CUBE_FACE_TOP = 163,
  678. ICON_CUBE_FACE_LEFT = 164,
  679. ICON_CUBE_FACE_FRONT = 165,
  680. ICON_CUBE_FACE_BOTTOM = 166,
  681. ICON_CUBE_FACE_RIGHT = 167,
  682. ICON_CUBE_FACE_BACK = 168,
  683. ICON_CAMERA = 169,
  684. ICON_SPECIAL = 170,
  685. ICON_LINK_NET = 171,
  686. ICON_LINK_BOXES = 172,
  687. ICON_LINK_MULTI = 173,
  688. ICON_LINK = 174,
  689. ICON_LINK_BROKE = 175,
  690. ICON_TEXT_NOTES = 176,
  691. ICON_NOTEBOOK = 177,
  692. ICON_SUITCASE = 178,
  693. ICON_SUITCASE_ZIP = 179,
  694. ICON_MAILBOX = 180,
  695. ICON_MONITOR = 181,
  696. ICON_PRINTER = 182,
  697. ICON_PHOTO_CAMERA = 183,
  698. ICON_PHOTO_CAMERA_FLASH = 184,
  699. ICON_HOUSE = 185,
  700. ICON_HEART = 186,
  701. ICON_CORNER = 187,
  702. ICON_VERTICAL_BARS = 188,
  703. ICON_VERTICAL_BARS_FILL = 189,
  704. ICON_LIFE_BARS = 190,
  705. ICON_INFO = 191,
  706. ICON_CROSSLINE = 192,
  707. ICON_HELP = 193,
  708. ICON_FILETYPE_ALPHA = 194,
  709. ICON_FILETYPE_HOME = 195,
  710. ICON_LAYERS_VISIBLE = 196,
  711. ICON_LAYERS = 197,
  712. ICON_WINDOW = 198,
  713. ICON_HIDPI = 199,
  714. ICON_FILETYPE_BINARY = 200,
  715. ICON_HEX = 201,
  716. ICON_SHIELD = 202,
  717. ICON_FILE_NEW = 203,
  718. ICON_FOLDER_ADD = 204,
  719. ICON_ALARM = 205,
  720. ICON_206 = 206,
  721. ICON_207 = 207,
  722. ICON_208 = 208,
  723. ICON_209 = 209,
  724. ICON_210 = 210,
  725. ICON_211 = 211,
  726. ICON_212 = 212,
  727. ICON_213 = 213,
  728. ICON_214 = 214,
  729. ICON_215 = 215,
  730. ICON_216 = 216,
  731. ICON_217 = 217,
  732. ICON_218 = 218,
  733. ICON_219 = 219,
  734. ICON_220 = 220,
  735. ICON_221 = 221,
  736. ICON_222 = 222,
  737. ICON_223 = 223,
  738. ICON_224 = 224,
  739. ICON_225 = 225,
  740. ICON_226 = 226,
  741. ICON_227 = 227,
  742. ICON_228 = 228,
  743. ICON_229 = 229,
  744. ICON_230 = 230,
  745. ICON_231 = 231,
  746. ICON_232 = 232,
  747. ICON_233 = 233,
  748. ICON_234 = 234,
  749. ICON_235 = 235,
  750. ICON_236 = 236,
  751. ICON_237 = 237,
  752. ICON_238 = 238,
  753. ICON_239 = 239,
  754. ICON_240 = 240,
  755. ICON_241 = 241,
  756. ICON_242 = 242,
  757. ICON_243 = 243,
  758. ICON_244 = 244,
  759. ICON_245 = 245,
  760. ICON_246 = 246,
  761. ICON_247 = 247,
  762. ICON_248 = 248,
  763. ICON_249 = 249,
  764. ICON_250 = 250,
  765. ICON_251 = 251,
  766. ICON_252 = 252,
  767. ICON_253 = 253,
  768. ICON_254 = 254,
  769. ICON_255 = 255,
  770. } GuiIconName;
  771. #endif
  772. #endif
  773. #if defined(__cplusplus)
  774. } // Prevents name mangling of functions
  775. #endif
  776. #endif // RAYGUI_H
  777. /***********************************************************************************
  778. *
  779. * RAYGUI IMPLEMENTATION
  780. *
  781. ************************************************************************************/
  782. #if defined(RAYGUI_IMPLEMENTATION)
  783. #include <stdio.h> // Required for: FILE, fopen(), fclose(), fprintf(), feof(), fscanf(), vsprintf() [GuiLoadStyle(), GuiLoadIcons()]
  784. #include <stdlib.h> // Required for: malloc(), calloc(), free() [GuiLoadStyle(), GuiLoadIcons()]
  785. #include <string.h> // Required for: strlen() [GuiTextBox(), GuiTextBoxMulti(), GuiValueBox()], memset(), memcpy()
  786. #include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end() [TextFormat()]
  787. #include <math.h> // Required for: roundf() [GuiColorPicker()]
  788. #ifdef __cplusplus
  789. #define RAYGUI_CLITERAL(name) name
  790. #else
  791. #define RAYGUI_CLITERAL(name) (name)
  792. #endif
  793. #if !defined(RAYGUI_NO_ICONS) && !defined(RAYGUI_CUSTOM_ICONS)
  794. // Embedded icons, no external file provided
  795. #define RAYGUI_ICON_SIZE 16 // Size of icons in pixels (squared)
  796. #define RAYGUI_ICON_MAX_ICONS 256 // Maximum number of icons
  797. #define RAYGUI_ICON_MAX_NAME_LENGTH 32 // Maximum length of icon name id
  798. // Icons data is defined by bit array (every bit represents one pixel)
  799. // Those arrays are stored as unsigned int data arrays, so,
  800. // every array element defines 32 pixels (bits) of information
  801. // One icon is defined by 8 int, (8 int * 32 bit = 256 bit = 16*16 pixels)
  802. // NOTE: Number of elemens depend on RAYGUI_ICON_SIZE (by default 16x16 pixels)
  803. #define RAYGUI_ICON_DATA_ELEMENTS (RAYGUI_ICON_SIZE*RAYGUI_ICON_SIZE/32)
  804. //----------------------------------------------------------------------------------
  805. // Icons data for all gui possible icons (allocated on data segment by default)
  806. //
  807. // NOTE 1: Every icon is codified in binary form, using 1 bit per pixel, so,
  808. // every 16x16 icon requires 8 integers (16*16/32) to be stored
  809. //
  810. // NOTE 2: A different icon set could be loaded over this array using GuiLoadIcons(),
  811. // but loaded icons set must be same RAYGUI_ICON_SIZE and no more than RAYGUI_ICON_MAX_ICONS
  812. //
  813. // guiIcons size is by default: 256*(16*16/32) = 2048*4 = 8192 bytes = 8 KB
  814. //----------------------------------------------------------------------------------
  815. static unsigned int guiIcons[RAYGUI_ICON_MAX_ICONS*RAYGUI_ICON_DATA_ELEMENTS] = {
  816. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_NONE
  817. 0x3ff80000, 0x2f082008, 0x2042207e, 0x40027fc2, 0x40024002, 0x40024002, 0x40024002, 0x00007ffe, // ICON_FOLDER_FILE_OPEN
  818. 0x3ffe0000, 0x44226422, 0x400247e2, 0x5ffa4002, 0x57ea500a, 0x500a500a, 0x40025ffa, 0x00007ffe, // ICON_FILE_SAVE_CLASSIC
  819. 0x00000000, 0x0042007e, 0x40027fc2, 0x40024002, 0x41024002, 0x44424282, 0x793e4102, 0x00000100, // ICON_FOLDER_OPEN
  820. 0x00000000, 0x0042007e, 0x40027fc2, 0x40024002, 0x41024102, 0x44424102, 0x793e4282, 0x00000000, // ICON_FOLDER_SAVE
  821. 0x3ff00000, 0x201c2010, 0x20042004, 0x21042004, 0x24442284, 0x21042104, 0x20042104, 0x00003ffc, // ICON_FILE_OPEN
  822. 0x3ff00000, 0x201c2010, 0x20042004, 0x21042004, 0x21042104, 0x22842444, 0x20042104, 0x00003ffc, // ICON_FILE_SAVE
  823. 0x3ff00000, 0x201c2010, 0x00042004, 0x20041004, 0x20844784, 0x00841384, 0x20042784, 0x00003ffc, // ICON_FILE_EXPORT
  824. 0x3ff00000, 0x201c2010, 0x20042004, 0x20042004, 0x22042204, 0x22042f84, 0x20042204, 0x00003ffc, // ICON_FILE_ADD
  825. 0x3ff00000, 0x201c2010, 0x20042004, 0x20042004, 0x25042884, 0x25042204, 0x20042884, 0x00003ffc, // ICON_FILE_DELETE
  826. 0x3ff00000, 0x201c2010, 0x20042004, 0x20042ff4, 0x20042ff4, 0x20042ff4, 0x20042004, 0x00003ffc, // ICON_FILETYPE_TEXT
  827. 0x3ff00000, 0x201c2010, 0x27042004, 0x244424c4, 0x26442444, 0x20642664, 0x20042004, 0x00003ffc, // ICON_FILETYPE_AUDIO
  828. 0x3ff00000, 0x201c2010, 0x26042604, 0x20042004, 0x35442884, 0x2414222c, 0x20042004, 0x00003ffc, // ICON_FILETYPE_IMAGE
  829. 0x3ff00000, 0x201c2010, 0x20c42004, 0x22442144, 0x22442444, 0x20c42144, 0x20042004, 0x00003ffc, // ICON_FILETYPE_PLAY
  830. 0x3ff00000, 0x3ffc2ff0, 0x3f3c2ff4, 0x3dbc2eb4, 0x3dbc2bb4, 0x3f3c2eb4, 0x3ffc2ff4, 0x00002ff4, // ICON_FILETYPE_VIDEO
  831. 0x3ff00000, 0x201c2010, 0x21842184, 0x21842004, 0x21842184, 0x21842184, 0x20042184, 0x00003ffc, // ICON_FILETYPE_INFO
  832. 0x0ff00000, 0x381c0810, 0x28042804, 0x28042804, 0x28042804, 0x28042804, 0x20102ffc, 0x00003ff0, // ICON_FILE_COPY
  833. 0x00000000, 0x701c0000, 0x079c1e14, 0x55a000f0, 0x079c00f0, 0x701c1e14, 0x00000000, 0x00000000, // ICON_FILE_CUT
  834. 0x01c00000, 0x13e41bec, 0x3f841004, 0x204420c4, 0x20442044, 0x20442044, 0x207c2044, 0x00003fc0, // ICON_FILE_PASTE
  835. 0x00000000, 0x3aa00fe0, 0x2abc2aa0, 0x2aa42aa4, 0x20042aa4, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_CURSOR_HAND
  836. 0x00000000, 0x003c000c, 0x030800c8, 0x30100c10, 0x10202020, 0x04400840, 0x01800280, 0x00000000, // ICON_CURSOR_POINTER
  837. 0x00000000, 0x00180000, 0x01f00078, 0x03e007f0, 0x07c003e0, 0x04000e40, 0x00000000, 0x00000000, // ICON_CURSOR_CLASSIC
  838. 0x00000000, 0x04000000, 0x11000a00, 0x04400a80, 0x01100220, 0x00580088, 0x00000038, 0x00000000, // ICON_PENCIL
  839. 0x04000000, 0x15000a00, 0x50402880, 0x14102820, 0x05040a08, 0x015c028c, 0x007c00bc, 0x00000000, // ICON_PENCIL_BIG
  840. 0x01c00000, 0x01400140, 0x01400140, 0x0ff80140, 0x0ff80808, 0x0aa80808, 0x0aa80aa8, 0x00000ff8, // ICON_BRUSH_CLASSIC
  841. 0x1ffc0000, 0x5ffc7ffe, 0x40004000, 0x00807f80, 0x01c001c0, 0x01c001c0, 0x01c001c0, 0x00000080, // ICON_BRUSH_PAINTER
  842. 0x00000000, 0x00800000, 0x01c00080, 0x03e001c0, 0x07f003e0, 0x036006f0, 0x000001c0, 0x00000000, // ICON_WATER_DROP
  843. 0x00000000, 0x3e003800, 0x1f803f80, 0x0c201e40, 0x02080c10, 0x00840104, 0x00380044, 0x00000000, // ICON_COLOR_PICKER
  844. 0x00000000, 0x07800300, 0x1fe00fc0, 0x3f883fd0, 0x0e021f04, 0x02040402, 0x00f00108, 0x00000000, // ICON_RUBBER
  845. 0x00c00000, 0x02800140, 0x08200440, 0x20081010, 0x2ffe3004, 0x03f807fc, 0x00e001f0, 0x00000040, // ICON_COLOR_BUCKET
  846. 0x00000000, 0x21843ffc, 0x01800180, 0x01800180, 0x01800180, 0x01800180, 0x03c00180, 0x00000000, // ICON_TEXT_T
  847. 0x00800000, 0x01400180, 0x06200340, 0x0c100620, 0x1ff80c10, 0x380c1808, 0x70067004, 0x0000f80f, // ICON_TEXT_A
  848. 0x78000000, 0x50004000, 0x00004800, 0x03c003c0, 0x03c003c0, 0x00100000, 0x0002000a, 0x0000000e, // ICON_SCALE
  849. 0x75560000, 0x5e004002, 0x54001002, 0x41001202, 0x408200fe, 0x40820082, 0x40820082, 0x00006afe, // ICON_RESIZE
  850. 0x00000000, 0x3f003f00, 0x3f003f00, 0x3f003f00, 0x00400080, 0x001c0020, 0x001c001c, 0x00000000, // ICON_FILTER_POINT
  851. 0x6d800000, 0x00004080, 0x40804080, 0x40800000, 0x00406d80, 0x001c0020, 0x001c001c, 0x00000000, // ICON_FILTER_BILINEAR
  852. 0x40080000, 0x1ffe2008, 0x14081008, 0x11081208, 0x10481088, 0x10081028, 0x10047ff8, 0x00001002, // ICON_CROP
  853. 0x00100000, 0x3ffc0010, 0x2ab03550, 0x22b02550, 0x20b02150, 0x20302050, 0x2000fff0, 0x00002000, // ICON_CROP_ALPHA
  854. 0x40000000, 0x1ff82000, 0x04082808, 0x01082208, 0x00482088, 0x00182028, 0x35542008, 0x00000002, // ICON_SQUARE_TOGGLE
  855. 0x00000000, 0x02800280, 0x06c006c0, 0x0ea00ee0, 0x1e901eb0, 0x3e883e98, 0x7efc7e8c, 0x00000000, // ICON_SYMMETRY
  856. 0x01000000, 0x05600100, 0x1d480d50, 0x7d423d44, 0x3d447d42, 0x0d501d48, 0x01000560, 0x00000100, // ICON_SYMMETRY_HORIZONTAL
  857. 0x01800000, 0x04200240, 0x10080810, 0x00001ff8, 0x00007ffe, 0x0ff01ff8, 0x03c007e0, 0x00000180, // ICON_SYMMETRY_VERTICAL
  858. 0x00000000, 0x010800f0, 0x02040204, 0x02040204, 0x07f00308, 0x1c000e00, 0x30003800, 0x00000000, // ICON_LENS
  859. 0x00000000, 0x061803f0, 0x08240c0c, 0x08040814, 0x0c0c0804, 0x23f01618, 0x18002400, 0x00000000, // ICON_LENS_BIG
  860. 0x00000000, 0x00000000, 0x1c7007c0, 0x638e3398, 0x1c703398, 0x000007c0, 0x00000000, 0x00000000, // ICON_EYE_ON
  861. 0x00000000, 0x10002000, 0x04700fc0, 0x610e3218, 0x1c703098, 0x001007a0, 0x00000008, 0x00000000, // ICON_EYE_OFF
  862. 0x00000000, 0x00007ffc, 0x40047ffc, 0x10102008, 0x04400820, 0x02800280, 0x02800280, 0x00000100, // ICON_FILTER_TOP
  863. 0x00000000, 0x40027ffe, 0x10082004, 0x04200810, 0x02400240, 0x02400240, 0x01400240, 0x000000c0, // ICON_FILTER
  864. 0x00800000, 0x00800080, 0x00000080, 0x3c9e0000, 0x00000000, 0x00800080, 0x00800080, 0x00000000, // ICON_TARGET_POINT
  865. 0x00800000, 0x00800080, 0x00800080, 0x3f7e01c0, 0x008001c0, 0x00800080, 0x00800080, 0x00000000, // ICON_TARGET_SMALL
  866. 0x00800000, 0x00800080, 0x03e00080, 0x3e3e0220, 0x03e00220, 0x00800080, 0x00800080, 0x00000000, // ICON_TARGET_BIG
  867. 0x01000000, 0x04400280, 0x01000100, 0x43842008, 0x43849ab2, 0x01002008, 0x04400100, 0x01000280, // ICON_TARGET_MOVE
  868. 0x01000000, 0x04400280, 0x01000100, 0x41042108, 0x41049ff2, 0x01002108, 0x04400100, 0x01000280, // ICON_CURSOR_MOVE
  869. 0x781e0000, 0x500a4002, 0x04204812, 0x00000240, 0x02400000, 0x48120420, 0x4002500a, 0x0000781e, // ICON_CURSOR_SCALE
  870. 0x00000000, 0x20003c00, 0x24002800, 0x01000200, 0x00400080, 0x00140024, 0x003c0004, 0x00000000, // ICON_CURSOR_SCALE_RIGHT
  871. 0x00000000, 0x0004003c, 0x00240014, 0x00800040, 0x02000100, 0x28002400, 0x3c002000, 0x00000000, // ICON_CURSOR_SCALE_LEFT
  872. 0x00000000, 0x00100020, 0x10101fc8, 0x10001020, 0x10001000, 0x10001000, 0x00001fc0, 0x00000000, // ICON_UNDO
  873. 0x00000000, 0x08000400, 0x080813f8, 0x00080408, 0x00080008, 0x00080008, 0x000003f8, 0x00000000, // ICON_REDO
  874. 0x00000000, 0x3ffc0000, 0x20042004, 0x20002000, 0x20402000, 0x3f902020, 0x00400020, 0x00000000, // ICON_REREDO
  875. 0x00000000, 0x3ffc0000, 0x20042004, 0x27fc2004, 0x20202000, 0x3fc82010, 0x00200010, 0x00000000, // ICON_MUTATE
  876. 0x00000000, 0x0ff00000, 0x10081818, 0x11801008, 0x10001180, 0x18101020, 0x00100fc8, 0x00000020, // ICON_ROTATE
  877. 0x00000000, 0x04000200, 0x240429fc, 0x20042204, 0x20442004, 0x3f942024, 0x00400020, 0x00000000, // ICON_REPEAT
  878. 0x00000000, 0x20001000, 0x22104c0e, 0x00801120, 0x11200040, 0x4c0e2210, 0x10002000, 0x00000000, // ICON_SHUFFLE
  879. 0x7ffe0000, 0x50024002, 0x44024802, 0x41024202, 0x40424082, 0x40124022, 0x4002400a, 0x00007ffe, // ICON_EMPTYBOX
  880. 0x00800000, 0x03e00080, 0x08080490, 0x3c9e0808, 0x08080808, 0x03e00490, 0x00800080, 0x00000000, // ICON_TARGET
  881. 0x00800000, 0x00800080, 0x00800080, 0x3ffe01c0, 0x008001c0, 0x00800080, 0x00800080, 0x00000000, // ICON_TARGET_SMALL_FILL
  882. 0x00800000, 0x00800080, 0x03e00080, 0x3ffe03e0, 0x03e003e0, 0x00800080, 0x00800080, 0x00000000, // ICON_TARGET_BIG_FILL
  883. 0x01000000, 0x07c00380, 0x01000100, 0x638c2008, 0x638cfbbe, 0x01002008, 0x07c00100, 0x01000380, // ICON_TARGET_MOVE_FILL
  884. 0x01000000, 0x07c00380, 0x01000100, 0x610c2108, 0x610cfffe, 0x01002108, 0x07c00100, 0x01000380, // ICON_CURSOR_MOVE_FILL
  885. 0x781e0000, 0x6006700e, 0x04204812, 0x00000240, 0x02400000, 0x48120420, 0x700e6006, 0x0000781e, // ICON_CURSOR_SCALE_FILL
  886. 0x00000000, 0x38003c00, 0x24003000, 0x01000200, 0x00400080, 0x000c0024, 0x003c001c, 0x00000000, // ICON_CURSOR_SCALE_RIGHT_FILL
  887. 0x00000000, 0x001c003c, 0x0024000c, 0x00800040, 0x02000100, 0x30002400, 0x3c003800, 0x00000000, // ICON_CURSOR_SCALE_LEFT_FILL
  888. 0x00000000, 0x00300020, 0x10301ff8, 0x10001020, 0x10001000, 0x10001000, 0x00001fc0, 0x00000000, // ICON_UNDO_FILL
  889. 0x00000000, 0x0c000400, 0x0c081ff8, 0x00080408, 0x00080008, 0x00080008, 0x000003f8, 0x00000000, // ICON_REDO_FILL
  890. 0x00000000, 0x3ffc0000, 0x20042004, 0x20002000, 0x20402000, 0x3ff02060, 0x00400060, 0x00000000, // ICON_REREDO_FILL
  891. 0x00000000, 0x3ffc0000, 0x20042004, 0x27fc2004, 0x20202000, 0x3ff82030, 0x00200030, 0x00000000, // ICON_MUTATE_FILL
  892. 0x00000000, 0x0ff00000, 0x10081818, 0x11801008, 0x10001180, 0x18301020, 0x00300ff8, 0x00000020, // ICON_ROTATE_FILL
  893. 0x00000000, 0x06000200, 0x26042ffc, 0x20042204, 0x20442004, 0x3ff42064, 0x00400060, 0x00000000, // ICON_REPEAT_FILL
  894. 0x00000000, 0x30001000, 0x32107c0e, 0x00801120, 0x11200040, 0x7c0e3210, 0x10003000, 0x00000000, // ICON_SHUFFLE_FILL
  895. 0x00000000, 0x30043ffc, 0x24042804, 0x21042204, 0x20442084, 0x20142024, 0x3ffc200c, 0x00000000, // ICON_EMPTYBOX_SMALL
  896. 0x00000000, 0x20043ffc, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_BOX
  897. 0x00000000, 0x23c43ffc, 0x23c423c4, 0x200423c4, 0x20042004, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_BOX_TOP
  898. 0x00000000, 0x3e043ffc, 0x3e043e04, 0x20043e04, 0x20042004, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_BOX_TOP_RIGHT
  899. 0x00000000, 0x20043ffc, 0x20042004, 0x3e043e04, 0x3e043e04, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_BOX_RIGHT
  900. 0x00000000, 0x20043ffc, 0x20042004, 0x20042004, 0x3e042004, 0x3e043e04, 0x3ffc3e04, 0x00000000, // ICON_BOX_BOTTOM_RIGHT
  901. 0x00000000, 0x20043ffc, 0x20042004, 0x20042004, 0x23c42004, 0x23c423c4, 0x3ffc23c4, 0x00000000, // ICON_BOX_BOTTOM
  902. 0x00000000, 0x20043ffc, 0x20042004, 0x20042004, 0x207c2004, 0x207c207c, 0x3ffc207c, 0x00000000, // ICON_BOX_BOTTOM_LEFT
  903. 0x00000000, 0x20043ffc, 0x20042004, 0x207c207c, 0x207c207c, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_BOX_LEFT
  904. 0x00000000, 0x207c3ffc, 0x207c207c, 0x2004207c, 0x20042004, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_BOX_TOP_LEFT
  905. 0x00000000, 0x20043ffc, 0x20042004, 0x23c423c4, 0x23c423c4, 0x20042004, 0x3ffc2004, 0x00000000, // ICON_BOX_CENTER
  906. 0x7ffe0000, 0x40024002, 0x47e24182, 0x4ff247e2, 0x47e24ff2, 0x418247e2, 0x40024002, 0x00007ffe, // ICON_BOX_CIRCLE_MASK
  907. 0x7fff0000, 0x40014001, 0x40014001, 0x49555ddd, 0x4945495d, 0x400149c5, 0x40014001, 0x00007fff, // ICON_POT
  908. 0x7ffe0000, 0x53327332, 0x44ce4cce, 0x41324332, 0x404e40ce, 0x48125432, 0x4006540e, 0x00007ffe, // ICON_ALPHA_MULTIPLY
  909. 0x7ffe0000, 0x53327332, 0x44ce4cce, 0x41324332, 0x5c4e40ce, 0x44124432, 0x40065c0e, 0x00007ffe, // ICON_ALPHA_CLEAR
  910. 0x7ffe0000, 0x42fe417e, 0x42fe417e, 0x42fe417e, 0x42fe417e, 0x42fe417e, 0x42fe417e, 0x00007ffe, // ICON_DITHERING
  911. 0x07fe0000, 0x1ffa0002, 0x7fea000a, 0x402a402a, 0x5b2a512a, 0x5128552a, 0x40205128, 0x00007fe0, // ICON_MIPMAPS
  912. 0x00000000, 0x1ff80000, 0x12481248, 0x12481ff8, 0x1ff81248, 0x12481248, 0x00001ff8, 0x00000000, // ICON_BOX_GRID
  913. 0x12480000, 0x7ffe1248, 0x12481248, 0x12487ffe, 0x7ffe1248, 0x12481248, 0x12487ffe, 0x00001248, // ICON_GRID
  914. 0x00000000, 0x1c380000, 0x1c3817e8, 0x08100810, 0x08100810, 0x17e81c38, 0x00001c38, 0x00000000, // ICON_BOX_CORNERS_SMALL
  915. 0x700e0000, 0x700e5ffa, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x5ffa700e, 0x0000700e, // ICON_BOX_CORNERS_BIG
  916. 0x3f7e0000, 0x21422142, 0x21422142, 0x00003f7e, 0x21423f7e, 0x21422142, 0x3f7e2142, 0x00000000, // ICON_FOUR_BOXES
  917. 0x00000000, 0x3bb80000, 0x3bb83bb8, 0x3bb80000, 0x3bb83bb8, 0x3bb80000, 0x3bb83bb8, 0x00000000, // ICON_GRID_FILL
  918. 0x7ffe0000, 0x7ffe7ffe, 0x77fe7000, 0x77fe77fe, 0x777e7700, 0x777e777e, 0x777e777e, 0x0000777e, // ICON_BOX_MULTISIZE
  919. 0x781e0000, 0x40024002, 0x00004002, 0x01800000, 0x00000180, 0x40020000, 0x40024002, 0x0000781e, // ICON_ZOOM_SMALL
  920. 0x781e0000, 0x40024002, 0x00004002, 0x03c003c0, 0x03c003c0, 0x40020000, 0x40024002, 0x0000781e, // ICON_ZOOM_MEDIUM
  921. 0x781e0000, 0x40024002, 0x07e04002, 0x07e007e0, 0x07e007e0, 0x400207e0, 0x40024002, 0x0000781e, // ICON_ZOOM_BIG
  922. 0x781e0000, 0x5ffa4002, 0x1ff85ffa, 0x1ff81ff8, 0x1ff81ff8, 0x5ffa1ff8, 0x40025ffa, 0x0000781e, // ICON_ZOOM_ALL
  923. 0x00000000, 0x2004381c, 0x00002004, 0x00000000, 0x00000000, 0x20040000, 0x381c2004, 0x00000000, // ICON_ZOOM_CENTER
  924. 0x00000000, 0x1db80000, 0x10081008, 0x10080000, 0x00001008, 0x10081008, 0x00001db8, 0x00000000, // ICON_BOX_DOTS_SMALL
  925. 0x35560000, 0x00002002, 0x00002002, 0x00002002, 0x00002002, 0x00002002, 0x35562002, 0x00000000, // ICON_BOX_DOTS_BIG
  926. 0x7ffe0000, 0x40024002, 0x48124ff2, 0x49924812, 0x48124992, 0x4ff24812, 0x40024002, 0x00007ffe, // ICON_BOX_CONCENTRIC
  927. 0x00000000, 0x10841ffc, 0x10841084, 0x1ffc1084, 0x10841084, 0x10841084, 0x00001ffc, 0x00000000, // ICON_BOX_GRID_BIG
  928. 0x00000000, 0x00000000, 0x10000000, 0x04000800, 0x01040200, 0x00500088, 0x00000020, 0x00000000, // ICON_OK_TICK
  929. 0x00000000, 0x10080000, 0x04200810, 0x01800240, 0x02400180, 0x08100420, 0x00001008, 0x00000000, // ICON_CROSS
  930. 0x00000000, 0x02000000, 0x00800100, 0x00200040, 0x00200010, 0x00800040, 0x02000100, 0x00000000, // ICON_ARROW_LEFT
  931. 0x00000000, 0x00400000, 0x01000080, 0x04000200, 0x04000800, 0x01000200, 0x00400080, 0x00000000, // ICON_ARROW_RIGHT
  932. 0x00000000, 0x00000000, 0x00000000, 0x08081004, 0x02200410, 0x00800140, 0x00000000, 0x00000000, // ICON_ARROW_DOWN
  933. 0x00000000, 0x00000000, 0x01400080, 0x04100220, 0x10040808, 0x00000000, 0x00000000, 0x00000000, // ICON_ARROW_UP
  934. 0x00000000, 0x02000000, 0x03800300, 0x03e003c0, 0x03e003f0, 0x038003c0, 0x02000300, 0x00000000, // ICON_ARROW_LEFT_FILL
  935. 0x00000000, 0x00400000, 0x01c000c0, 0x07c003c0, 0x07c00fc0, 0x01c003c0, 0x004000c0, 0x00000000, // ICON_ARROW_RIGHT_FILL
  936. 0x00000000, 0x00000000, 0x00000000, 0x0ff81ffc, 0x03e007f0, 0x008001c0, 0x00000000, 0x00000000, // ICON_ARROW_DOWN_FILL
  937. 0x00000000, 0x00000000, 0x01c00080, 0x07f003e0, 0x1ffc0ff8, 0x00000000, 0x00000000, 0x00000000, // ICON_ARROW_UP_FILL
  938. 0x00000000, 0x18a008c0, 0x32881290, 0x24822686, 0x26862482, 0x12903288, 0x08c018a0, 0x00000000, // ICON_AUDIO
  939. 0x00000000, 0x04800780, 0x004000c0, 0x662000f0, 0x08103c30, 0x130a0e18, 0x0000318e, 0x00000000, // ICON_FX
  940. 0x00000000, 0x00800000, 0x08880888, 0x2aaa0a8a, 0x0a8a2aaa, 0x08880888, 0x00000080, 0x00000000, // ICON_WAVE
  941. 0x00000000, 0x00600000, 0x01080090, 0x02040108, 0x42044204, 0x24022402, 0x00001800, 0x00000000, // ICON_WAVE_SINUS
  942. 0x00000000, 0x07f80000, 0x04080408, 0x04080408, 0x04080408, 0x7c0e0408, 0x00000000, 0x00000000, // ICON_WAVE_SQUARE
  943. 0x00000000, 0x00000000, 0x00a00040, 0x22084110, 0x08021404, 0x00000000, 0x00000000, 0x00000000, // ICON_WAVE_TRIANGULAR
  944. 0x00000000, 0x00000000, 0x04200000, 0x01800240, 0x02400180, 0x00000420, 0x00000000, 0x00000000, // ICON_CROSS_SMALL
  945. 0x00000000, 0x18380000, 0x12281428, 0x10a81128, 0x112810a8, 0x14281228, 0x00001838, 0x00000000, // ICON_PLAYER_PREVIOUS
  946. 0x00000000, 0x18000000, 0x11801600, 0x10181060, 0x10601018, 0x16001180, 0x00001800, 0x00000000, // ICON_PLAYER_PLAY_BACK
  947. 0x00000000, 0x00180000, 0x01880068, 0x18080608, 0x06081808, 0x00680188, 0x00000018, 0x00000000, // ICON_PLAYER_PLAY
  948. 0x00000000, 0x1e780000, 0x12481248, 0x12481248, 0x12481248, 0x12481248, 0x00001e78, 0x00000000, // ICON_PLAYER_PAUSE
  949. 0x00000000, 0x1ff80000, 0x10081008, 0x10081008, 0x10081008, 0x10081008, 0x00001ff8, 0x00000000, // ICON_PLAYER_STOP
  950. 0x00000000, 0x1c180000, 0x14481428, 0x15081488, 0x14881508, 0x14281448, 0x00001c18, 0x00000000, // ICON_PLAYER_NEXT
  951. 0x00000000, 0x03c00000, 0x08100420, 0x10081008, 0x10081008, 0x04200810, 0x000003c0, 0x00000000, // ICON_PLAYER_RECORD
  952. 0x00000000, 0x0c3007e0, 0x13c81818, 0x14281668, 0x14281428, 0x1c381c38, 0x08102244, 0x00000000, // ICON_MAGNET
  953. 0x07c00000, 0x08200820, 0x3ff80820, 0x23882008, 0x21082388, 0x20082108, 0x1ff02008, 0x00000000, // ICON_LOCK_CLOSE
  954. 0x07c00000, 0x08000800, 0x3ff80800, 0x23882008, 0x21082388, 0x20082108, 0x1ff02008, 0x00000000, // ICON_LOCK_OPEN
  955. 0x01c00000, 0x0c180770, 0x3086188c, 0x60832082, 0x60034781, 0x30062002, 0x0c18180c, 0x01c00770, // ICON_CLOCK
  956. 0x0a200000, 0x1b201b20, 0x04200e20, 0x04200420, 0x04700420, 0x0e700e70, 0x0e700e70, 0x04200e70, // ICON_TOOLS
  957. 0x01800000, 0x3bdc318c, 0x0ff01ff8, 0x7c3e1e78, 0x1e787c3e, 0x1ff80ff0, 0x318c3bdc, 0x00000180, // ICON_GEAR
  958. 0x01800000, 0x3ffc318c, 0x1c381ff8, 0x781e1818, 0x1818781e, 0x1ff81c38, 0x318c3ffc, 0x00000180, // ICON_GEAR_BIG
  959. 0x00000000, 0x08080ff8, 0x08081ffc, 0x0aa80aa8, 0x0aa80aa8, 0x0aa80aa8, 0x08080aa8, 0x00000ff8, // ICON_BIN
  960. 0x00000000, 0x00000000, 0x20043ffc, 0x08043f84, 0x04040f84, 0x04040784, 0x000007fc, 0x00000000, // ICON_HAND_POINTER
  961. 0x00000000, 0x24400400, 0x00001480, 0x6efe0e00, 0x00000e00, 0x24401480, 0x00000400, 0x00000000, // ICON_LASER
  962. 0x00000000, 0x03c00000, 0x08300460, 0x11181118, 0x11181118, 0x04600830, 0x000003c0, 0x00000000, // ICON_COIN
  963. 0x00000000, 0x10880080, 0x06c00810, 0x366c07e0, 0x07e00240, 0x00001768, 0x04200240, 0x00000000, // ICON_EXPLOSION
  964. 0x00000000, 0x3d280000, 0x2528252c, 0x3d282528, 0x05280528, 0x05e80528, 0x00000000, 0x00000000, // ICON_1UP
  965. 0x01800000, 0x03c003c0, 0x018003c0, 0x0ff007e0, 0x0bd00bd0, 0x0a500bd0, 0x02400240, 0x02400240, // ICON_PLAYER
  966. 0x01800000, 0x03c003c0, 0x118013c0, 0x03c81ff8, 0x07c003c8, 0x04400440, 0x0c080478, 0x00000000, // ICON_PLAYER_JUMP
  967. 0x3ff80000, 0x30183ff8, 0x30183018, 0x3ff83ff8, 0x03000300, 0x03c003c0, 0x03e00300, 0x000003e0, // ICON_KEY
  968. 0x3ff80000, 0x3ff83ff8, 0x33983ff8, 0x3ff83398, 0x3ff83ff8, 0x00000540, 0x0fe00aa0, 0x00000fe0, // ICON_DEMON
  969. 0x00000000, 0x0ff00000, 0x20041008, 0x25442004, 0x10082004, 0x06000bf0, 0x00000300, 0x00000000, // ICON_TEXT_POPUP
  970. 0x00000000, 0x11440000, 0x07f00be8, 0x1c1c0e38, 0x1c1c0c18, 0x07f00e38, 0x11440be8, 0x00000000, // ICON_GEAR_EX
  971. 0x00000000, 0x20080000, 0x0c601010, 0x07c00fe0, 0x07c007c0, 0x0c600fe0, 0x20081010, 0x00000000, // ICON_CRACK
  972. 0x00000000, 0x20080000, 0x0c601010, 0x04400fe0, 0x04405554, 0x0c600fe0, 0x20081010, 0x00000000, // ICON_CRACK_POINTS
  973. 0x00000000, 0x00800080, 0x01c001c0, 0x1ffc3ffe, 0x03e007f0, 0x07f003e0, 0x0c180770, 0x00000808, // ICON_STAR
  974. 0x0ff00000, 0x08180810, 0x08100818, 0x0a100810, 0x08180810, 0x08100818, 0x08100810, 0x00001ff8, // ICON_DOOR
  975. 0x0ff00000, 0x08100810, 0x08100810, 0x10100010, 0x4f902010, 0x10102010, 0x08100010, 0x00000ff0, // ICON_EXIT
  976. 0x00040000, 0x001f000e, 0x0ef40004, 0x12f41284, 0x0ef41214, 0x10040004, 0x7ffc3004, 0x10003000, // ICON_MODE_2D
  977. 0x78040000, 0x501f600e, 0x0ef44004, 0x12f41284, 0x0ef41284, 0x10140004, 0x7ffc300c, 0x10003000, // ICON_MODE_3D
  978. 0x7fe00000, 0x50286030, 0x47fe4804, 0x44224402, 0x44224422, 0x241275e2, 0x0c06140a, 0x000007fe, // ICON_CUBE
  979. 0x7fe00000, 0x5ff87ff0, 0x47fe4ffc, 0x44224402, 0x44224422, 0x241275e2, 0x0c06140a, 0x000007fe, // ICON_CUBE_FACE_TOP
  980. 0x7fe00000, 0x50386030, 0x47fe483c, 0x443e443e, 0x443e443e, 0x241e75fe, 0x0c06140e, 0x000007fe, // ICON_CUBE_FACE_LEFT
  981. 0x7fe00000, 0x50286030, 0x47fe4804, 0x47fe47fe, 0x47fe47fe, 0x27fe77fe, 0x0ffe17fe, 0x000007fe, // ICON_CUBE_FACE_FRONT
  982. 0x7fe00000, 0x50286030, 0x47fe4804, 0x44224402, 0x44224422, 0x3ff27fe2, 0x0ffe1ffa, 0x000007fe, // ICON_CUBE_FACE_BOTTOM
  983. 0x7fe00000, 0x70286030, 0x7ffe7804, 0x7c227c02, 0x7c227c22, 0x3c127de2, 0x0c061c0a, 0x000007fe, // ICON_CUBE_FACE_RIGHT
  984. 0x7fe00000, 0x7fe87ff0, 0x7ffe7fe4, 0x7fe27fe2, 0x7fe27fe2, 0x24127fe2, 0x0c06140a, 0x000007fe, // ICON_CUBE_FACE_BACK
  985. 0x00000000, 0x2a0233fe, 0x22022602, 0x22022202, 0x2a022602, 0x00a033fe, 0x02080110, 0x00000000, // ICON_CAMERA
  986. 0x00000000, 0x200c3ffc, 0x000c000c, 0x3ffc000c, 0x30003000, 0x30003000, 0x3ffc3004, 0x00000000, // ICON_SPECIAL
  987. 0x00000000, 0x0022003e, 0x012201e2, 0x0100013e, 0x01000100, 0x79000100, 0x4f004900, 0x00007800, // ICON_LINK_NET
  988. 0x00000000, 0x44007c00, 0x45004600, 0x00627cbe, 0x00620022, 0x45007cbe, 0x44004600, 0x00007c00, // ICON_LINK_BOXES
  989. 0x00000000, 0x0044007c, 0x0010007c, 0x3f100010, 0x3f1021f0, 0x3f100010, 0x3f0021f0, 0x00000000, // ICON_LINK_MULTI
  990. 0x00000000, 0x0044007c, 0x00440044, 0x0010007c, 0x00100010, 0x44107c10, 0x440047f0, 0x00007c00, // ICON_LINK
  991. 0x00000000, 0x0044007c, 0x00440044, 0x0000007c, 0x00000010, 0x44007c10, 0x44004550, 0x00007c00, // ICON_LINK_BROKE
  992. 0x02a00000, 0x22a43ffc, 0x20042004, 0x20042ff4, 0x20042ff4, 0x20042ff4, 0x20042004, 0x00003ffc, // ICON_TEXT_NOTES
  993. 0x3ffc0000, 0x20042004, 0x245e27c4, 0x27c42444, 0x2004201e, 0x201e2004, 0x20042004, 0x00003ffc, // ICON_NOTEBOOK
  994. 0x00000000, 0x07e00000, 0x04200420, 0x24243ffc, 0x24242424, 0x24242424, 0x3ffc2424, 0x00000000, // ICON_SUITCASE
  995. 0x00000000, 0x0fe00000, 0x08200820, 0x40047ffc, 0x7ffc5554, 0x40045554, 0x7ffc4004, 0x00000000, // ICON_SUITCASE_ZIP
  996. 0x00000000, 0x20043ffc, 0x3ffc2004, 0x13c81008, 0x100813c8, 0x10081008, 0x1ff81008, 0x00000000, // ICON_MAILBOX
  997. 0x00000000, 0x40027ffe, 0x5ffa5ffa, 0x5ffa5ffa, 0x40025ffa, 0x03c07ffe, 0x1ff81ff8, 0x00000000, // ICON_MONITOR
  998. 0x0ff00000, 0x6bfe7ffe, 0x7ffe7ffe, 0x68167ffe, 0x08106816, 0x08100810, 0x0ff00810, 0x00000000, // ICON_PRINTER
  999. 0x3ff80000, 0xfffe2008, 0x870a8002, 0x904a888a, 0x904a904a, 0x870a888a, 0xfffe8002, 0x00000000, // ICON_PHOTO_CAMERA
  1000. 0x0fc00000, 0xfcfe0cd8, 0x8002fffe, 0x84428382, 0x84428442, 0x80028382, 0xfffe8002, 0x00000000, // ICON_PHOTO_CAMERA_FLASH
  1001. 0x00000000, 0x02400180, 0x08100420, 0x20041008, 0x23c42004, 0x22442244, 0x3ffc2244, 0x00000000, // ICON_HOUSE
  1002. 0x00000000, 0x1c700000, 0x3ff83ef8, 0x3ff83ff8, 0x0fe01ff0, 0x038007c0, 0x00000100, 0x00000000, // ICON_HEART
  1003. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0xe000c000, // ICON_CORNER
  1004. 0x00000000, 0x14001c00, 0x15c01400, 0x15401540, 0x155c1540, 0x15541554, 0x1ddc1554, 0x00000000, // ICON_VERTICAL_BARS
  1005. 0x00000000, 0x03000300, 0x1b001b00, 0x1b601b60, 0x1b6c1b60, 0x1b6c1b6c, 0x1b6c1b6c, 0x00000000, // ICON_VERTICAL_BARS_FILL
  1006. 0x00000000, 0x00000000, 0x403e7ffe, 0x7ffe403e, 0x7ffe0000, 0x43fe43fe, 0x00007ffe, 0x00000000, // ICON_LIFE_BARS
  1007. 0x7ffc0000, 0x43844004, 0x43844284, 0x43844004, 0x42844284, 0x42844284, 0x40044384, 0x00007ffc, // ICON_INFO
  1008. 0x40008000, 0x10002000, 0x04000800, 0x01000200, 0x00400080, 0x00100020, 0x00040008, 0x00010002, // ICON_CROSSLINE
  1009. 0x00000000, 0x1ff01ff0, 0x18301830, 0x1f001830, 0x03001f00, 0x00000300, 0x03000300, 0x00000000, // ICON_HELP
  1010. 0x3ff00000, 0x2abc3550, 0x2aac3554, 0x2aac3554, 0x2aac3554, 0x2aac3554, 0x2aac3554, 0x00003ffc, // ICON_FILETYPE_ALPHA
  1011. 0x3ff00000, 0x201c2010, 0x22442184, 0x28142424, 0x29942814, 0x2ff42994, 0x20042004, 0x00003ffc, // ICON_FILETYPE_HOME
  1012. 0x07fe0000, 0x04020402, 0x7fe20402, 0x44224422, 0x44224422, 0x402047fe, 0x40204020, 0x00007fe0, // ICON_LAYERS_VISIBLE
  1013. 0x07fe0000, 0x04020402, 0x7c020402, 0x44024402, 0x44024402, 0x402047fe, 0x40204020, 0x00007fe0, // ICON_LAYERS
  1014. 0x00000000, 0x40027ffe, 0x7ffe4002, 0x40024002, 0x40024002, 0x40024002, 0x7ffe4002, 0x00000000, // ICON_WINDOW
  1015. 0x09100000, 0x09f00910, 0x09100910, 0x00000910, 0x24a2779e, 0x27a224a2, 0x709e20a2, 0x00000000, // ICON_HIDPI
  1016. 0x3ff00000, 0x201c2010, 0x2a842e84, 0x2e842a84, 0x2ba42004, 0x2aa42aa4, 0x20042ba4, 0x00003ffc, // ICON_FILETYPE_BINARY
  1017. 0x00000000, 0x00000000, 0x00120012, 0x4a5e4bd2, 0x485233d2, 0x00004bd2, 0x00000000, 0x00000000, // ICON_HEX
  1018. 0x01800000, 0x381c0660, 0x23c42004, 0x23c42044, 0x13c82204, 0x08101008, 0x02400420, 0x00000180, // ICON_SHIELD
  1019. 0x007e0000, 0x20023fc2, 0x40227fe2, 0x400a403a, 0x400a400a, 0x400a400a, 0x4008400e, 0x00007ff8, // ICON_FILE_NEW
  1020. 0x00000000, 0x0042007e, 0x40027fc2, 0x44024002, 0x5f024402, 0x44024402, 0x7ffe4002, 0x00000000, // ICON_FOLDER_ADD
  1021. 0x44220000, 0x12482244, 0xf3cf0000, 0x14280420, 0x48122424, 0x08100810, 0x1ff81008, 0x03c00420, // ICON_ALARM
  1022. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_206
  1023. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_207
  1024. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_208
  1025. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_209
  1026. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_210
  1027. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_211
  1028. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_212
  1029. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_213
  1030. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_214
  1031. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_215
  1032. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_216
  1033. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_217
  1034. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_218
  1035. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_219
  1036. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_220
  1037. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_221
  1038. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_222
  1039. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_223
  1040. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_224
  1041. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_225
  1042. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_226
  1043. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_227
  1044. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_228
  1045. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_229
  1046. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_230
  1047. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_231
  1048. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_232
  1049. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_233
  1050. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_234
  1051. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_235
  1052. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_236
  1053. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_237
  1054. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_238
  1055. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_239
  1056. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_240
  1057. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_241
  1058. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_242
  1059. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_243
  1060. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_244
  1061. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_245
  1062. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_246
  1063. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_247
  1064. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_248
  1065. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_249
  1066. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_250
  1067. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_251
  1068. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_252
  1069. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_253
  1070. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_254
  1071. 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // ICON_255
  1072. };
  1073. #endif // !RAYGUI_NO_ICONS && !RAYGUI_CUSTOM_ICONS
  1074. #ifndef RAYGUI_ICON_SIZE
  1075. #define RAYGUI_ICON_SIZE 0
  1076. #endif
  1077. #define RAYGUI_MAX_CONTROLS 16 // Maximum number of standard controls
  1078. #define RAYGUI_MAX_PROPS_BASE 16 // Maximum number of standard properties
  1079. #define RAYGUI_MAX_PROPS_EXTENDED 8 // Maximum number of extended properties
  1080. //----------------------------------------------------------------------------------
  1081. // Types and Structures Definition
  1082. //----------------------------------------------------------------------------------
  1083. // Gui control property style color element
  1084. typedef enum { BORDER = 0, BASE, TEXT, OTHER } GuiPropertyElement;
  1085. //----------------------------------------------------------------------------------
  1086. // Global Variables Definition
  1087. //----------------------------------------------------------------------------------
  1088. static GuiState guiState = STATE_NORMAL; // Gui global state, if !STATE_NORMAL, forces defined state
  1089. static Font guiFont = { 0 }; // Gui current font (WARNING: highly coupled to raylib)
  1090. static bool guiLocked = false; // Gui lock state (no inputs processed)
  1091. static float guiAlpha = 1.0f; // Gui element transpacency on drawing
  1092. static unsigned int guiIconScale = 1; // Gui icon default scale (if icons enabled)
  1093. //----------------------------------------------------------------------------------
  1094. // Style data array for all gui style properties (allocated on data segment by default)
  1095. //
  1096. // NOTE 1: First set of BASE properties are generic to all controls but could be individually
  1097. // overwritten per control, first set of EXTENDED properties are generic to all controls and
  1098. // can not be overwritten individually but custom EXTENDED properties can be used by control
  1099. //
  1100. // NOTE 2: A new style set could be loaded over this array using GuiLoadStyle(),
  1101. // but default gui style could always be recovered with GuiLoadStyleDefault()
  1102. //
  1103. // guiStyle size is by default: 16*(16 + 8) = 384*4 = 1536 bytes = 1.5 KB
  1104. //----------------------------------------------------------------------------------
  1105. static unsigned int guiStyle[RAYGUI_MAX_CONTROLS*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED)] = { 0 };
  1106. static bool guiStyleLoaded = false; // Style loaded flag for lazy style initialization
  1107. //----------------------------------------------------------------------------------
  1108. // Standalone Mode Functions Declaration
  1109. //
  1110. // NOTE: raygui depend on some raylib input and drawing functions
  1111. // To use raygui as standalone library, below functions must be defined by the user
  1112. //----------------------------------------------------------------------------------
  1113. #if defined(RAYGUI_STANDALONE)
  1114. #define KEY_RIGHT 262
  1115. #define KEY_LEFT 263
  1116. #define KEY_DOWN 264
  1117. #define KEY_UP 265
  1118. #define KEY_BACKSPACE 259
  1119. #define KEY_ENTER 257
  1120. #define MOUSE_LEFT_BUTTON 0
  1121. // Input required functions
  1122. //-------------------------------------------------------------------------------
  1123. static Vector2 GetMousePosition(void);
  1124. static float GetMouseWheelMove(void);
  1125. static bool IsMouseButtonDown(int button);
  1126. static bool IsMouseButtonPressed(int button);
  1127. static bool IsMouseButtonReleased(int button);
  1128. static bool IsKeyDown(int key);
  1129. static bool IsKeyPressed(int key);
  1130. static int GetCharPressed(void); // -- GuiTextBox(), GuiTextBoxMulti(), GuiValueBox()
  1131. //-------------------------------------------------------------------------------
  1132. // Drawing required functions
  1133. //-------------------------------------------------------------------------------
  1134. static void DrawRectangle(int x, int y, int width, int height, Color color); // -- GuiDrawRectangle(), GuiDrawIcon()
  1135. static void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4); // -- GuiColorPicker()
  1136. //-------------------------------------------------------------------------------
  1137. // Text required functions
  1138. //-------------------------------------------------------------------------------
  1139. static Font LoadFontEx(const char *fileName, int fontSize, int *fontChars, int glyphCount); // -- GuiLoadStyle()
  1140. static Font GetFontDefault(void); // -- GuiLoadStyleDefault()
  1141. static Texture2D LoadTextureFromImage(Image image); // -- GuiLoadStyle()
  1142. static void SetShapesTexture(Texture2D tex, Rectangle rec); // -- GuiLoadStyle()
  1143. static char *LoadFileText(const char *fileName); // -- GuiLoadStyle()
  1144. static const char *GetDirectoryPath(const char *filePath); // -- GuiLoadStyle()
  1145. static Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing); // -- GetTextWidth(), GuiTextBoxMulti()
  1146. static void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint); // -- GuiDrawText()
  1147. //-------------------------------------------------------------------------------
  1148. // raylib functions already implemented in raygui
  1149. //-------------------------------------------------------------------------------
  1150. static Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value
  1151. static int ColorToInt(Color color); // Returns hexadecimal value for a Color
  1152. static Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f
  1153. static bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
  1154. static const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed'
  1155. static const char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings
  1156. static int TextToInteger(const char *text); // Get integer value from text
  1157. static int GetCodepoint(const char *text, int *bytesProcessed); // Get next codepoint in a UTF-8 encoded text
  1158. static const char *CodepointToUTF8(int codepoint, int *byteSize); // Encode codepoint into UTF-8 text (char array size returned as parameter)
  1159. static void DrawRectangleGradientV(int posX, int posY, int width, int height, Color color1, Color color2); // Draw rectangle vertical gradient
  1160. //-------------------------------------------------------------------------------
  1161. #endif // RAYGUI_STANDALONE
  1162. //----------------------------------------------------------------------------------
  1163. // Module specific Functions Declaration
  1164. //----------------------------------------------------------------------------------
  1165. static int GetTextWidth(const char *text); // Gui get text width using default font
  1166. static Rectangle GetTextBounds(int control, Rectangle bounds); // Get text bounds considering control bounds
  1167. static const char *GetTextIcon(const char *text, int *iconId); // Get text icon if provided and move text cursor
  1168. static void GuiDrawText(const char *text, Rectangle bounds, int alignment, Color tint); // Gui draw text using default font
  1169. static void GuiDrawRectangle(Rectangle rec, int borderWidth, Color borderColor, Color color); // Gui draw rectangle using default raygui style
  1170. static const char **GuiTextSplit(const char *text, int *count, int *textRow); // Split controls text into multiple strings
  1171. static Vector3 ConvertHSVtoRGB(Vector3 hsv); // Convert color data from HSV to RGB
  1172. static Vector3 ConvertRGBtoHSV(Vector3 rgb); // Convert color data from RGB to HSV
  1173. static int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue); // Scroll bar control, used by GuiScrollPanel()
  1174. //----------------------------------------------------------------------------------
  1175. // Gui Setup Functions Definition
  1176. //----------------------------------------------------------------------------------
  1177. // Enable gui global state
  1178. // NOTE: We check for STATE_DISABLED to avoid messing custom global state setups
  1179. void GuiEnable(void) { if (guiState == STATE_DISABLED) guiState = STATE_NORMAL; }
  1180. // Disable gui global state
  1181. // NOTE: We check for STATE_NORMAL to avoid messing custom global state setups
  1182. void GuiDisable(void) { if (guiState == STATE_NORMAL) guiState = STATE_DISABLED; }
  1183. // Lock gui global state
  1184. void GuiLock(void) { guiLocked = true; }
  1185. // Unlock gui global state
  1186. void GuiUnlock(void) { guiLocked = false; }
  1187. // Check if gui is locked (global state)
  1188. bool GuiIsLocked(void) { return guiLocked; }
  1189. // Set gui controls alpha global state
  1190. void GuiFade(float alpha)
  1191. {
  1192. if (alpha < 0.0f) alpha = 0.0f;
  1193. else if (alpha > 1.0f) alpha = 1.0f;
  1194. guiAlpha = alpha;
  1195. }
  1196. // Set gui state (global state)
  1197. void GuiSetState(int state) { guiState = (GuiState)state; }
  1198. // Get gui state (global state)
  1199. int GuiGetState(void) { return guiState; }
  1200. // Set custom gui font
  1201. // NOTE: Font loading/unloading is external to raygui
  1202. void GuiSetFont(Font font)
  1203. {
  1204. if (font.texture.id > 0)
  1205. {
  1206. // NOTE: If we try to setup a font but default style has not been
  1207. // lazily loaded before, it will be overwritten, so we need to force
  1208. // default style loading first
  1209. if (!guiStyleLoaded) GuiLoadStyleDefault();
  1210. guiFont = font;
  1211. GuiSetStyle(DEFAULT, TEXT_SIZE, font.baseSize);
  1212. }
  1213. }
  1214. // Get custom gui font
  1215. Font GuiGetFont(void)
  1216. {
  1217. return guiFont;
  1218. }
  1219. // Set control style property value
  1220. void GuiSetStyle(int control, int property, int value)
  1221. {
  1222. if (!guiStyleLoaded) GuiLoadStyleDefault();
  1223. guiStyle[control*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED) + property] = value;
  1224. // Default properties are propagated to all controls
  1225. if ((control == 0) && (property < RAYGUI_MAX_PROPS_BASE))
  1226. {
  1227. for (int i = 1; i < RAYGUI_MAX_CONTROLS; i++) guiStyle[i*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED) + property] = value;
  1228. }
  1229. }
  1230. // Get control style property value
  1231. int GuiGetStyle(int control, int property)
  1232. {
  1233. if (!guiStyleLoaded) GuiLoadStyleDefault();
  1234. return guiStyle[control*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED) + property];
  1235. }
  1236. //----------------------------------------------------------------------------------
  1237. // Gui Controls Functions Definition
  1238. //----------------------------------------------------------------------------------
  1239. // Window Box control
  1240. bool GuiWindowBox(Rectangle bounds, const char *title)
  1241. {
  1242. // Window title bar height (including borders)
  1243. // NOTE: This define is also used by GuiMessageBox() and GuiTextInputBox()
  1244. #if !defined(RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT)
  1245. #define RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT 24
  1246. #endif
  1247. //GuiState state = guiState;
  1248. bool clicked = false;
  1249. int statusBarHeight = RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT;
  1250. Rectangle statusBar = { bounds.x, bounds.y, bounds.width, (float)statusBarHeight };
  1251. if (bounds.height < statusBarHeight*2.0f) bounds.height = statusBarHeight*2.0f;
  1252. Rectangle windowPanel = { bounds.x, bounds.y + (float)statusBarHeight - 1, bounds.width, bounds.height - (float)statusBarHeight + 1 };
  1253. Rectangle closeButtonRec = { statusBar.x + statusBar.width - GuiGetStyle(STATUSBAR, BORDER_WIDTH) - 20,
  1254. statusBar.y + statusBarHeight/2.0f - 18.0f/2.0f, 18, 18 };
  1255. // Update control
  1256. //--------------------------------------------------------------------
  1257. // NOTE: Logic is directly managed by button
  1258. //--------------------------------------------------------------------
  1259. // Draw control
  1260. //--------------------------------------------------------------------
  1261. GuiStatusBar(statusBar, title); // Draw window header as status bar
  1262. GuiPanel(windowPanel, NULL); // Draw window base
  1263. // Draw window close button
  1264. int tempBorderWidth = GuiGetStyle(BUTTON, BORDER_WIDTH);
  1265. int tempTextAlignment = GuiGetStyle(BUTTON, TEXT_ALIGNMENT);
  1266. GuiSetStyle(BUTTON, BORDER_WIDTH, 1);
  1267. GuiSetStyle(BUTTON, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER);
  1268. #if defined(RAYGUI_NO_ICONS)
  1269. clicked = GuiButton(closeButtonRec, "x");
  1270. #else
  1271. clicked = GuiButton(closeButtonRec, GuiIconText(ICON_CROSS_SMALL, NULL));
  1272. #endif
  1273. GuiSetStyle(BUTTON, BORDER_WIDTH, tempBorderWidth);
  1274. GuiSetStyle(BUTTON, TEXT_ALIGNMENT, tempTextAlignment);
  1275. //--------------------------------------------------------------------
  1276. return clicked;
  1277. }
  1278. // Group Box control with text name
  1279. void GuiGroupBox(Rectangle bounds, const char *text)
  1280. {
  1281. #if !defined(RAYGUI_GROUPBOX_LINE_THICK)
  1282. #define RAYGUI_GROUPBOX_LINE_THICK 1
  1283. #endif
  1284. GuiState state = guiState;
  1285. // Draw control
  1286. //--------------------------------------------------------------------
  1287. GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y, RAYGUI_GROUPBOX_LINE_THICK, bounds.height }, 0, BLANK, Fade(GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? BORDER_COLOR_DISABLED : LINE_COLOR)), guiAlpha));
  1288. GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + bounds.height - 1, bounds.width, RAYGUI_GROUPBOX_LINE_THICK }, 0, BLANK, Fade(GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? BORDER_COLOR_DISABLED : LINE_COLOR)), guiAlpha));
  1289. GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x + bounds.width - 1, bounds.y, RAYGUI_GROUPBOX_LINE_THICK, bounds.height }, 0, BLANK, Fade(GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? BORDER_COLOR_DISABLED : LINE_COLOR)), guiAlpha));
  1290. GuiLine(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y - GuiGetStyle(DEFAULT, TEXT_SIZE)/2, bounds.width, (float)GuiGetStyle(DEFAULT, TEXT_SIZE) }, text);
  1291. //--------------------------------------------------------------------
  1292. }
  1293. // Line control
  1294. void GuiLine(Rectangle bounds, const char *text)
  1295. {
  1296. #if !defined(RAYGUI_LINE_ORIGIN_SIZE)
  1297. #define RAYGUI_LINE_MARGIN_TEXT 12
  1298. #endif
  1299. #if !defined(RAYGUI_LINE_TEXT_PADDING)
  1300. #define RAYGUI_LINE_TEXT_PADDING 4
  1301. #endif
  1302. GuiState state = guiState;
  1303. Color color = Fade(GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? BORDER_COLOR_DISABLED : LINE_COLOR)), guiAlpha);
  1304. // Draw control
  1305. //--------------------------------------------------------------------
  1306. if (text == NULL) GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + bounds.height/2, bounds.width, 1 }, 0, BLANK, color);
  1307. else
  1308. {
  1309. Rectangle textBounds = { 0 };
  1310. textBounds.width = (float)GetTextWidth(text);
  1311. textBounds.height = bounds.height;
  1312. textBounds.x = bounds.x + RAYGUI_LINE_MARGIN_TEXT;
  1313. textBounds.y = bounds.y;
  1314. // Draw line with embedded text label: "--- text --------------"
  1315. GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x, bounds.y + bounds.height/2, RAYGUI_LINE_MARGIN_TEXT - RAYGUI_LINE_TEXT_PADDING, 1 }, 0, BLANK, color);
  1316. GuiDrawText(text, textBounds, TEXT_ALIGN_LEFT, color);
  1317. GuiDrawRectangle(RAYGUI_CLITERAL(Rectangle){ bounds.x + 12 + textBounds.width + 4, bounds.y + bounds.height/2, bounds.width - textBounds.width - RAYGUI_LINE_MARGIN_TEXT - RAYGUI_LINE_TEXT_PADDING, 1 }, 0, BLANK, color);
  1318. }
  1319. //--------------------------------------------------------------------
  1320. }
  1321. // Panel control
  1322. void GuiPanel(Rectangle bounds, const char *text)
  1323. {
  1324. #if !defined(RAYGUI_PANEL_BORDER_WIDTH)
  1325. #define RAYGUI_PANEL_BORDER_WIDTH 1
  1326. #endif
  1327. GuiState state = guiState;
  1328. // Text will be drawn as a header bar (if provided)
  1329. Rectangle statusBar = { bounds.x, bounds.y, bounds.width, (float)RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT };
  1330. if ((text != NULL) && (bounds.height < RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT*2.0f)) bounds.height = RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT*2.0f;
  1331. if (text != NULL)
  1332. {
  1333. // Move panel bounds after the header bar
  1334. bounds.y += (float)RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT - 1;
  1335. bounds.height -= (float)RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT + 1;
  1336. }
  1337. // Draw control
  1338. //--------------------------------------------------------------------
  1339. if (text != NULL) GuiStatusBar(statusBar, text); // Draw panel header as status bar
  1340. GuiDrawRectangle(bounds, RAYGUI_PANEL_BORDER_WIDTH, Fade(GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? BORDER_COLOR_DISABLED: LINE_COLOR)), guiAlpha),
  1341. Fade(GetColor(GuiGetStyle(DEFAULT, (state == STATE_DISABLED)? BASE_COLOR_DISABLED : BACKGROUND_COLOR)), guiAlpha));
  1342. //--------------------------------------------------------------------
  1343. }
  1344. // Scroll Panel control
  1345. Rectangle GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector2 *scroll)
  1346. {
  1347. GuiState state = guiState;
  1348. Vector2 scrollPos = { 0.0f, 0.0f };
  1349. if (scroll != NULL) scrollPos = *scroll;
  1350. // Text will be drawn as a header bar (if provided)
  1351. Rectangle statusBar = { bounds.x, bounds.y, bounds.width, (float)RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT };
  1352. if (bounds.height < RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT*2.0f) bounds.height = RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT*2.0f;
  1353. if (text != NULL)
  1354. {
  1355. // Move panel bounds after the header bar
  1356. bounds.y += (float)RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT - 1;
  1357. bounds.height -= (float)RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT + 1;
  1358. }
  1359. bool hasHorizontalScrollBar = (content.width > bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH))? true : false;
  1360. bool hasVerticalScrollBar = (content.height > bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH))? true : false;
  1361. // Recheck to account for the other scrollbar being visible
  1362. if (!hasHorizontalScrollBar) hasHorizontalScrollBar = (hasVerticalScrollBar && (content.width > (bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH))))? true : false;
  1363. if (!hasVerticalScrollBar) hasVerticalScrollBar = (hasHorizontalScrollBar && (content.height > (bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH))))? true : false;
  1364. int horizontalScrollBarWidth = hasHorizontalScrollBar? GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH) : 0;
  1365. int verticalScrollBarWidth = hasVerticalScrollBar? GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH) : 0;
  1366. Rectangle horizontalScrollBar = { (float)((GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)bounds.x + verticalScrollBarWidth : (float)bounds.x) + GuiGetStyle(DEFAULT, BORDER_WIDTH), (float)bounds.y + bounds.height - horizontalScrollBarWidth - GuiGetStyle(DEFAULT, BORDER_WIDTH), (float)bounds.width - verticalScrollBarWidth - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH), (float)horizontalScrollBarWidth };
  1367. Rectangle verticalScrollBar = { (float)((GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)bounds.x + GuiGetStyle(DEFAULT, BORDER_WIDTH) : (float)bounds.x + bounds.width - verticalScrollBarWidth - GuiGetStyle(DEFAULT, BORDER_WIDTH)), (float)bounds.y + GuiGetStyle(DEFAULT, BORDER_WIDTH), (float)verticalScrollBarWidth, (float)bounds.height - horizontalScrollBarWidth - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) };
  1368. // Calculate view area (area without the scrollbars)
  1369. Rectangle view = (GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)?
  1370. RAYGUI_CLITERAL(Rectangle){ bounds.x + verticalScrollBarWidth + GuiGetStyle(DEFAULT, BORDER_WIDTH), bounds.y + GuiGetStyle(DEFAULT, BORDER_WIDTH), bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - verticalScrollBarWidth, bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - horizontalScrollBarWidth } :
  1371. RAYGUI_CLITERAL(Rectangle){ bounds.x + GuiGetStyle(DEFAULT, BORDER_WIDTH), bounds.y + GuiGetStyle(DEFAULT, BORDER_WIDTH), bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - verticalScrollBarWidth, bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - horizontalScrollBarWidth };
  1372. // Clip view area to the actual content size
  1373. if (view.width > content.width) view.width = content.width;
  1374. if (view.height > content.height) view.height = content.height;
  1375. float horizontalMin = hasHorizontalScrollBar? ((GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)-verticalScrollBarWidth : 0) - (float)GuiGetStyle(DEFAULT, BORDER_WIDTH) : (((float)GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)-verticalScrollBarWidth : 0) - (float)GuiGetStyle(DEFAULT, BORDER_WIDTH);
  1376. float horizontalMax = hasHorizontalScrollBar? content.width - bounds.width + (float)verticalScrollBarWidth + GuiGetStyle(DEFAULT, BORDER_WIDTH) - (((float)GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)verticalScrollBarWidth : 0) : (float)-GuiGetStyle(DEFAULT, BORDER_WIDTH);
  1377. float verticalMin = hasVerticalScrollBar? 0 : -1;
  1378. float verticalMax = hasVerticalScrollBar? content.height - bounds.height + (float)horizontalScrollBarWidth + (float)GuiGetStyle(DEFAULT, BORDER_WIDTH) : (float)-GuiGetStyle(DEFAULT, BORDER_WIDTH);
  1379. // Update control
  1380. //--------------------------------------------------------------------
  1381. if ((state != STATE_DISABLED) && !guiLocked)
  1382. {
  1383. Vector2 mousePoint = GetMousePosition();
  1384. // Check button state
  1385. if (CheckCollisionPointRec(mousePoint, bounds))
  1386. {
  1387. if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED;
  1388. else state = STATE_FOCUSED;
  1389. #if defined(SUPPORT_SCROLLBAR_KEY_INPUT)
  1390. if (hasHorizontalScrollBar)
  1391. {
  1392. if (IsKeyDown(KEY_RIGHT)) scrollPos.x -= GuiGetStyle(SCROLLBAR, SCROLL_SPEED);
  1393. if (IsKeyDown(KEY_LEFT)) scrollPos.x += GuiGetStyle(SCROLLBAR, SCROLL_SPEED);
  1394. }
  1395. if (hasVerticalScrollBar)
  1396. {
  1397. if (IsKeyDown(KEY_DOWN)) scrollPos.y -= GuiGetStyle(SCROLLBAR, SCROLL_SPEED);
  1398. if (IsKeyDown(KEY_UP)) scrollPos.y += GuiGetStyle(SCROLLBAR, SCROLL_SPEED);
  1399. }
  1400. #endif
  1401. float wheelMove = GetMouseWheelMove();
  1402. // Horizontal scroll (Shift + Mouse wheel)
  1403. if (hasHorizontalScrollBar && (IsKeyDown(KEY_LEFT_CONTROL) || IsKeyDown(KEY_RIGHT_SHIFT))) scrollPos.x += wheelMove*20;
  1404. else scrollPos.y += wheelMove*20; // Vertical scroll
  1405. }
  1406. }
  1407. // Normalize scroll values
  1408. if (scrollPos.x > -horizontalMin) scrollPos.x = -horizontalMin;
  1409. if (scrollPos.x < -horizontalMax) scrollPos.x = -horizontalMax;
  1410. if (scrollPos.y > -verticalMin) scrollPos.y = -verticalMin;
  1411. if (scrollPos.y < -verticalMax) scrollPos.y = -verticalMax;
  1412. //--------------------------------------------------------------------
  1413. // Draw control
  1414. //--------------------------------------------------------------------
  1415. if (text != NULL) GuiStatusBar(statusBar, text); // Draw panel header as status bar
  1416. GuiDrawRectangle(bounds, 0, BLANK, GetColor(GuiGetStyle(DEFAULT, BACKGROUND_COLOR))); // Draw background
  1417. // Save size of the scrollbar slider
  1418. const int slider = GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE);
  1419. // Draw horizontal scrollbar if visible
  1420. if (hasHorizontalScrollBar)
  1421. {
  1422. // Change scrollbar slider size to show the diff in size between the content width and the widget width
  1423. GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, (int)(((bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - verticalScrollBarWidth)/(int)content.width)*((int)bounds.width - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - verticalScrollBarWidth)));
  1424. scrollPos.x = (float)-GuiScrollBar(horizontalScrollBar, (int)-scrollPos.x, (int)horizontalMin, (int)horizontalMax);
  1425. }
  1426. else scrollPos.x = 0.0f;
  1427. // Draw vertical scrollbar if visible
  1428. if (hasVerticalScrollBar)
  1429. {
  1430. // Change scrollbar slider size to show the diff in size between the content height and the widget height
  1431. GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, (int)(((bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - horizontalScrollBarWidth)/(int)content.height)*((int)bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH) - horizontalScrollBarWidth)));
  1432. scrollPos.y = (float)-GuiScrollBar(verticalScrollBar, (int)-scrollPos.y, (int)verticalMin, (int)verticalMax);
  1433. }
  1434. else scrollPos.y = 0.0f;
  1435. // Draw detail corner rectangle if both scroll bars are visible
  1436. if (hasHorizontalScrollBar && hasVerticalScrollBar)
  1437. {
  1438. Rectangle corner = { (GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (bounds.x + GuiGetStyle(DEFAULT, BORDER_WIDTH) + 2) : (horizontalScrollBar.x + horizontalScrollBar.width + 2), verticalScrollBar.y + verticalScrollBar.height + 2, (float)horizontalScrollBarWidth - 4, (float)verticalScrollBarWidth - 4 };
  1439. GuiDrawRectangle(corner, 0, BLANK, Fade(GetColor(GuiGetStyle(LISTVIEW, TEXT + (state*3))), guiAlpha));
  1440. }
  1441. // Draw scrollbar lines depending on current state
  1442. GuiDrawRectangle(bounds, GuiGetStyle(DEFAULT, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(LISTVIEW, BORDER + (state*3))), guiAlpha), BLANK);
  1443. // Set scrollbar slider size back to the way it was before
  1444. GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, slider);
  1445. //--------------------------------------------------------------------
  1446. if (scroll != NULL) *scroll = scrollPos;
  1447. return view;
  1448. }
  1449. // Label control
  1450. void GuiLabel(Rectangle bounds, const char *text)
  1451. {
  1452. GuiState state = guiState;
  1453. // Update control
  1454. //--------------------------------------------------------------------
  1455. // ...
  1456. //--------------------------------------------------------------------
  1457. // Draw control
  1458. //--------------------------------------------------------------------
  1459. GuiDrawText(text, GetTextBounds(LABEL, bounds), GuiGetStyle(LABEL, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(LABEL, TEXT + (state*3))), guiAlpha));
  1460. //--------------------------------------------------------------------
  1461. }
  1462. // Button control, returns true when clicked
  1463. bool GuiButton(Rectangle bounds, const char *text)
  1464. {
  1465. GuiState state = guiState;
  1466. bool pressed = false;
  1467. // Update control
  1468. //--------------------------------------------------------------------
  1469. if ((state != STATE_DISABLED) && !guiLocked)
  1470. {
  1471. Vector2 mousePoint = GetMousePosition();
  1472. // Check button state
  1473. if (CheckCollisionPointRec(mousePoint, bounds))
  1474. {
  1475. if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED;
  1476. else state = STATE_FOCUSED;
  1477. if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) pressed = true;
  1478. }
  1479. }
  1480. //--------------------------------------------------------------------
  1481. // Draw control
  1482. //--------------------------------------------------------------------
  1483. GuiDrawRectangle(bounds, GuiGetStyle(BUTTON, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(BUTTON, BORDER + (state*3))), guiAlpha), Fade(GetColor(GuiGetStyle(BUTTON, BASE + (state*3))), guiAlpha));
  1484. GuiDrawText(text, GetTextBounds(BUTTON, bounds), GuiGetStyle(BUTTON, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(BUTTON, TEXT + (state*3))), guiAlpha));
  1485. //------------------------------------------------------------------
  1486. return pressed;
  1487. }
  1488. // Label button control
  1489. bool GuiLabelButton(Rectangle bounds, const char *text)
  1490. {
  1491. GuiState state = guiState;
  1492. bool pressed = false;
  1493. // NOTE: We force bounds.width to be all text
  1494. float textWidth = MeasureTextEx(guiFont, text, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), (float)GuiGetStyle(DEFAULT, TEXT_SPACING)).x;
  1495. if (bounds.width < textWidth) bounds.width = textWidth;
  1496. // Update control
  1497. //--------------------------------------------------------------------
  1498. if ((state != STATE_DISABLED) && !guiLocked)
  1499. {
  1500. Vector2 mousePoint = GetMousePosition();
  1501. // Check checkbox state
  1502. if (CheckCollisionPointRec(mousePoint, bounds))
  1503. {
  1504. if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED;
  1505. else state = STATE_FOCUSED;
  1506. if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) pressed = true;
  1507. }
  1508. }
  1509. //--------------------------------------------------------------------
  1510. // Draw control
  1511. //--------------------------------------------------------------------
  1512. GuiDrawText(text, GetTextBounds(LABEL, bounds), GuiGetStyle(LABEL, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(LABEL, TEXT + (state*3))), guiAlpha));
  1513. //--------------------------------------------------------------------
  1514. return pressed;
  1515. }
  1516. // Toggle Button control, returns true when active
  1517. bool GuiToggle(Rectangle bounds, const char *text, bool active)
  1518. {
  1519. GuiState state = guiState;
  1520. // Update control
  1521. //--------------------------------------------------------------------
  1522. if ((state != STATE_DISABLED) && !guiLocked)
  1523. {
  1524. Vector2 mousePoint = GetMousePosition();
  1525. // Check toggle button state
  1526. if (CheckCollisionPointRec(mousePoint, bounds))
  1527. {
  1528. if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED;
  1529. else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON))
  1530. {
  1531. state = STATE_NORMAL;
  1532. active = !active;
  1533. }
  1534. else state = STATE_FOCUSED;
  1535. }
  1536. }
  1537. //--------------------------------------------------------------------
  1538. // Draw control
  1539. //--------------------------------------------------------------------
  1540. if (state == STATE_NORMAL)
  1541. {
  1542. GuiDrawRectangle(bounds, GuiGetStyle(TOGGLE, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(TOGGLE, (active? BORDER_COLOR_PRESSED : (BORDER + state*3)))), guiAlpha), Fade(GetColor(GuiGetStyle(TOGGLE, (active? BASE_COLOR_PRESSED : (BASE + state*3)))), guiAlpha));
  1543. GuiDrawText(text, GetTextBounds(TOGGLE, bounds), GuiGetStyle(TOGGLE, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(TOGGLE, (active? TEXT_COLOR_PRESSED : (TEXT + state*3)))), guiAlpha));
  1544. }
  1545. else
  1546. {
  1547. GuiDrawRectangle(bounds, GuiGetStyle(TOGGLE, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(TOGGLE, BORDER + state*3)), guiAlpha), Fade(GetColor(GuiGetStyle(TOGGLE, BASE + state*3)), guiAlpha));
  1548. GuiDrawText(text, GetTextBounds(TOGGLE, bounds), GuiGetStyle(TOGGLE, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(TOGGLE, TEXT + state*3)), guiAlpha));
  1549. }
  1550. //--------------------------------------------------------------------
  1551. return active;
  1552. }
  1553. // Toggle Group control, returns toggled button index
  1554. int GuiToggleGroup(Rectangle bounds, const char *text, int active)
  1555. {
  1556. #if !defined(RAYGUI_TOGGLEGROUP_MAX_ITEMS)
  1557. #define RAYGUI_TOGGLEGROUP_MAX_ITEMS 32
  1558. #endif
  1559. float initBoundsX = bounds.x;
  1560. // Get substrings items from text (items pointers)
  1561. int rows[RAYGUI_TOGGLEGROUP_MAX_ITEMS] = { 0 };
  1562. int itemCount = 0;
  1563. const char **items = GuiTextSplit(text, &itemCount, rows);
  1564. int prevRow = rows[0];
  1565. for (int i = 0; i < itemCount; i++)
  1566. {
  1567. if (prevRow != rows[i])
  1568. {
  1569. bounds.x = initBoundsX;
  1570. bounds.y += (bounds.height + GuiGetStyle(TOGGLE, GROUP_PADDING));
  1571. prevRow = rows[i];
  1572. }
  1573. if (i == active) GuiToggle(bounds, items[i], true);
  1574. else if (GuiToggle(bounds, items[i], false) == true) active = i;
  1575. bounds.x += (bounds.width + GuiGetStyle(TOGGLE, GROUP_PADDING));
  1576. }
  1577. return active;
  1578. }
  1579. // Check Box control, returns true when active
  1580. bool GuiCheckBox(Rectangle bounds, const char *text, bool checked)
  1581. {
  1582. GuiState state = guiState;
  1583. Rectangle textBounds = { 0 };
  1584. if (text != NULL)
  1585. {
  1586. textBounds.width = (float)GetTextWidth(text);
  1587. textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
  1588. textBounds.x = bounds.x + bounds.width + GuiGetStyle(CHECKBOX, TEXT_PADDING);
  1589. textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
  1590. if (GuiGetStyle(CHECKBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_LEFT) textBounds.x = bounds.x - textBounds.width - GuiGetStyle(CHECKBOX, TEXT_PADDING);
  1591. }
  1592. // Update control
  1593. //--------------------------------------------------------------------
  1594. if ((state != STATE_DISABLED) && !guiLocked)
  1595. {
  1596. Vector2 mousePoint = GetMousePosition();
  1597. Rectangle totalBounds = {
  1598. (GuiGetStyle(CHECKBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_LEFT)? textBounds.x : bounds.x,
  1599. bounds.y,
  1600. bounds.width + textBounds.width + GuiGetStyle(CHECKBOX, TEXT_PADDING),
  1601. bounds.height,
  1602. };
  1603. // Check checkbox state
  1604. if (CheckCollisionPointRec(mousePoint, totalBounds))
  1605. {
  1606. if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED;
  1607. else state = STATE_FOCUSED;
  1608. if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) checked = !checked;
  1609. }
  1610. }
  1611. //--------------------------------------------------------------------
  1612. // Draw control
  1613. //--------------------------------------------------------------------
  1614. GuiDrawRectangle(bounds, GuiGetStyle(CHECKBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(CHECKBOX, BORDER + (state*3))), guiAlpha), BLANK);
  1615. if (checked)
  1616. {
  1617. Rectangle check = { bounds.x + GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, CHECK_PADDING),
  1618. bounds.y + GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, CHECK_PADDING),
  1619. bounds.width - 2*(GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, CHECK_PADDING)),
  1620. bounds.height - 2*(GuiGetStyle(CHECKBOX, BORDER_WIDTH) + GuiGetStyle(CHECKBOX, CHECK_PADDING)) };
  1621. GuiDrawRectangle(check, 0, BLANK, Fade(GetColor(GuiGetStyle(CHECKBOX, TEXT + state*3)), guiAlpha));
  1622. }
  1623. GuiDrawText(text, textBounds, (GuiGetStyle(CHECKBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_RIGHT)? TEXT_ALIGN_LEFT : TEXT_ALIGN_RIGHT, Fade(GetColor(GuiGetStyle(LABEL, TEXT + (state*3))), guiAlpha));
  1624. //--------------------------------------------------------------------
  1625. return checked;
  1626. }
  1627. // Combo Box control, returns selected item index
  1628. int GuiComboBox(Rectangle bounds, const char *text, int active)
  1629. {
  1630. GuiState state = guiState;
  1631. bounds.width -= (GuiGetStyle(COMBOBOX, COMBO_BUTTON_WIDTH) + GuiGetStyle(COMBOBOX, COMBO_BUTTON_SPACING));
  1632. Rectangle selector = { (float)bounds.x + bounds.width + GuiGetStyle(COMBOBOX, COMBO_BUTTON_SPACING),
  1633. (float)bounds.y, (float)GuiGetStyle(COMBOBOX, COMBO_BUTTON_WIDTH), (float)bounds.height };
  1634. // Get substrings items from text (items pointers, lengths and count)
  1635. int itemCount = 0;
  1636. const char **items = GuiTextSplit(text, &itemCount, NULL);
  1637. if (active < 0) active = 0;
  1638. else if (active > itemCount - 1) active = itemCount - 1;
  1639. // Update control
  1640. //--------------------------------------------------------------------
  1641. if ((state != STATE_DISABLED) && !guiLocked && (itemCount > 1))
  1642. {
  1643. Vector2 mousePoint = GetMousePosition();
  1644. if (CheckCollisionPointRec(mousePoint, bounds) ||
  1645. CheckCollisionPointRec(mousePoint, selector))
  1646. {
  1647. if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
  1648. {
  1649. active += 1;
  1650. if (active >= itemCount) active = 0;
  1651. }
  1652. if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED;
  1653. else state = STATE_FOCUSED;
  1654. }
  1655. }
  1656. //--------------------------------------------------------------------
  1657. // Draw control
  1658. //--------------------------------------------------------------------
  1659. // Draw combo box main
  1660. GuiDrawRectangle(bounds, GuiGetStyle(COMBOBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COMBOBOX, BORDER + (state*3))), guiAlpha), Fade(GetColor(GuiGetStyle(COMBOBOX, BASE + (state*3))), guiAlpha));
  1661. GuiDrawText(items[active], GetTextBounds(COMBOBOX, bounds), GuiGetStyle(COMBOBOX, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(COMBOBOX, TEXT + (state*3))), guiAlpha));
  1662. // Draw selector using a custom button
  1663. // NOTE: BORDER_WIDTH and TEXT_ALIGNMENT forced values
  1664. int tempBorderWidth = GuiGetStyle(BUTTON, BORDER_WIDTH);
  1665. int tempTextAlign = GuiGetStyle(BUTTON, TEXT_ALIGNMENT);
  1666. GuiSetStyle(BUTTON, BORDER_WIDTH, 1);
  1667. GuiSetStyle(BUTTON, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER);
  1668. GuiButton(selector, TextFormat("%i/%i", active + 1, itemCount));
  1669. GuiSetStyle(BUTTON, TEXT_ALIGNMENT, tempTextAlign);
  1670. GuiSetStyle(BUTTON, BORDER_WIDTH, tempBorderWidth);
  1671. //--------------------------------------------------------------------
  1672. return active;
  1673. }
  1674. // Dropdown Box control
  1675. // NOTE: Returns mouse click
  1676. bool GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMode)
  1677. {
  1678. GuiState state = guiState;
  1679. int itemSelected = *active;
  1680. int itemFocused = -1;
  1681. // Get substrings items from text (items pointers, lengths and count)
  1682. int itemCount = 0;
  1683. const char **items = GuiTextSplit(text, &itemCount, NULL);
  1684. Rectangle boundsOpen = bounds;
  1685. boundsOpen.height = (itemCount + 1)*(bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING));
  1686. Rectangle itemBounds = bounds;
  1687. bool pressed = false; // Check mouse button pressed
  1688. // Update control
  1689. //--------------------------------------------------------------------
  1690. if ((state != STATE_DISABLED) && (editMode || !guiLocked) && (itemCount > 1))
  1691. {
  1692. Vector2 mousePoint = GetMousePosition();
  1693. if (editMode)
  1694. {
  1695. state = STATE_PRESSED;
  1696. // Check if mouse has been pressed or released outside limits
  1697. if (!CheckCollisionPointRec(mousePoint, boundsOpen))
  1698. {
  1699. if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON) || IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) pressed = true;
  1700. }
  1701. // Check if already selected item has been pressed again
  1702. if (CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) pressed = true;
  1703. // Check focused and selected item
  1704. for (int i = 0; i < itemCount; i++)
  1705. {
  1706. // Update item rectangle y position for next item
  1707. itemBounds.y += (bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING));
  1708. if (CheckCollisionPointRec(mousePoint, itemBounds))
  1709. {
  1710. itemFocused = i;
  1711. if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON))
  1712. {
  1713. itemSelected = i;
  1714. pressed = true; // Item selected, change to editMode = false
  1715. }
  1716. break;
  1717. }
  1718. }
  1719. itemBounds = bounds;
  1720. }
  1721. else
  1722. {
  1723. if (CheckCollisionPointRec(mousePoint, bounds))
  1724. {
  1725. if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
  1726. {
  1727. pressed = true;
  1728. state = STATE_PRESSED;
  1729. }
  1730. else state = STATE_FOCUSED;
  1731. }
  1732. }
  1733. }
  1734. //--------------------------------------------------------------------
  1735. // Draw control
  1736. //--------------------------------------------------------------------
  1737. if (editMode) GuiPanel(boundsOpen, NULL);
  1738. GuiDrawRectangle(bounds, GuiGetStyle(DROPDOWNBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(DROPDOWNBOX, BORDER + state*3)), guiAlpha), Fade(GetColor(GuiGetStyle(DROPDOWNBOX, BASE + state*3)), guiAlpha));
  1739. GuiDrawText(items[itemSelected], GetTextBounds(DEFAULT, bounds), GuiGetStyle(DROPDOWNBOX, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + state*3)), guiAlpha));
  1740. if (editMode)
  1741. {
  1742. // Draw visible items
  1743. for (int i = 0; i < itemCount; i++)
  1744. {
  1745. // Update item rectangle y position for next item
  1746. itemBounds.y += (bounds.height + GuiGetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING));
  1747. if (i == itemSelected)
  1748. {
  1749. GuiDrawRectangle(itemBounds, GuiGetStyle(DROPDOWNBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(DROPDOWNBOX, BORDER_COLOR_PRESSED)), guiAlpha), Fade(GetColor(GuiGetStyle(DROPDOWNBOX, BASE_COLOR_PRESSED)), guiAlpha));
  1750. GuiDrawText(items[i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(DROPDOWNBOX, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(DROPDOWNBOX, TEXT_COLOR_PRESSED)), guiAlpha));
  1751. }
  1752. else if (i == itemFocused)
  1753. {
  1754. GuiDrawRectangle(itemBounds, GuiGetStyle(DROPDOWNBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(DROPDOWNBOX, BORDER_COLOR_FOCUSED)), guiAlpha), Fade(GetColor(GuiGetStyle(DROPDOWNBOX, BASE_COLOR_FOCUSED)), guiAlpha));
  1755. GuiDrawText(items[i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(DROPDOWNBOX, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(DROPDOWNBOX, TEXT_COLOR_FOCUSED)), guiAlpha));
  1756. }
  1757. else GuiDrawText(items[i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(DROPDOWNBOX, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(DROPDOWNBOX, TEXT_COLOR_NORMAL)), guiAlpha));
  1758. }
  1759. }
  1760. // Draw arrows (using icon if available)
  1761. #if defined(RAYGUI_NO_ICONS)
  1762. GuiDrawText("v", RAYGUI_CLITERAL(Rectangle){ bounds.x + bounds.width - GuiGetStyle(DROPDOWNBOX, ARROW_PADDING), bounds.y + bounds.height/2 - 2, 10, 10 },
  1763. TEXT_ALIGN_CENTER, Fade(GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + (state*3))), guiAlpha));
  1764. #else
  1765. GuiDrawText("#120#", RAYGUI_CLITERAL(Rectangle){ bounds.x + bounds.width - GuiGetStyle(DROPDOWNBOX, ARROW_PADDING), bounds.y + bounds.height/2 - 6, 10, 10 },
  1766. TEXT_ALIGN_CENTER, Fade(GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + (state*3))), guiAlpha)); // ICON_ARROW_DOWN_FILL
  1767. #endif
  1768. //--------------------------------------------------------------------
  1769. *active = itemSelected;
  1770. return pressed;
  1771. }
  1772. // Text Box control, updates input text
  1773. // NOTE 2: Returns if KEY_ENTER pressed (useful for data validation)
  1774. bool GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode)
  1775. {
  1776. GuiState state = guiState;
  1777. bool pressed = false;
  1778. Rectangle cursor = {
  1779. bounds.x + GuiGetStyle(TEXTBOX, TEXT_PADDING) + GetTextWidth(text) + 2,
  1780. bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE),
  1781. 4,
  1782. (float)GuiGetStyle(DEFAULT, TEXT_SIZE)*2
  1783. };
  1784. if (cursor.height >= bounds.height) cursor.height = bounds.height - GuiGetStyle(TEXTBOX, BORDER_WIDTH)*2;
  1785. if (cursor.y < (bounds.y + GuiGetStyle(TEXTBOX, BORDER_WIDTH))) cursor.y = bounds.y + GuiGetStyle(TEXTBOX, BORDER_WIDTH);
  1786. // Update control
  1787. //--------------------------------------------------------------------
  1788. if ((state != STATE_DISABLED) && !guiLocked)
  1789. {
  1790. Vector2 mousePoint = GetMousePosition();
  1791. if (editMode)
  1792. {
  1793. state = STATE_PRESSED;
  1794. int key = GetCharPressed(); // Returns codepoint as Unicode
  1795. int keyCount = (int)strlen(text);
  1796. int byteSize = 0;
  1797. const char *textUTF8 = CodepointToUTF8(key, &byteSize);
  1798. // Only allow keys in range [32..125]
  1799. if ((keyCount + byteSize) < textSize)
  1800. {
  1801. float maxWidth = (bounds.width - (GuiGetStyle(TEXTBOX, TEXT_INNER_PADDING)*2));
  1802. if ((GetTextWidth(text) < (maxWidth - GuiGetStyle(DEFAULT, TEXT_SIZE))) && (key >= 32))
  1803. {
  1804. for (int i = 0; i < byteSize; i++)
  1805. {
  1806. text[keyCount] = textUTF8[i];
  1807. keyCount++;
  1808. }
  1809. text[keyCount] = '\0';
  1810. }
  1811. }
  1812. // Delete text
  1813. if (keyCount > 0)
  1814. {
  1815. if (IsKeyPressed(KEY_BACKSPACE))
  1816. {
  1817. while ((keyCount > 0) && ((text[--keyCount] & 0xc0) == 0x80));
  1818. text[keyCount] = '\0';
  1819. }
  1820. }
  1821. if (IsKeyPressed(KEY_ENTER) || (!CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) pressed = true;
  1822. // Check text alignment to position cursor properly
  1823. int textAlignment = GuiGetStyle(TEXTBOX, TEXT_ALIGNMENT);
  1824. if (textAlignment == TEXT_ALIGN_CENTER) cursor.x = bounds.x + GetTextWidth(text)/2 + bounds.width/2 + 1;
  1825. else if (textAlignment == TEXT_ALIGN_RIGHT) cursor.x = bounds.x + bounds.width - GuiGetStyle(TEXTBOX, TEXT_INNER_PADDING);
  1826. }
  1827. else
  1828. {
  1829. if (CheckCollisionPointRec(mousePoint, bounds))
  1830. {
  1831. state = STATE_FOCUSED;
  1832. if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) pressed = true;
  1833. }
  1834. }
  1835. }
  1836. //--------------------------------------------------------------------
  1837. // Draw control
  1838. //--------------------------------------------------------------------
  1839. if (state == STATE_PRESSED)
  1840. {
  1841. GuiDrawRectangle(bounds, GuiGetStyle(TEXTBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(TEXTBOX, BORDER + (state*3))), guiAlpha), Fade(GetColor(GuiGetStyle(TEXTBOX, BASE_COLOR_PRESSED)), guiAlpha));
  1842. }
  1843. else if (state == STATE_DISABLED)
  1844. {
  1845. GuiDrawRectangle(bounds, GuiGetStyle(TEXTBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(TEXTBOX, BORDER + (state*3))), guiAlpha), Fade(GetColor(GuiGetStyle(TEXTBOX, BASE_COLOR_DISABLED)), guiAlpha));
  1846. }
  1847. else GuiDrawRectangle(bounds, 1, Fade(GetColor(GuiGetStyle(TEXTBOX, BORDER + (state*3))), guiAlpha), BLANK);
  1848. GuiDrawText(text, GetTextBounds(TEXTBOX, bounds), GuiGetStyle(TEXTBOX, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(TEXTBOX, TEXT + (state*3))), guiAlpha));
  1849. // Draw cursor
  1850. if (editMode) GuiDrawRectangle(cursor, 0, BLANK, Fade(GetColor(GuiGetStyle(TEXTBOX, BORDER_COLOR_PRESSED)), guiAlpha));
  1851. //--------------------------------------------------------------------
  1852. return pressed;
  1853. }
  1854. // Spinner control, returns selected value
  1855. bool GuiSpinner(Rectangle bounds, const char *text, int *value, int minValue, int maxValue, bool editMode)
  1856. {
  1857. GuiState state = guiState;
  1858. bool pressed = false;
  1859. int tempValue = *value;
  1860. Rectangle spinner = { bounds.x + GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH) + GuiGetStyle(SPINNER, SPIN_BUTTON_SPACING), bounds.y,
  1861. bounds.width - 2*(GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH) + GuiGetStyle(SPINNER, SPIN_BUTTON_SPACING)), bounds.height };
  1862. Rectangle leftButtonBound = { (float)bounds.x, (float)bounds.y, (float)GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH), (float)bounds.height };
  1863. Rectangle rightButtonBound = { (float)bounds.x + bounds.width - GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH), (float)bounds.y, (float)GuiGetStyle(SPINNER, SPIN_BUTTON_WIDTH), (float)bounds.height };
  1864. Rectangle textBounds = { 0 };
  1865. if (text != NULL)
  1866. {
  1867. textBounds.width = (float)GetTextWidth(text);
  1868. textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
  1869. textBounds.x = bounds.x + bounds.width + GuiGetStyle(SPINNER, TEXT_PADDING);
  1870. textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
  1871. if (GuiGetStyle(SPINNER, TEXT_ALIGNMENT) == TEXT_ALIGN_LEFT) textBounds.x = bounds.x - textBounds.width - GuiGetStyle(SPINNER, TEXT_PADDING);
  1872. }
  1873. // Update control
  1874. //--------------------------------------------------------------------
  1875. if ((state != STATE_DISABLED) && !guiLocked)
  1876. {
  1877. Vector2 mousePoint = GetMousePosition();
  1878. // Check spinner state
  1879. if (CheckCollisionPointRec(mousePoint, bounds))
  1880. {
  1881. if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED;
  1882. else state = STATE_FOCUSED;
  1883. }
  1884. }
  1885. #if defined(RAYGUI_NO_ICONS)
  1886. if (GuiButton(leftButtonBound, "<")) tempValue--;
  1887. if (GuiButton(rightButtonBound, ">")) tempValue++;
  1888. #else
  1889. if (GuiButton(leftButtonBound, GuiIconText(ICON_ARROW_LEFT_FILL, NULL))) tempValue--;
  1890. if (GuiButton(rightButtonBound, GuiIconText(ICON_ARROW_RIGHT_FILL, NULL))) tempValue++;
  1891. #endif
  1892. if (!editMode)
  1893. {
  1894. if (tempValue < minValue) tempValue = minValue;
  1895. if (tempValue > maxValue) tempValue = maxValue;
  1896. }
  1897. //--------------------------------------------------------------------
  1898. // Draw control
  1899. //--------------------------------------------------------------------
  1900. // TODO: Set Spinner properties for ValueBox
  1901. pressed = GuiValueBox(spinner, NULL, &tempValue, minValue, maxValue, editMode);
  1902. // Draw value selector custom buttons
  1903. // NOTE: BORDER_WIDTH and TEXT_ALIGNMENT forced values
  1904. int tempBorderWidth = GuiGetStyle(BUTTON, BORDER_WIDTH);
  1905. int tempTextAlign = GuiGetStyle(BUTTON, TEXT_ALIGNMENT);
  1906. GuiSetStyle(BUTTON, BORDER_WIDTH, GuiGetStyle(SPINNER, BORDER_WIDTH));
  1907. GuiSetStyle(BUTTON, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER);
  1908. GuiSetStyle(BUTTON, TEXT_ALIGNMENT, tempTextAlign);
  1909. GuiSetStyle(BUTTON, BORDER_WIDTH, tempBorderWidth);
  1910. // Draw text label if provided
  1911. GuiDrawText(text, textBounds, (GuiGetStyle(SPINNER, TEXT_ALIGNMENT) == TEXT_ALIGN_RIGHT)? TEXT_ALIGN_LEFT : TEXT_ALIGN_RIGHT, Fade(GetColor(GuiGetStyle(LABEL, TEXT + (state*3))), guiAlpha));
  1912. //--------------------------------------------------------------------
  1913. *value = tempValue;
  1914. return pressed;
  1915. }
  1916. // Value Box control, updates input text with numbers
  1917. // NOTE: Requires static variables: frameCounter
  1918. bool GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, int maxValue, bool editMode)
  1919. {
  1920. #if !defined(RAYGUI_VALUEBOX_MAX_CHARS)
  1921. #define RAYGUI_VALUEBOX_MAX_CHARS 32
  1922. #endif
  1923. GuiState state = guiState;
  1924. bool pressed = false;
  1925. char textValue[RAYGUI_VALUEBOX_MAX_CHARS + 1] = "\0";
  1926. sprintf(textValue, "%i", *value);
  1927. Rectangle textBounds = { 0 };
  1928. if (text != NULL)
  1929. {
  1930. textBounds.width = (float)GetTextWidth(text);
  1931. textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
  1932. textBounds.x = bounds.x + bounds.width + GuiGetStyle(VALUEBOX, TEXT_PADDING);
  1933. textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
  1934. if (GuiGetStyle(VALUEBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_LEFT) textBounds.x = bounds.x - textBounds.width - GuiGetStyle(VALUEBOX, TEXT_PADDING);
  1935. }
  1936. // Update control
  1937. //--------------------------------------------------------------------
  1938. if ((state != STATE_DISABLED) && !guiLocked)
  1939. {
  1940. Vector2 mousePoint = GetMousePosition();
  1941. bool valueHasChanged = false;
  1942. if (editMode)
  1943. {
  1944. state = STATE_PRESSED;
  1945. int keyCount = (int)strlen(textValue);
  1946. // Only allow keys in range [48..57]
  1947. if (keyCount < RAYGUI_VALUEBOX_MAX_CHARS)
  1948. {
  1949. if (GetTextWidth(textValue) < bounds.width)
  1950. {
  1951. int key = GetCharPressed();
  1952. if ((key >= 48) && (key <= 57))
  1953. {
  1954. textValue[keyCount] = (char)key;
  1955. keyCount++;
  1956. valueHasChanged = true;
  1957. }
  1958. }
  1959. }
  1960. // Delete text
  1961. if (keyCount > 0)
  1962. {
  1963. if (IsKeyPressed(KEY_BACKSPACE))
  1964. {
  1965. keyCount--;
  1966. textValue[keyCount] = '\0';
  1967. valueHasChanged = true;
  1968. }
  1969. }
  1970. if (valueHasChanged) *value = TextToInteger(textValue);
  1971. // NOTE: We are not clamp values until user input finishes
  1972. //if (*value > maxValue) *value = maxValue;
  1973. //else if (*value < minValue) *value = minValue;
  1974. if (IsKeyPressed(KEY_ENTER) || (!CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) pressed = true;
  1975. }
  1976. else
  1977. {
  1978. if (*value > maxValue) *value = maxValue;
  1979. else if (*value < minValue) *value = minValue;
  1980. if (CheckCollisionPointRec(mousePoint, bounds))
  1981. {
  1982. state = STATE_FOCUSED;
  1983. if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) pressed = true;
  1984. }
  1985. }
  1986. }
  1987. //--------------------------------------------------------------------
  1988. // Draw control
  1989. //--------------------------------------------------------------------
  1990. Color baseColor = BLANK;
  1991. if (state == STATE_PRESSED) baseColor = GetColor(GuiGetStyle(VALUEBOX, BASE_COLOR_PRESSED));
  1992. else if (state == STATE_DISABLED) baseColor = GetColor(GuiGetStyle(VALUEBOX, BASE_COLOR_DISABLED));
  1993. // WARNING: BLANK color does not work properly with Fade()
  1994. GuiDrawRectangle(bounds, GuiGetStyle(VALUEBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(VALUEBOX, BORDER + (state*3))), guiAlpha), baseColor);
  1995. GuiDrawText(textValue, GetTextBounds(VALUEBOX, bounds), TEXT_ALIGN_CENTER, Fade(GetColor(GuiGetStyle(VALUEBOX, TEXT + (state*3))), guiAlpha));
  1996. // Draw cursor
  1997. if (editMode)
  1998. {
  1999. // NOTE: ValueBox internal text is always centered
  2000. Rectangle cursor = { bounds.x + GetTextWidth(textValue)/2 + bounds.width/2 + 2, bounds.y + 2*GuiGetStyle(VALUEBOX, BORDER_WIDTH), 4, bounds.height - 4*GuiGetStyle(VALUEBOX, BORDER_WIDTH) };
  2001. GuiDrawRectangle(cursor, 0, BLANK, Fade(GetColor(GuiGetStyle(VALUEBOX, BORDER_COLOR_PRESSED)), guiAlpha));
  2002. }
  2003. // Draw text label if provided
  2004. GuiDrawText(text, textBounds, (GuiGetStyle(VALUEBOX, TEXT_ALIGNMENT) == TEXT_ALIGN_RIGHT)? TEXT_ALIGN_LEFT : TEXT_ALIGN_RIGHT, Fade(GetColor(GuiGetStyle(LABEL, TEXT + (state*3))), guiAlpha));
  2005. //--------------------------------------------------------------------
  2006. return pressed;
  2007. }
  2008. // Text Box control with multiple lines
  2009. bool GuiTextBoxMulti(Rectangle bounds, char *text, int textSize, bool editMode)
  2010. {
  2011. GuiState state = guiState;
  2012. bool pressed = false;
  2013. Rectangle textAreaBounds = {
  2014. bounds.x + GuiGetStyle(TEXTBOX, BORDER_WIDTH) + GuiGetStyle(TEXTBOX, TEXT_INNER_PADDING),
  2015. bounds.y + GuiGetStyle(TEXTBOX, BORDER_WIDTH) + GuiGetStyle(TEXTBOX, TEXT_INNER_PADDING),
  2016. bounds.width - 2*(GuiGetStyle(TEXTBOX, BORDER_WIDTH) + GuiGetStyle(TEXTBOX, TEXT_INNER_PADDING)),
  2017. bounds.height - 2*(GuiGetStyle(TEXTBOX, BORDER_WIDTH) + GuiGetStyle(TEXTBOX, TEXT_INNER_PADDING))
  2018. };
  2019. // Cursor position, [x, y] values should be updated
  2020. Rectangle cursor = { 0, -1, 4, (float)GuiGetStyle(DEFAULT, TEXT_SIZE) + 2 };
  2021. float scaleFactor = (float)GuiGetStyle(DEFAULT, TEXT_SIZE)/(float)guiFont.baseSize; // Character rectangle scaling factor
  2022. // Update control
  2023. //--------------------------------------------------------------------
  2024. if ((state != STATE_DISABLED) && !guiLocked)
  2025. {
  2026. Vector2 mousePoint = GetMousePosition();
  2027. if (editMode)
  2028. {
  2029. state = STATE_PRESSED;
  2030. // We get an Unicode codepoint
  2031. int codepoint = GetCharPressed();
  2032. int textLength = (int)strlen(text); // Length in bytes (UTF-8 string)
  2033. // Introduce characters
  2034. if (textLength < (textSize - 1))
  2035. {
  2036. if (IsKeyPressed(KEY_ENTER))
  2037. {
  2038. text[textLength] = '\n';
  2039. textLength++;
  2040. }
  2041. else if (codepoint >= 32)
  2042. {
  2043. // Supports Unicode inputs -> Encoded to UTF-8
  2044. int charUTF8Length = 0;
  2045. const char *charEncoded = CodepointToUTF8(codepoint, &charUTF8Length);
  2046. memcpy(text + textLength, charEncoded, charUTF8Length);
  2047. textLength += charUTF8Length;
  2048. }
  2049. }
  2050. // Delete characters
  2051. if (textLength > 0)
  2052. {
  2053. if (IsKeyPressed(KEY_BACKSPACE))
  2054. {
  2055. if ((unsigned char)text[textLength - 1] < 127)
  2056. {
  2057. // Remove ASCII equivalent character (1 byte)
  2058. textLength--;
  2059. text[textLength] = '\0';
  2060. }
  2061. else
  2062. {
  2063. // Remove latest UTF-8 unicode character introduced (n bytes)
  2064. int charUTF8Length = 0;
  2065. while (((unsigned char)text[textLength - 1 - charUTF8Length] & 0b01000000) == 0) charUTF8Length++;
  2066. textLength -= (charUTF8Length + 1);
  2067. text[textLength] = '\0';
  2068. }
  2069. }
  2070. }
  2071. // Exit edit mode
  2072. if (!CheckCollisionPointRec(mousePoint, bounds) && IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) pressed = true;
  2073. }
  2074. else
  2075. {
  2076. if (CheckCollisionPointRec(mousePoint, bounds))
  2077. {
  2078. state = STATE_FOCUSED;
  2079. if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) pressed = true;
  2080. }
  2081. }
  2082. }
  2083. //--------------------------------------------------------------------
  2084. // Draw control
  2085. //--------------------------------------------------------------------
  2086. if (state == STATE_PRESSED)
  2087. {
  2088. GuiDrawRectangle(bounds, GuiGetStyle(TEXTBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(TEXTBOX, BORDER + (state*3))), guiAlpha), Fade(GetColor(GuiGetStyle(TEXTBOX, BASE_COLOR_PRESSED)), guiAlpha));
  2089. }
  2090. else if (state == STATE_DISABLED)
  2091. {
  2092. GuiDrawRectangle(bounds, GuiGetStyle(TEXTBOX, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(TEXTBOX, BORDER + (state*3))), guiAlpha), Fade(GetColor(GuiGetStyle(TEXTBOX, BASE_COLOR_DISABLED)), guiAlpha));
  2093. }
  2094. else GuiDrawRectangle(bounds, 1, Fade(GetColor(GuiGetStyle(TEXTBOX, BORDER + (state*3))), guiAlpha), BLANK);
  2095. int wrapMode = 1; // 0-No wrap, 1-Char wrap, 2-Word wrap
  2096. Vector2 cursorPos = { textAreaBounds.x, textAreaBounds.y };
  2097. //int lastSpacePos = 0;
  2098. //int lastSpaceWidth = 0;
  2099. //int lastSpaceCursorPos = 0;
  2100. for (int i = 0, codepointLength = 0; text[i] != '\0'; i += codepointLength)
  2101. {
  2102. int codepoint = GetCodepoint(text + i, &codepointLength);
  2103. int index = GetGlyphIndex(guiFont, codepoint); // If requested codepoint is not found, we get '?' (0x3f)
  2104. Rectangle atlasRec = guiFont.recs[index];
  2105. GlyphInfo glyphInfo = guiFont.glyphs[index]; // Glyph measures
  2106. if ((codepointLength == 1) && (codepoint == '\n'))
  2107. {
  2108. cursorPos.y += (guiFont.baseSize*scaleFactor + GuiGetStyle(TEXTBOX, TEXT_LINES_SPACING)); // Line feed
  2109. cursorPos.x = textAreaBounds.x; // Carriage return
  2110. }
  2111. else
  2112. {
  2113. if (wrapMode == 1)
  2114. {
  2115. int glyphWidth = 0;
  2116. if (glyphInfo.advanceX != 0) glyphWidth += glyphInfo.advanceX;
  2117. else glyphWidth += (int)(atlasRec.width + glyphInfo.offsetX);
  2118. // Jump line if the end of the text box area has been reached
  2119. if ((cursorPos.x + (glyphWidth*scaleFactor)) > (textAreaBounds.x + textAreaBounds.width))
  2120. {
  2121. cursorPos.y += (guiFont.baseSize*scaleFactor + GuiGetStyle(TEXTBOX, TEXT_LINES_SPACING)); // Line feed
  2122. cursorPos.x = textAreaBounds.x; // Carriage return
  2123. }
  2124. }
  2125. else if (wrapMode == 2)
  2126. {
  2127. /*
  2128. if ((codepointLength == 1) && (codepoint == ' '))
  2129. {
  2130. lastSpacePos = i;
  2131. lastSpaceWidth = 0;
  2132. lastSpaceCursorPos = cursorPos.x;
  2133. }
  2134. // Jump line if last word reaches end of text box area
  2135. if ((lastSpaceCursorPos + lastSpaceWidth) > (textAreaBounds.x + textAreaBounds.width))
  2136. {
  2137. cursorPos.y += 12; // Line feed
  2138. cursorPos.x = textAreaBounds.x; // Carriage return
  2139. }
  2140. */
  2141. }
  2142. // Draw current character glyph
  2143. DrawTextCodepoint(guiFont, codepoint, cursorPos, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), Fade(GetColor(GuiGetStyle(TEXTBOX, TEXT + (state*3))), guiAlpha));
  2144. int glyphWidth = 0;
  2145. if (glyphInfo.advanceX != 0) glyphWidth += glyphInfo.advanceX;
  2146. else glyphWidth += (int)(atlasRec.width + glyphInfo.offsetX);
  2147. cursorPos.x += (glyphWidth*scaleFactor + (float)GuiGetStyle(DEFAULT, TEXT_SPACING));
  2148. //if (i > lastSpacePos) lastSpaceWidth += (atlasRec.width + (float)GuiGetStyle(DEFAULT, TEXT_SPACING));
  2149. }
  2150. }
  2151. cursor.x = cursorPos.x;
  2152. cursor.y = cursorPos.y;
  2153. // Draw cursor position considering text glyphs
  2154. if (editMode) GuiDrawRectangle(cursor, 0, BLANK, Fade(GetColor(GuiGetStyle(TEXTBOX, BORDER_COLOR_PRESSED)), guiAlpha));
  2155. //--------------------------------------------------------------------
  2156. return pressed;
  2157. }
  2158. // Slider control with pro parameters
  2159. // NOTE: Other GuiSlider*() controls use this one
  2160. float GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight, float value, float minValue, float maxValue, int sliderWidth)
  2161. {
  2162. GuiState state = guiState;
  2163. int sliderValue = (int)(((value - minValue)/(maxValue - minValue))*(bounds.width - 2*GuiGetStyle(SLIDER, BORDER_WIDTH)));
  2164. Rectangle slider = { bounds.x, bounds.y + GuiGetStyle(SLIDER, BORDER_WIDTH) + GuiGetStyle(SLIDER, SLIDER_PADDING),
  2165. 0, bounds.height - 2*GuiGetStyle(SLIDER, BORDER_WIDTH) - 2*GuiGetStyle(SLIDER, SLIDER_PADDING) };
  2166. if (sliderWidth > 0) // Slider
  2167. {
  2168. slider.x += (sliderValue - sliderWidth/2);
  2169. slider.width = (float)sliderWidth;
  2170. }
  2171. else if (sliderWidth == 0) // SliderBar
  2172. {
  2173. slider.x += GuiGetStyle(SLIDER, BORDER_WIDTH);
  2174. slider.width = (float)sliderValue;
  2175. }
  2176. // Update control
  2177. //--------------------------------------------------------------------
  2178. if ((state != STATE_DISABLED) && !guiLocked)
  2179. {
  2180. Vector2 mousePoint = GetMousePosition();
  2181. if (CheckCollisionPointRec(mousePoint, bounds))
  2182. {
  2183. if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
  2184. {
  2185. state = STATE_PRESSED;
  2186. // Get equivalent value and slider position from mousePoint.x
  2187. value = ((maxValue - minValue)*(mousePoint.x - (float)(bounds.x + sliderWidth/2)))/(float)(bounds.width - sliderWidth) + minValue;
  2188. if (sliderWidth > 0) slider.x = mousePoint.x - slider.width/2; // Slider
  2189. else if (sliderWidth == 0) slider.width = (float)sliderValue; // SliderBar
  2190. }
  2191. else state = STATE_FOCUSED;
  2192. }
  2193. if (value > maxValue) value = maxValue;
  2194. else if (value < minValue) value = minValue;
  2195. }
  2196. // Bar limits check
  2197. if (sliderWidth > 0) // Slider
  2198. {
  2199. if (slider.x <= (bounds.x + GuiGetStyle(SLIDER, BORDER_WIDTH))) slider.x = bounds.x + GuiGetStyle(SLIDER, BORDER_WIDTH);
  2200. else if ((slider.x + slider.width) >= (bounds.x + bounds.width)) slider.x = bounds.x + bounds.width - slider.width - GuiGetStyle(SLIDER, BORDER_WIDTH);
  2201. }
  2202. else if (sliderWidth == 0) // SliderBar
  2203. {
  2204. if (slider.width > bounds.width) slider.width = bounds.width - 2*GuiGetStyle(SLIDER, BORDER_WIDTH);
  2205. }
  2206. //--------------------------------------------------------------------
  2207. // Draw control
  2208. //--------------------------------------------------------------------
  2209. GuiDrawRectangle(bounds, GuiGetStyle(SLIDER, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(SLIDER, BORDER + (state*3))), guiAlpha), Fade(GetColor(GuiGetStyle(SLIDER, (state != STATE_DISABLED)? BASE_COLOR_NORMAL : BASE_COLOR_DISABLED)), guiAlpha));
  2210. // Draw slider internal bar (depends on state)
  2211. if ((state == STATE_NORMAL) || (state == STATE_PRESSED)) GuiDrawRectangle(slider, 0, BLANK, Fade(GetColor(GuiGetStyle(SLIDER, BASE_COLOR_PRESSED)), guiAlpha));
  2212. else if (state == STATE_FOCUSED) GuiDrawRectangle(slider, 0, BLANK, Fade(GetColor(GuiGetStyle(SLIDER, TEXT_COLOR_FOCUSED)), guiAlpha));
  2213. // Draw left/right text if provided
  2214. if (textLeft != NULL)
  2215. {
  2216. Rectangle textBounds = { 0 };
  2217. textBounds.width = (float)GetTextWidth(textLeft);
  2218. textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
  2219. textBounds.x = bounds.x - textBounds.width - GuiGetStyle(SLIDER, TEXT_PADDING);
  2220. textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
  2221. GuiDrawText(textLeft, textBounds, TEXT_ALIGN_RIGHT, Fade(GetColor(GuiGetStyle(SLIDER, TEXT + (state*3))), guiAlpha));
  2222. }
  2223. if (textRight != NULL)
  2224. {
  2225. Rectangle textBounds = { 0 };
  2226. textBounds.width = (float)GetTextWidth(textRight);
  2227. textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
  2228. textBounds.x = bounds.x + bounds.width + GuiGetStyle(SLIDER, TEXT_PADDING);
  2229. textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
  2230. GuiDrawText(textRight, textBounds, TEXT_ALIGN_LEFT, Fade(GetColor(GuiGetStyle(SLIDER, TEXT + (state*3))), guiAlpha));
  2231. }
  2232. //--------------------------------------------------------------------
  2233. return value;
  2234. }
  2235. // Slider control extended, returns selected value and has text
  2236. float GuiSlider(Rectangle bounds, const char *textLeft, const char *textRight, float value, float minValue, float maxValue)
  2237. {
  2238. return GuiSliderPro(bounds, textLeft, textRight, value, minValue, maxValue, GuiGetStyle(SLIDER, SLIDER_WIDTH));
  2239. }
  2240. // Slider Bar control extended, returns selected value
  2241. float GuiSliderBar(Rectangle bounds, const char *textLeft, const char *textRight, float value, float minValue, float maxValue)
  2242. {
  2243. return GuiSliderPro(bounds, textLeft, textRight, value, minValue, maxValue, 0);
  2244. }
  2245. // Progress Bar control extended, shows current progress value
  2246. float GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight, float value, float minValue, float maxValue)
  2247. {
  2248. GuiState state = guiState;
  2249. Rectangle progress = { bounds.x + GuiGetStyle(PROGRESSBAR, BORDER_WIDTH),
  2250. bounds.y + GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) + GuiGetStyle(PROGRESSBAR, PROGRESS_PADDING), 0,
  2251. bounds.height - 2*GuiGetStyle(PROGRESSBAR, BORDER_WIDTH) - 2*GuiGetStyle(PROGRESSBAR, PROGRESS_PADDING) };
  2252. // Update control
  2253. //--------------------------------------------------------------------
  2254. if (value > maxValue) value = maxValue;
  2255. if (state != STATE_DISABLED) progress.width = ((float)(value/(maxValue - minValue))*(float)(bounds.width - 2*GuiGetStyle(PROGRESSBAR, BORDER_WIDTH)));
  2256. //--------------------------------------------------------------------
  2257. // Draw control
  2258. //--------------------------------------------------------------------
  2259. GuiDrawRectangle(bounds, GuiGetStyle(PROGRESSBAR, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(PROGRESSBAR, BORDER + (state*3))), guiAlpha), BLANK);
  2260. // Draw slider internal progress bar (depends on state)
  2261. if ((state == STATE_NORMAL) || (state == STATE_PRESSED)) GuiDrawRectangle(progress, 0, BLANK, Fade(GetColor(GuiGetStyle(PROGRESSBAR, BASE_COLOR_PRESSED)), guiAlpha));
  2262. else if (state == STATE_FOCUSED) GuiDrawRectangle(progress, 0, BLANK, Fade(GetColor(GuiGetStyle(PROGRESSBAR, TEXT_COLOR_FOCUSED)), guiAlpha));
  2263. // Draw left/right text if provided
  2264. if (textLeft != NULL)
  2265. {
  2266. Rectangle textBounds = { 0 };
  2267. textBounds.width = (float)GetTextWidth(textLeft);
  2268. textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
  2269. textBounds.x = bounds.x - textBounds.width - GuiGetStyle(PROGRESSBAR, TEXT_PADDING);
  2270. textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
  2271. GuiDrawText(textLeft, textBounds, TEXT_ALIGN_RIGHT, Fade(GetColor(GuiGetStyle(PROGRESSBAR, TEXT + (state*3))), guiAlpha));
  2272. }
  2273. if (textRight != NULL)
  2274. {
  2275. Rectangle textBounds = { 0 };
  2276. textBounds.width = (float)GetTextWidth(textRight);
  2277. textBounds.height = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
  2278. textBounds.x = bounds.x + bounds.width + GuiGetStyle(PROGRESSBAR, TEXT_PADDING);
  2279. textBounds.y = bounds.y + bounds.height/2 - GuiGetStyle(DEFAULT, TEXT_SIZE)/2;
  2280. GuiDrawText(textRight, textBounds, TEXT_ALIGN_LEFT, Fade(GetColor(GuiGetStyle(PROGRESSBAR, TEXT + (state*3))), guiAlpha));
  2281. }
  2282. //--------------------------------------------------------------------
  2283. return value;
  2284. }
  2285. // Status Bar control
  2286. void GuiStatusBar(Rectangle bounds, const char *text)
  2287. {
  2288. GuiState state = guiState;
  2289. // Draw control
  2290. //--------------------------------------------------------------------
  2291. GuiDrawRectangle(bounds, GuiGetStyle(STATUSBAR, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(STATUSBAR, (state != STATE_DISABLED)? BORDER_COLOR_NORMAL : BORDER_COLOR_DISABLED)), guiAlpha),
  2292. Fade(GetColor(GuiGetStyle(STATUSBAR, (state != STATE_DISABLED)? BASE_COLOR_NORMAL : BASE_COLOR_DISABLED)), guiAlpha));
  2293. GuiDrawText(text, GetTextBounds(STATUSBAR, bounds), GuiGetStyle(STATUSBAR, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(STATUSBAR, (state != STATE_DISABLED)? TEXT_COLOR_NORMAL : TEXT_COLOR_DISABLED)), guiAlpha));
  2294. //--------------------------------------------------------------------
  2295. }
  2296. // Dummy rectangle control, intended for placeholding
  2297. void GuiDummyRec(Rectangle bounds, const char *text)
  2298. {
  2299. GuiState state = guiState;
  2300. // Update control
  2301. //--------------------------------------------------------------------
  2302. if ((state != STATE_DISABLED) && !guiLocked)
  2303. {
  2304. Vector2 mousePoint = GetMousePosition();
  2305. // Check button state
  2306. if (CheckCollisionPointRec(mousePoint, bounds))
  2307. {
  2308. if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) state = STATE_PRESSED;
  2309. else state = STATE_FOCUSED;
  2310. }
  2311. }
  2312. //--------------------------------------------------------------------
  2313. // Draw control
  2314. //--------------------------------------------------------------------
  2315. GuiDrawRectangle(bounds, 0, BLANK, Fade(GetColor(GuiGetStyle(DEFAULT, (state != STATE_DISABLED)? BASE_COLOR_NORMAL : BASE_COLOR_DISABLED)), guiAlpha));
  2316. GuiDrawText(text, GetTextBounds(DEFAULT, bounds), TEXT_ALIGN_CENTER, Fade(GetColor(GuiGetStyle(BUTTON, (state != STATE_DISABLED)? TEXT_COLOR_NORMAL : TEXT_COLOR_DISABLED)), guiAlpha));
  2317. //------------------------------------------------------------------
  2318. }
  2319. // List View control
  2320. int GuiListView(Rectangle bounds, const char *text, int *scrollIndex, int active)
  2321. {
  2322. int itemCount = 0;
  2323. const char **items = NULL;
  2324. if (text != NULL) items = GuiTextSplit(text, &itemCount, NULL);
  2325. return GuiListViewEx(bounds, items, itemCount, NULL, scrollIndex, active);
  2326. }
  2327. // List View control with extended parameters
  2328. int GuiListViewEx(Rectangle bounds, const char **text, int count, int *focus, int *scrollIndex, int active)
  2329. {
  2330. GuiState state = guiState;
  2331. int itemFocused = (focus == NULL)? -1 : *focus;
  2332. int itemSelected = active;
  2333. // Check if we need a scroll bar
  2334. bool useScrollBar = false;
  2335. if ((GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT) + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING))*count > bounds.height) useScrollBar = true;
  2336. // Define base item rectangle [0]
  2337. Rectangle itemBounds = { 0 };
  2338. itemBounds.x = bounds.x + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING);
  2339. itemBounds.y = bounds.y + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING) + GuiGetStyle(DEFAULT, BORDER_WIDTH);
  2340. itemBounds.width = bounds.width - 2*GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING) - GuiGetStyle(DEFAULT, BORDER_WIDTH);
  2341. itemBounds.height = (float)GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT);
  2342. if (useScrollBar) itemBounds.width -= GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH);
  2343. // Get items on the list
  2344. int visibleItems = (int)bounds.height/(GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT) + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING));
  2345. if (visibleItems > count) visibleItems = count;
  2346. int startIndex = (scrollIndex == NULL)? 0 : *scrollIndex;
  2347. if ((startIndex < 0) || (startIndex > (count - visibleItems))) startIndex = 0;
  2348. int endIndex = startIndex + visibleItems;
  2349. // Update control
  2350. //--------------------------------------------------------------------
  2351. if ((state != STATE_DISABLED) && !guiLocked)
  2352. {
  2353. Vector2 mousePoint = GetMousePosition();
  2354. // Check mouse inside list view
  2355. if (CheckCollisionPointRec(mousePoint, bounds))
  2356. {
  2357. state = STATE_FOCUSED;
  2358. // Check focused and selected item
  2359. for (int i = 0; i < visibleItems; i++)
  2360. {
  2361. if (CheckCollisionPointRec(mousePoint, itemBounds))
  2362. {
  2363. itemFocused = startIndex + i;
  2364. if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
  2365. {
  2366. if (itemSelected == (startIndex + i)) itemSelected = -1;
  2367. else itemSelected = startIndex + i;
  2368. }
  2369. break;
  2370. }
  2371. // Update item rectangle y position for next item
  2372. itemBounds.y += (GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT) + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING));
  2373. }
  2374. if (useScrollBar)
  2375. {
  2376. int wheelMove = (int)GetMouseWheelMove();
  2377. startIndex -= wheelMove;
  2378. if (startIndex < 0) startIndex = 0;
  2379. else if (startIndex > (count - visibleItems)) startIndex = count - visibleItems;
  2380. endIndex = startIndex + visibleItems;
  2381. if (endIndex > count) endIndex = count;
  2382. }
  2383. }
  2384. else itemFocused = -1;
  2385. // Reset item rectangle y to [0]
  2386. itemBounds.y = bounds.y + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING) + GuiGetStyle(DEFAULT, BORDER_WIDTH);
  2387. }
  2388. //--------------------------------------------------------------------
  2389. // Draw control
  2390. //--------------------------------------------------------------------
  2391. GuiDrawRectangle(bounds, GuiGetStyle(DEFAULT, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(LISTVIEW, BORDER + state*3)), guiAlpha), GetColor(GuiGetStyle(DEFAULT, BACKGROUND_COLOR))); // Draw background
  2392. // Draw visible items
  2393. for (int i = 0; ((i < visibleItems) && (text != NULL)); i++)
  2394. {
  2395. if (state == STATE_DISABLED)
  2396. {
  2397. if ((startIndex + i) == itemSelected) GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_DISABLED)), guiAlpha), Fade(GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_DISABLED)), guiAlpha));
  2398. GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_DISABLED)), guiAlpha));
  2399. }
  2400. else
  2401. {
  2402. if ((startIndex + i) == itemSelected)
  2403. {
  2404. // Draw item selected
  2405. GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_PRESSED)), guiAlpha), Fade(GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_PRESSED)), guiAlpha));
  2406. GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_PRESSED)), guiAlpha));
  2407. }
  2408. else if ((startIndex + i) == itemFocused)
  2409. {
  2410. // Draw item focused
  2411. GuiDrawRectangle(itemBounds, GuiGetStyle(LISTVIEW, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(LISTVIEW, BORDER_COLOR_FOCUSED)), guiAlpha), Fade(GetColor(GuiGetStyle(LISTVIEW, BASE_COLOR_FOCUSED)), guiAlpha));
  2412. GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_FOCUSED)), guiAlpha));
  2413. }
  2414. else
  2415. {
  2416. // Draw item normal
  2417. GuiDrawText(text[startIndex + i], GetTextBounds(DEFAULT, itemBounds), GuiGetStyle(LISTVIEW, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(LISTVIEW, TEXT_COLOR_NORMAL)), guiAlpha));
  2418. }
  2419. }
  2420. // Update item rectangle y position for next item
  2421. itemBounds.y += (GuiGetStyle(LISTVIEW, LIST_ITEMS_HEIGHT) + GuiGetStyle(LISTVIEW, LIST_ITEMS_SPACING));
  2422. }
  2423. if (useScrollBar)
  2424. {
  2425. Rectangle scrollBarBounds = {
  2426. bounds.x + bounds.width - GuiGetStyle(LISTVIEW, BORDER_WIDTH) - GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH),
  2427. bounds.y + GuiGetStyle(LISTVIEW, BORDER_WIDTH), (float)GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH),
  2428. bounds.height - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH)
  2429. };
  2430. // Calculate percentage of visible items and apply same percentage to scrollbar
  2431. float percentVisible = (float)(endIndex - startIndex)/count;
  2432. float sliderSize = bounds.height*percentVisible;
  2433. int prevSliderSize = GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE); // Save default slider size
  2434. int prevScrollSpeed = GuiGetStyle(SCROLLBAR, SCROLL_SPEED); // Save default scroll speed
  2435. GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, (int)sliderSize); // Change slider size
  2436. GuiSetStyle(SCROLLBAR, SCROLL_SPEED, count - visibleItems); // Change scroll speed
  2437. startIndex = GuiScrollBar(scrollBarBounds, startIndex, 0, count - visibleItems);
  2438. GuiSetStyle(SCROLLBAR, SCROLL_SPEED, prevScrollSpeed); // Reset scroll speed to default
  2439. GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, prevSliderSize); // Reset slider size to default
  2440. }
  2441. //--------------------------------------------------------------------
  2442. if (focus != NULL) *focus = itemFocused;
  2443. if (scrollIndex != NULL) *scrollIndex = startIndex;
  2444. return itemSelected;
  2445. }
  2446. // Color Panel control
  2447. Color GuiColorPanel(Rectangle bounds, const char *text, Color color)
  2448. {
  2449. const Color colWhite = { 255, 255, 255, 255 };
  2450. const Color colBlack = { 0, 0, 0, 255 };
  2451. GuiState state = guiState;
  2452. Vector2 pickerSelector = { 0 };
  2453. Vector3 vcolor = { (float)color.r/255.0f, (float)color.g/255.0f, (float)color.b/255.0f };
  2454. Vector3 hsv = ConvertRGBtoHSV(vcolor);
  2455. pickerSelector.x = bounds.x + (float)hsv.y*bounds.width; // HSV: Saturation
  2456. pickerSelector.y = bounds.y + (1.0f - (float)hsv.z)*bounds.height; // HSV: Value
  2457. float hue = -1.0f;
  2458. Vector3 maxHue = { hue >= 0.0f ? hue : hsv.x, 1.0f, 1.0f };
  2459. Vector3 rgbHue = ConvertHSVtoRGB(maxHue);
  2460. Color maxHueCol = { (unsigned char)(255.0f*rgbHue.x),
  2461. (unsigned char)(255.0f*rgbHue.y),
  2462. (unsigned char)(255.0f*rgbHue.z), 255 };
  2463. // Update control
  2464. //--------------------------------------------------------------------
  2465. if ((state != STATE_DISABLED) && !guiLocked)
  2466. {
  2467. Vector2 mousePoint = GetMousePosition();
  2468. if (CheckCollisionPointRec(mousePoint, bounds))
  2469. {
  2470. if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
  2471. {
  2472. state = STATE_PRESSED;
  2473. pickerSelector = mousePoint;
  2474. // Calculate color from picker
  2475. Vector2 colorPick = { pickerSelector.x - bounds.x, pickerSelector.y - bounds.y };
  2476. colorPick.x /= (float)bounds.width; // Get normalized value on x
  2477. colorPick.y /= (float)bounds.height; // Get normalized value on y
  2478. hsv.y = colorPick.x;
  2479. hsv.z = 1.0f - colorPick.y;
  2480. Vector3 rgb = ConvertHSVtoRGB(hsv);
  2481. // NOTE: Vector3ToColor() only available on raylib 1.8.1
  2482. color = RAYGUI_CLITERAL(Color){ (unsigned char)(255.0f*rgb.x),
  2483. (unsigned char)(255.0f*rgb.y),
  2484. (unsigned char)(255.0f*rgb.z),
  2485. (unsigned char)(255.0f*(float)color.a/255.0f) };
  2486. }
  2487. else state = STATE_FOCUSED;
  2488. }
  2489. }
  2490. //--------------------------------------------------------------------
  2491. // Draw control
  2492. //--------------------------------------------------------------------
  2493. if (state != STATE_DISABLED)
  2494. {
  2495. DrawRectangleGradientEx(bounds, Fade(colWhite, guiAlpha), Fade(colWhite, guiAlpha), Fade(maxHueCol, guiAlpha), Fade(maxHueCol, guiAlpha));
  2496. DrawRectangleGradientEx(bounds, Fade(colBlack, 0), Fade(colBlack, guiAlpha), Fade(colBlack, guiAlpha), Fade(colBlack, 0));
  2497. // Draw color picker: selector
  2498. Rectangle selector = { pickerSelector.x - GuiGetStyle(COLORPICKER, COLOR_SELECTOR_SIZE)/2, pickerSelector.y - GuiGetStyle(COLORPICKER, COLOR_SELECTOR_SIZE)/2, (float)GuiGetStyle(COLORPICKER, COLOR_SELECTOR_SIZE), (float)GuiGetStyle(COLORPICKER, COLOR_SELECTOR_SIZE) };
  2499. GuiDrawRectangle(selector, 0, BLANK, Fade(colWhite, guiAlpha));
  2500. }
  2501. else
  2502. {
  2503. DrawRectangleGradientEx(bounds, Fade(Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.1f), guiAlpha), Fade(Fade(colBlack, 0.6f), guiAlpha), Fade(Fade(colBlack, 0.6f), guiAlpha), Fade(Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), 0.6f), guiAlpha));
  2504. }
  2505. GuiDrawRectangle(bounds, GuiGetStyle(COLORPICKER, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)), guiAlpha), BLANK);
  2506. //--------------------------------------------------------------------
  2507. return color;
  2508. }
  2509. // Color Bar Alpha control
  2510. // NOTE: Returns alpha value normalized [0..1]
  2511. float GuiColorBarAlpha(Rectangle bounds, const char *text, float alpha)
  2512. {
  2513. #if !defined(RAYGUI_COLORBARALPHA_CHECKED_SIZE)
  2514. #define RAYGUI_COLORBARALPHA_CHECKED_SIZE 10
  2515. #endif
  2516. GuiState state = guiState;
  2517. Rectangle selector = { (float)bounds.x + alpha*bounds.width - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT)/2, (float)bounds.y - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW), (float)GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT), (float)bounds.height + GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW)*2 };
  2518. // Update control
  2519. //--------------------------------------------------------------------
  2520. if ((state != STATE_DISABLED) && !guiLocked)
  2521. {
  2522. Vector2 mousePoint = GetMousePosition();
  2523. if (CheckCollisionPointRec(mousePoint, bounds) ||
  2524. CheckCollisionPointRec(mousePoint, selector))
  2525. {
  2526. if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
  2527. {
  2528. state = STATE_PRESSED;
  2529. alpha = (mousePoint.x - bounds.x)/bounds.width;
  2530. if (alpha <= 0.0f) alpha = 0.0f;
  2531. if (alpha >= 1.0f) alpha = 1.0f;
  2532. //selector.x = bounds.x + (int)(((alpha - 0)/(100 - 0))*(bounds.width - 2*GuiGetStyle(SLIDER, BORDER_WIDTH))) - selector.width/2;
  2533. }
  2534. else state = STATE_FOCUSED;
  2535. }
  2536. }
  2537. //--------------------------------------------------------------------
  2538. // Draw control
  2539. //--------------------------------------------------------------------
  2540. // Draw alpha bar: checked background
  2541. if (state != STATE_DISABLED)
  2542. {
  2543. int checksX = (int)bounds.width/RAYGUI_COLORBARALPHA_CHECKED_SIZE;
  2544. int checksY = (int)bounds.height/RAYGUI_COLORBARALPHA_CHECKED_SIZE;
  2545. for (int x = 0; x < checksX; x++)
  2546. {
  2547. for (int y = 0; y < checksY; y++)
  2548. {
  2549. Rectangle check = { bounds.x + x*RAYGUI_COLORBARALPHA_CHECKED_SIZE, bounds.y + y*RAYGUI_COLORBARALPHA_CHECKED_SIZE, RAYGUI_COLORBARALPHA_CHECKED_SIZE, RAYGUI_COLORBARALPHA_CHECKED_SIZE };
  2550. GuiDrawRectangle(check, 0, BLANK, ((x + y)%2)? Fade(Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), 0.4f), guiAlpha) : Fade(Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.4f), guiAlpha));
  2551. }
  2552. }
  2553. DrawRectangleGradientEx(bounds, RAYGUI_CLITERAL(Color){ 255, 255, 255, 0 }, RAYGUI_CLITERAL(Color){ 255, 255, 255, 0 }, Fade(RAYGUI_CLITERAL(Color){ 0, 0, 0, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color){ 0, 0, 0, 255 }, guiAlpha));
  2554. }
  2555. else DrawRectangleGradientEx(bounds, Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.1f), Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.1f), Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), guiAlpha), Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), guiAlpha));
  2556. GuiDrawRectangle(bounds, GuiGetStyle(COLORPICKER, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)), guiAlpha), BLANK);
  2557. // Draw alpha bar: selector
  2558. GuiDrawRectangle(selector, 0, BLANK, Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)), guiAlpha));
  2559. //--------------------------------------------------------------------
  2560. return alpha;
  2561. }
  2562. // Color Bar Hue control
  2563. // Returns hue value normalized [0..1]
  2564. // NOTE: Other similar bars (for reference):
  2565. // Color GuiColorBarSat() [WHITE->color]
  2566. // Color GuiColorBarValue() [BLACK->color], HSV/HSL
  2567. // float GuiColorBarLuminance() [BLACK->WHITE]
  2568. float GuiColorBarHue(Rectangle bounds, const char *text, float hue)
  2569. {
  2570. GuiState state = guiState;
  2571. Rectangle selector = { (float)bounds.x - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW), (float)bounds.y + hue/360.0f*bounds.height - GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT)/2, (float)bounds.width + GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW)*2, (float)GuiGetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT) };
  2572. // Update control
  2573. //--------------------------------------------------------------------
  2574. if ((state != STATE_DISABLED) && !guiLocked)
  2575. {
  2576. Vector2 mousePoint = GetMousePosition();
  2577. if (CheckCollisionPointRec(mousePoint, bounds) ||
  2578. CheckCollisionPointRec(mousePoint, selector))
  2579. {
  2580. if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
  2581. {
  2582. state = STATE_PRESSED;
  2583. hue = (mousePoint.y - bounds.y)*360/bounds.height;
  2584. if (hue <= 0.0f) hue = 0.0f;
  2585. if (hue >= 359.0f) hue = 359.0f;
  2586. }
  2587. else state = STATE_FOCUSED;
  2588. /*if (IsKeyDown(KEY_UP))
  2589. {
  2590. hue -= 2.0f;
  2591. if (hue <= 0.0f) hue = 0.0f;
  2592. }
  2593. else if (IsKeyDown(KEY_DOWN))
  2594. {
  2595. hue += 2.0f;
  2596. if (hue >= 360.0f) hue = 360.0f;
  2597. }*/
  2598. }
  2599. }
  2600. //--------------------------------------------------------------------
  2601. // Draw control
  2602. //--------------------------------------------------------------------
  2603. if (state != STATE_DISABLED)
  2604. {
  2605. // Draw hue bar:color bars
  2606. DrawRectangleGradientV((int)bounds.x, (int)(bounds.y), (int)bounds.width, (int)ceilf(bounds.height/6), Fade(RAYGUI_CLITERAL(Color) { 255, 0, 0, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color) { 255, 255, 0, 255 }, guiAlpha));
  2607. DrawRectangleGradientV((int)bounds.x, (int)(bounds.y + bounds.height/6), (int)bounds.width, (int)ceilf(bounds.height/6), Fade(RAYGUI_CLITERAL(Color) { 255, 255, 0, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color) { 0, 255, 0, 255 }, guiAlpha));
  2608. DrawRectangleGradientV((int)bounds.x, (int)(bounds.y + 2*(bounds.height/6)), (int)bounds.width, (int)ceilf(bounds.height/6), Fade(RAYGUI_CLITERAL(Color) { 0, 255, 0, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color) { 0, 255, 255, 255 }, guiAlpha));
  2609. DrawRectangleGradientV((int)bounds.x, (int)(bounds.y + 3*(bounds.height/6)), (int)bounds.width, (int)ceilf(bounds.height/6), Fade(RAYGUI_CLITERAL(Color) { 0, 255, 255, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color) { 0, 0, 255, 255 }, guiAlpha));
  2610. DrawRectangleGradientV((int)bounds.x, (int)(bounds.y + 4*(bounds.height/6)), (int)bounds.width, (int)ceilf(bounds.height/6), Fade(RAYGUI_CLITERAL(Color) { 0, 0, 255, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color) { 255, 0, 255, 255 }, guiAlpha));
  2611. DrawRectangleGradientV((int)bounds.x, (int)(bounds.y + 5*(bounds.height/6)), (int)bounds.width, (int)(bounds.height/6), Fade(RAYGUI_CLITERAL(Color) { 255, 0, 255, 255 }, guiAlpha), Fade(RAYGUI_CLITERAL(Color) { 255, 0, 0, 255 }, guiAlpha));
  2612. }
  2613. else DrawRectangleGradientV((int)bounds.x, (int)bounds.y, (int)bounds.width, (int)bounds.height, Fade(Fade(GetColor(GuiGetStyle(COLORPICKER, BASE_COLOR_DISABLED)), 0.1f), guiAlpha), Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER_COLOR_DISABLED)), guiAlpha));
  2614. GuiDrawRectangle(bounds, GuiGetStyle(COLORPICKER, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)), guiAlpha), BLANK);
  2615. // Draw hue bar: selector
  2616. GuiDrawRectangle(selector, 0, BLANK, Fade(GetColor(GuiGetStyle(COLORPICKER, BORDER + state*3)), guiAlpha));
  2617. //--------------------------------------------------------------------
  2618. return hue;
  2619. }
  2620. // Color Picker control
  2621. // NOTE: It's divided in multiple controls:
  2622. // Color GuiColorPanel(Rectangle bounds, Color color)
  2623. // float GuiColorBarAlpha(Rectangle bounds, float alpha)
  2624. // float GuiColorBarHue(Rectangle bounds, float value)
  2625. // NOTE: bounds define GuiColorPanel() size
  2626. Color GuiColorPicker(Rectangle bounds, const char *text, Color color)
  2627. {
  2628. color = GuiColorPanel(bounds, NULL, color);
  2629. Rectangle boundsHue = { (float)bounds.x + bounds.width + GuiGetStyle(COLORPICKER, HUEBAR_PADDING), (float)bounds.y, (float)GuiGetStyle(COLORPICKER, HUEBAR_WIDTH), (float)bounds.height };
  2630. //Rectangle boundsAlpha = { bounds.x, bounds.y + bounds.height + GuiGetStyle(COLORPICKER, BARS_PADDING), bounds.width, GuiGetStyle(COLORPICKER, BARS_THICK) };
  2631. Vector3 hsv = ConvertRGBtoHSV(RAYGUI_CLITERAL(Vector3){ color.r/255.0f, color.g/255.0f, color.b/255.0f });
  2632. hsv.x = GuiColorBarHue(boundsHue, NULL, hsv.x);
  2633. //color.a = (unsigned char)(GuiColorBarAlpha(boundsAlpha, (float)color.a/255.0f)*255.0f);
  2634. Vector3 rgb = ConvertHSVtoRGB(hsv);
  2635. color = RAYGUI_CLITERAL(Color){ (unsigned char)roundf(rgb.x*255.0f), (unsigned char)roundf(rgb.y*255.0f), (unsigned char)roundf(rgb.z*255.0f), color.a };
  2636. return color;
  2637. }
  2638. // Message Box control
  2639. int GuiMessageBox(Rectangle bounds, const char *title, const char *message, const char *buttons)
  2640. {
  2641. #if !defined(RAYGUI_MESSAGEBOX_BUTTON_HEIGHT)
  2642. #define RAYGUI_MESSAGEBOX_BUTTON_HEIGHT 24
  2643. #endif
  2644. #if !defined(RAYGUI_MESSAGEBOX_BUTTON_PADDING)
  2645. #define RAYGUI_MESSAGEBOX_BUTTON_PADDING 12
  2646. #endif
  2647. int clicked = -1; // Returns clicked button from buttons list, 0 refers to closed window button
  2648. int buttonCount = 0;
  2649. const char **buttonsText = GuiTextSplit(buttons, &buttonCount, NULL);
  2650. Rectangle buttonBounds = { 0 };
  2651. buttonBounds.x = bounds.x + RAYGUI_MESSAGEBOX_BUTTON_PADDING;
  2652. buttonBounds.y = bounds.y + bounds.height - RAYGUI_MESSAGEBOX_BUTTON_HEIGHT - RAYGUI_MESSAGEBOX_BUTTON_PADDING;
  2653. buttonBounds.width = (bounds.width - RAYGUI_MESSAGEBOX_BUTTON_PADDING*(buttonCount + 1))/buttonCount;
  2654. buttonBounds.height = RAYGUI_MESSAGEBOX_BUTTON_HEIGHT;
  2655. Vector2 textSize = MeasureTextEx(guiFont, message, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), 1);
  2656. Rectangle textBounds = { 0 };
  2657. textBounds.x = bounds.x + bounds.width/2 - textSize.x/2;
  2658. textBounds.y = bounds.y + RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT + RAYGUI_MESSAGEBOX_BUTTON_PADDING;
  2659. textBounds.width = textSize.x;
  2660. textBounds.height = bounds.height - RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT - 3*RAYGUI_MESSAGEBOX_BUTTON_PADDING - RAYGUI_MESSAGEBOX_BUTTON_HEIGHT;
  2661. // Draw control
  2662. //--------------------------------------------------------------------
  2663. if (GuiWindowBox(bounds, title)) clicked = 0;
  2664. int prevTextAlignment = GuiGetStyle(LABEL, TEXT_ALIGNMENT);
  2665. GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER);
  2666. GuiLabel(textBounds, message);
  2667. GuiSetStyle(LABEL, TEXT_ALIGNMENT, prevTextAlignment);
  2668. prevTextAlignment = GuiGetStyle(BUTTON, TEXT_ALIGNMENT);
  2669. GuiSetStyle(BUTTON, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER);
  2670. for (int i = 0; i < buttonCount; i++)
  2671. {
  2672. if (GuiButton(buttonBounds, buttonsText[i])) clicked = i + 1;
  2673. buttonBounds.x += (buttonBounds.width + RAYGUI_MESSAGEBOX_BUTTON_PADDING);
  2674. }
  2675. GuiSetStyle(BUTTON, TEXT_ALIGNMENT, prevTextAlignment);
  2676. //--------------------------------------------------------------------
  2677. return clicked;
  2678. }
  2679. // Text Input Box control, ask for text
  2680. int GuiTextInputBox(Rectangle bounds, const char *title, const char *message, const char *buttons, char *text, int textMaxSize, int *secretViewActive)
  2681. {
  2682. #if !defined(RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT)
  2683. #define RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT 28
  2684. #endif
  2685. #if !defined(RAYGUI_TEXTINPUTBOX_BUTTON_PADDING)
  2686. #define RAYGUI_TEXTINPUTBOX_BUTTON_PADDING 12
  2687. #endif
  2688. #if !defined(RAYGUI_TEXTINPUTBOX_HEIGHT)
  2689. #define RAYGUI_TEXTINPUTBOX_HEIGHT 28
  2690. #endif
  2691. // Used to enable text edit mode
  2692. // WARNING: No more than one GuiTextInputBox() should be open at the same time
  2693. static bool textEditMode = false;
  2694. int btnIndex = -1;
  2695. int buttonCount = 0;
  2696. const char **buttonsText = GuiTextSplit(buttons, &buttonCount, NULL);
  2697. Rectangle buttonBounds = { 0 };
  2698. buttonBounds.x = bounds.x + RAYGUI_TEXTINPUTBOX_BUTTON_PADDING;
  2699. buttonBounds.y = bounds.y + bounds.height - RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT - RAYGUI_TEXTINPUTBOX_BUTTON_PADDING;
  2700. buttonBounds.width = (bounds.width - RAYGUI_TEXTINPUTBOX_BUTTON_PADDING*(buttonCount + 1))/buttonCount;
  2701. buttonBounds.height = RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT;
  2702. int messageInputHeight = (int)bounds.height - RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT - GuiGetStyle(STATUSBAR, BORDER_WIDTH) - RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT - 2*RAYGUI_TEXTINPUTBOX_BUTTON_PADDING;
  2703. Rectangle textBounds = { 0 };
  2704. if (message != NULL)
  2705. {
  2706. Vector2 textSize = MeasureTextEx(guiFont, message, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), 1);
  2707. textBounds.x = bounds.x + bounds.width/2 - textSize.x/2;
  2708. textBounds.y = bounds.y + RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT + messageInputHeight/4 - textSize.y/2;
  2709. textBounds.width = textSize.x;
  2710. textBounds.height = textSize.y;
  2711. }
  2712. Rectangle textBoxBounds = { 0 };
  2713. textBoxBounds.x = bounds.x + RAYGUI_TEXTINPUTBOX_BUTTON_PADDING;
  2714. textBoxBounds.y = bounds.y + RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT - RAYGUI_TEXTINPUTBOX_HEIGHT/2;
  2715. if (message == NULL) textBoxBounds.y = bounds.y + 24 + RAYGUI_TEXTINPUTBOX_BUTTON_PADDING;
  2716. else textBoxBounds.y += (messageInputHeight/2 + messageInputHeight/4);
  2717. textBoxBounds.width = bounds.width - RAYGUI_TEXTINPUTBOX_BUTTON_PADDING*2;
  2718. textBoxBounds.height = RAYGUI_TEXTINPUTBOX_HEIGHT;
  2719. // Draw control
  2720. //--------------------------------------------------------------------
  2721. if (GuiWindowBox(bounds, title)) btnIndex = 0;
  2722. // Draw message if available
  2723. if (message != NULL)
  2724. {
  2725. int prevTextAlignment = GuiGetStyle(LABEL, TEXT_ALIGNMENT);
  2726. GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER);
  2727. GuiLabel(textBounds, message);
  2728. GuiSetStyle(LABEL, TEXT_ALIGNMENT, prevTextAlignment);
  2729. }
  2730. if (secretViewActive != NULL)
  2731. {
  2732. static char stars[] = "****************";
  2733. if (GuiTextBox(RAYGUI_CLITERAL(Rectangle){ textBoxBounds.x, textBoxBounds.y, textBoxBounds.width - 4 - RAYGUI_TEXTINPUTBOX_HEIGHT, textBoxBounds.height },
  2734. ((*secretViewActive == 1) || textEditMode)? text : stars, textMaxSize, textEditMode)) textEditMode = !textEditMode;
  2735. *secretViewActive = GuiToggle(RAYGUI_CLITERAL(Rectangle){ textBoxBounds.x + textBoxBounds.width - RAYGUI_TEXTINPUTBOX_HEIGHT, textBoxBounds.y, RAYGUI_TEXTINPUTBOX_HEIGHT, RAYGUI_TEXTINPUTBOX_HEIGHT }, (*secretViewActive == 1)? "#44#" : "#45#", *secretViewActive);
  2736. }
  2737. else
  2738. {
  2739. if (GuiTextBox(textBoxBounds, text, textMaxSize, textEditMode)) textEditMode = !textEditMode;
  2740. }
  2741. int prevBtnTextAlignment = GuiGetStyle(BUTTON, TEXT_ALIGNMENT);
  2742. GuiSetStyle(BUTTON, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER);
  2743. for (int i = 0; i < buttonCount; i++)
  2744. {
  2745. if (GuiButton(buttonBounds, buttonsText[i])) btnIndex = i + 1;
  2746. buttonBounds.x += (buttonBounds.width + RAYGUI_MESSAGEBOX_BUTTON_PADDING);
  2747. }
  2748. GuiSetStyle(BUTTON, TEXT_ALIGNMENT, prevBtnTextAlignment);
  2749. //--------------------------------------------------------------------
  2750. return btnIndex;
  2751. }
  2752. // Grid control
  2753. // NOTE: Returns grid mouse-hover selected cell
  2754. // About drawing lines at subpixel spacing, simple put, not easy solution:
  2755. // https://stackoverflow.com/questions/4435450/2d-opengl-drawing-lines-that-dont-exactly-fit-pixel-raster
  2756. Vector2 GuiGrid(Rectangle bounds, const char *text, float spacing, int subdivs)
  2757. {
  2758. // Grid lines alpha amount
  2759. #if !defined(RAYGUI_GRID_ALPHA)
  2760. #define RAYGUI_GRID_ALPHA 0.15f
  2761. #endif
  2762. GuiState state = guiState;
  2763. Vector2 mousePoint = GetMousePosition();
  2764. Vector2 currentCell = { -1, -1 };
  2765. int linesV = ((int)(bounds.width/spacing))*subdivs + 1;
  2766. int linesH = ((int)(bounds.height/spacing))*subdivs + 1;
  2767. // Update control
  2768. //--------------------------------------------------------------------
  2769. if ((state != STATE_DISABLED) && !guiLocked)
  2770. {
  2771. if (CheckCollisionPointRec(mousePoint, bounds))
  2772. {
  2773. // NOTE: Cell values must be rounded to int
  2774. currentCell.x = (int)((mousePoint.x - bounds.x)/spacing);
  2775. currentCell.y = (int)((mousePoint.y - bounds.y)/spacing);
  2776. }
  2777. }
  2778. //--------------------------------------------------------------------
  2779. // Draw control
  2780. //--------------------------------------------------------------------
  2781. // TODO: Draw background panel?
  2782. switch (state)
  2783. {
  2784. case STATE_NORMAL:
  2785. {
  2786. if (subdivs > 0)
  2787. {
  2788. // Draw vertical grid lines
  2789. for (int i = 0; i < linesV; i++)
  2790. {
  2791. Rectangle lineV = { bounds.x + spacing*i/subdivs, bounds.y, 1, bounds.height };
  2792. GuiDrawRectangle(lineV, 0, BLANK, ((i%subdivs) == 0) ? Fade(GetColor(GuiGetStyle(DEFAULT, LINE_COLOR)), RAYGUI_GRID_ALPHA*4) : Fade(GetColor(GuiGetStyle(DEFAULT, LINE_COLOR)), RAYGUI_GRID_ALPHA));
  2793. }
  2794. // Draw horizontal grid lines
  2795. for (int i = 0; i < linesH; i++)
  2796. {
  2797. Rectangle lineH = { bounds.x, bounds.y + spacing*i/subdivs, bounds.width, 1 };
  2798. GuiDrawRectangle(lineH, 0, BLANK, ((i%subdivs) == 0) ? Fade(GetColor(GuiGetStyle(DEFAULT, LINE_COLOR)), RAYGUI_GRID_ALPHA*4) : Fade(GetColor(GuiGetStyle(DEFAULT, LINE_COLOR)), RAYGUI_GRID_ALPHA));
  2799. }
  2800. }
  2801. } break;
  2802. default: break;
  2803. }
  2804. return currentCell;
  2805. }
  2806. //----------------------------------------------------------------------------------
  2807. // Styles loading functions
  2808. //----------------------------------------------------------------------------------
  2809. // Load raygui style file (.rgs)
  2810. // NOTE: By default a binary file is expected, that file could contain a custom font,
  2811. // in that case, custom font image atlas is GRAY+ALPHA and pixel data can be compressed (DEFLATE)
  2812. void GuiLoadStyle(const char *fileName)
  2813. {
  2814. #define MAX_LINE_BUFFER_SIZE 256
  2815. bool tryBinary = false;
  2816. // Try reading the files as text file first
  2817. FILE *rgsFile = fopen(fileName, "rt");
  2818. if (rgsFile != NULL)
  2819. {
  2820. char buffer[MAX_LINE_BUFFER_SIZE] = { 0 };
  2821. fgets(buffer, MAX_LINE_BUFFER_SIZE, rgsFile);
  2822. if (buffer[0] == '#')
  2823. {
  2824. int controlId = 0;
  2825. int propertyId = 0;
  2826. unsigned int propertyValue = 0;
  2827. while (!feof(rgsFile))
  2828. {
  2829. switch (buffer[0])
  2830. {
  2831. case 'p':
  2832. {
  2833. // Style property: p <control_id> <property_id> <property_value> <property_name>
  2834. sscanf(buffer, "p %d %d 0x%x", &controlId, &propertyId, &propertyValue);
  2835. GuiSetStyle(controlId, propertyId, (int)propertyValue);
  2836. } break;
  2837. case 'f':
  2838. {
  2839. // Style font: f <gen_font_size> <charmap_file> <font_file>
  2840. int fontSize = 0;
  2841. char charmapFileName[256] = { 0 };
  2842. char fontFileName[256] = { 0 };
  2843. sscanf(buffer, "f %d %s %[^\r\n]s", &fontSize, charmapFileName, fontFileName);
  2844. Font font = { 0 };
  2845. if (charmapFileName[0] != '0')
  2846. {
  2847. // Load characters from charmap file,
  2848. // expected '\n' separated list of integer values
  2849. char *charValues = LoadFileText(charmapFileName);
  2850. if (charValues != NULL)
  2851. {
  2852. int glyphCount = 0;
  2853. const char **chars = TextSplit(charValues, '\n', &glyphCount);
  2854. int *values = (int *)RAYGUI_MALLOC(glyphCount*sizeof(int));
  2855. for (int i = 0; i < glyphCount; i++) values[i] = TextToInteger(chars[i]);
  2856. if (font.texture.id != GetFontDefault().texture.id) UnloadTexture(font.texture);
  2857. font = LoadFontEx(TextFormat("%s/%s", GetDirectoryPath(fileName), fontFileName), fontSize, values, glyphCount);
  2858. if (font.texture.id == 0) font = GetFontDefault();
  2859. RAYGUI_FREE(values);
  2860. }
  2861. }
  2862. else
  2863. {
  2864. if (font.texture.id != GetFontDefault().texture.id) UnloadTexture(font.texture);
  2865. font = LoadFontEx(TextFormat("%s/%s", GetDirectoryPath(fileName), fontFileName), fontSize, NULL, 0);
  2866. if (font.texture.id == 0) font = GetFontDefault();
  2867. }
  2868. if ((font.texture.id > 0) && (font.glyphCount > 0)) GuiSetFont(font);
  2869. } break;
  2870. default: break;
  2871. }
  2872. fgets(buffer, MAX_LINE_BUFFER_SIZE, rgsFile);
  2873. }
  2874. }
  2875. else tryBinary = true;
  2876. fclose(rgsFile);
  2877. }
  2878. if (tryBinary)
  2879. {
  2880. rgsFile = fopen(fileName, "rb");
  2881. if (rgsFile == NULL) return;
  2882. char signature[5] = { 0 };
  2883. short version = 0;
  2884. short reserved = 0;
  2885. int propertyCount = 0;
  2886. fread(signature, 1, 4, rgsFile);
  2887. fread(&version, 1, sizeof(short), rgsFile);
  2888. fread(&reserved, 1, sizeof(short), rgsFile);
  2889. fread(&propertyCount, 1, sizeof(int), rgsFile);
  2890. if ((signature[0] == 'r') &&
  2891. (signature[1] == 'G') &&
  2892. (signature[2] == 'S') &&
  2893. (signature[3] == ' '))
  2894. {
  2895. short controlId = 0;
  2896. short propertyId = 0;
  2897. unsigned int propertyValue = 0;
  2898. for (int i = 0; i < propertyCount; i++)
  2899. {
  2900. fread(&controlId, 1, sizeof(short), rgsFile);
  2901. fread(&propertyId, 1, sizeof(short), rgsFile);
  2902. fread(&propertyValue, 1, sizeof(unsigned int), rgsFile);
  2903. if (controlId == 0) // DEFAULT control
  2904. {
  2905. // If a DEFAULT property is loaded, it is propagated to all controls
  2906. // NOTE: All DEFAULT properties should be defined first in the file
  2907. GuiSetStyle(0, (int)propertyId, propertyValue);
  2908. if (propertyId < RAYGUI_MAX_PROPS_BASE) for (int i = 1; i < RAYGUI_MAX_CONTROLS; i++) GuiSetStyle(i, (int)propertyId, propertyValue);
  2909. }
  2910. else GuiSetStyle((int)controlId, (int)propertyId, propertyValue);
  2911. }
  2912. // Font loading is highly dependant on raylib API to load font data and image
  2913. #if !defined(RAYGUI_STANDALONE)
  2914. // Load custom font if available
  2915. int fontDataSize = 0;
  2916. fread(&fontDataSize, 1, sizeof(int), rgsFile);
  2917. if (fontDataSize > 0)
  2918. {
  2919. Font font = { 0 };
  2920. int fontType = 0; // 0-Normal, 1-SDF
  2921. Rectangle whiteRec = { 0 };
  2922. fread(&font.baseSize, 1, sizeof(int), rgsFile);
  2923. fread(&font.glyphCount, 1, sizeof(int), rgsFile);
  2924. fread(&fontType, 1, sizeof(int), rgsFile);
  2925. // Load font white rectangle
  2926. fread(&whiteRec, 1, sizeof(Rectangle), rgsFile);
  2927. // Load font image parameters
  2928. int fontImageUncompSize = 0;
  2929. int fontImageCompSize = 0;
  2930. fread(&fontImageUncompSize, 1, sizeof(int), rgsFile);
  2931. fread(&fontImageCompSize, 1, sizeof(int), rgsFile);
  2932. Image imFont = { 0 };
  2933. imFont.mipmaps = 1;
  2934. fread(&imFont.width, 1, sizeof(int), rgsFile);
  2935. fread(&imFont.height, 1, sizeof(int), rgsFile);
  2936. fread(&imFont.format, 1, sizeof(int), rgsFile);
  2937. if (fontImageCompSize < fontImageUncompSize)
  2938. {
  2939. // Compressed font atlas image data (DEFLATE), it requires DecompressData()
  2940. int dataUncompSize = 0;
  2941. unsigned char *compData = (unsigned char *)RAYGUI_MALLOC(fontImageCompSize);
  2942. fread(compData, 1, fontImageCompSize, rgsFile);
  2943. imFont.data = DecompressData(compData, fontImageCompSize, &dataUncompSize);
  2944. // Security check, dataUncompSize must match the provided fontImageUncompSize
  2945. if (dataUncompSize != fontImageUncompSize) RAYGUI_LOG("WARNING: Uncompressed font atlas image data could be corrupted");
  2946. RAYGUI_FREE(compData);
  2947. }
  2948. else
  2949. {
  2950. // Font atlas image data is not compressed
  2951. imFont.data = (unsigned char *)RAYGUI_MALLOC(fontImageUncompSize);
  2952. fread(imFont.data, 1, fontImageUncompSize, rgsFile);
  2953. }
  2954. if (font.texture.id != GetFontDefault().texture.id) UnloadTexture(font.texture);
  2955. font.texture = LoadTextureFromImage(imFont);
  2956. if (font.texture.id == 0) font = GetFontDefault();
  2957. RAYGUI_FREE(imFont.data);
  2958. // Load font recs data
  2959. font.recs = (Rectangle *)RAYGUI_CALLOC(font.glyphCount, sizeof(Rectangle));
  2960. for (int i = 0; i < font.glyphCount; i++) fread(&font.recs[i], 1, sizeof(Rectangle), rgsFile);
  2961. // Load font chars info data
  2962. font.glyphs = (GlyphInfo *)RAYGUI_CALLOC(font.glyphCount, sizeof(GlyphInfo));
  2963. for (int i = 0; i < font.glyphCount; i++)
  2964. {
  2965. fread(&font.glyphs[i].value, 1, sizeof(int), rgsFile);
  2966. fread(&font.glyphs[i].offsetX, 1, sizeof(int), rgsFile);
  2967. fread(&font.glyphs[i].offsetY, 1, sizeof(int), rgsFile);
  2968. fread(&font.glyphs[i].advanceX, 1, sizeof(int), rgsFile);
  2969. }
  2970. GuiSetFont(font);
  2971. // Set font texture source rectangle to be used as white texture to draw shapes
  2972. // NOTE: This way, all gui can be draw using a single draw call
  2973. if ((whiteRec.width != 0) && (whiteRec.height != 0)) SetShapesTexture(font.texture, whiteRec);
  2974. }
  2975. #endif
  2976. }
  2977. fclose(rgsFile);
  2978. }
  2979. }
  2980. // Load style default over global style
  2981. void GuiLoadStyleDefault(void)
  2982. {
  2983. // We set this variable first to avoid cyclic function calls
  2984. // when calling GuiSetStyle() and GuiGetStyle()
  2985. guiStyleLoaded = true;
  2986. // Initialize default LIGHT style property values
  2987. GuiSetStyle(DEFAULT, BORDER_COLOR_NORMAL, 0x838383ff);
  2988. GuiSetStyle(DEFAULT, BASE_COLOR_NORMAL, 0xc9c9c9ff);
  2989. GuiSetStyle(DEFAULT, TEXT_COLOR_NORMAL, 0x686868ff);
  2990. GuiSetStyle(DEFAULT, BORDER_COLOR_FOCUSED, 0x5bb2d9ff);
  2991. GuiSetStyle(DEFAULT, BASE_COLOR_FOCUSED, 0xc9effeff);
  2992. GuiSetStyle(DEFAULT, TEXT_COLOR_FOCUSED, 0x6c9bbcff);
  2993. GuiSetStyle(DEFAULT, BORDER_COLOR_PRESSED, 0x0492c7ff);
  2994. GuiSetStyle(DEFAULT, BASE_COLOR_PRESSED, 0x97e8ffff);
  2995. GuiSetStyle(DEFAULT, TEXT_COLOR_PRESSED, 0x368bafff);
  2996. GuiSetStyle(DEFAULT, BORDER_COLOR_DISABLED, 0xb5c1c2ff);
  2997. GuiSetStyle(DEFAULT, BASE_COLOR_DISABLED, 0xe6e9e9ff);
  2998. GuiSetStyle(DEFAULT, TEXT_COLOR_DISABLED, 0xaeb7b8ff);
  2999. GuiSetStyle(DEFAULT, BORDER_WIDTH, 1); // WARNING: Some controls use other values
  3000. GuiSetStyle(DEFAULT, TEXT_PADDING, 0); // WARNING: Some controls use other values
  3001. GuiSetStyle(DEFAULT, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); // WARNING: Some controls use other values
  3002. // Initialize control-specific property values
  3003. // NOTE: Those properties are in default list but require specific values by control type
  3004. GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
  3005. GuiSetStyle(BUTTON, BORDER_WIDTH, 2);
  3006. GuiSetStyle(SLIDER, TEXT_PADDING, 4);
  3007. GuiSetStyle(CHECKBOX, TEXT_PADDING, 4);
  3008. GuiSetStyle(CHECKBOX, TEXT_ALIGNMENT, TEXT_ALIGN_RIGHT);
  3009. GuiSetStyle(TEXTBOX, TEXT_PADDING, 4);
  3010. GuiSetStyle(TEXTBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
  3011. GuiSetStyle(VALUEBOX, TEXT_PADDING, 4);
  3012. GuiSetStyle(VALUEBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
  3013. GuiSetStyle(SPINNER, TEXT_PADDING, 4);
  3014. GuiSetStyle(SPINNER, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
  3015. GuiSetStyle(STATUSBAR, TEXT_PADDING, 8);
  3016. GuiSetStyle(STATUSBAR, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
  3017. // Initialize extended property values
  3018. // NOTE: By default, extended property values are initialized to 0
  3019. GuiSetStyle(DEFAULT, TEXT_SIZE, 10); // DEFAULT, shared by all controls
  3020. GuiSetStyle(DEFAULT, TEXT_SPACING, 1); // DEFAULT, shared by all controls
  3021. GuiSetStyle(DEFAULT, LINE_COLOR, 0x90abb5ff); // DEFAULT specific property
  3022. GuiSetStyle(DEFAULT, BACKGROUND_COLOR, 0xf5f5f5ff); // DEFAULT specific property
  3023. GuiSetStyle(TOGGLE, GROUP_PADDING, 2);
  3024. GuiSetStyle(SLIDER, SLIDER_WIDTH, 16);
  3025. GuiSetStyle(SLIDER, SLIDER_PADDING, 1);
  3026. GuiSetStyle(PROGRESSBAR, PROGRESS_PADDING, 1);
  3027. GuiSetStyle(CHECKBOX, CHECK_PADDING, 1);
  3028. GuiSetStyle(COMBOBOX, COMBO_BUTTON_WIDTH, 32);
  3029. GuiSetStyle(COMBOBOX, COMBO_BUTTON_SPACING, 2);
  3030. GuiSetStyle(DROPDOWNBOX, ARROW_PADDING, 16);
  3031. GuiSetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING, 2);
  3032. GuiSetStyle(TEXTBOX, TEXT_LINES_SPACING, 4);
  3033. GuiSetStyle(TEXTBOX, TEXT_INNER_PADDING, 4);
  3034. GuiSetStyle(SPINNER, SPIN_BUTTON_WIDTH, 24);
  3035. GuiSetStyle(SPINNER, SPIN_BUTTON_SPACING, 2);
  3036. GuiSetStyle(SCROLLBAR, BORDER_WIDTH, 0);
  3037. GuiSetStyle(SCROLLBAR, ARROWS_VISIBLE, 0);
  3038. GuiSetStyle(SCROLLBAR, ARROWS_SIZE, 6);
  3039. GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING, 0);
  3040. GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, 16);
  3041. GuiSetStyle(SCROLLBAR, SCROLL_PADDING, 0);
  3042. GuiSetStyle(SCROLLBAR, SCROLL_SPEED, 12);
  3043. GuiSetStyle(LISTVIEW, LIST_ITEMS_HEIGHT, 24);
  3044. GuiSetStyle(LISTVIEW, LIST_ITEMS_SPACING, 2);
  3045. GuiSetStyle(LISTVIEW, SCROLLBAR_WIDTH, 12);
  3046. GuiSetStyle(LISTVIEW, SCROLLBAR_SIDE, SCROLLBAR_RIGHT_SIDE);
  3047. GuiSetStyle(COLORPICKER, COLOR_SELECTOR_SIZE, 8);
  3048. GuiSetStyle(COLORPICKER, HUEBAR_WIDTH, 16);
  3049. GuiSetStyle(COLORPICKER, HUEBAR_PADDING, 8);
  3050. GuiSetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT, 8);
  3051. GuiSetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW, 2);
  3052. guiFont = GetFontDefault(); // Initialize default font
  3053. }
  3054. // Get text with icon id prepended
  3055. // NOTE: Useful to add icons by name id (enum) instead of
  3056. // a number that can change between ricon versions
  3057. const char *GuiIconText(int iconId, const char *text)
  3058. {
  3059. #if defined(RAYGUI_NO_ICONS)
  3060. return NULL;
  3061. #else
  3062. static char buffer[1024] = { 0 };
  3063. static char iconBuffer[6] = { 0 };
  3064. if (text != NULL)
  3065. {
  3066. memset(buffer, 0, 1024);
  3067. sprintf(buffer, "#%03i#", iconId);
  3068. for (int i = 5; i < 1024; i++)
  3069. {
  3070. buffer[i] = text[i - 5];
  3071. if (text[i - 5] == '\0') break;
  3072. }
  3073. return buffer;
  3074. }
  3075. else
  3076. {
  3077. sprintf(iconBuffer, "#%03i#", iconId & 0x1ff);
  3078. return iconBuffer;
  3079. }
  3080. #endif
  3081. }
  3082. #if !defined(RAYGUI_NO_ICONS)
  3083. // Get full icons data pointer
  3084. unsigned int *GuiGetIcons(void) { return guiIcons; }
  3085. // Load raygui icons file (.rgi)
  3086. // NOTE: In case nameIds are required, they can be requested with loadIconsName,
  3087. // they are returned as a guiIconsName[iconCount][RAYGUI_ICON_MAX_NAME_LENGTH],
  3088. // WARNING: guiIconsName[]][] memory should be manually freed!
  3089. char **GuiLoadIcons(const char *fileName, bool loadIconsName)
  3090. {
  3091. // Style File Structure (.rgi)
  3092. // ------------------------------------------------------
  3093. // Offset | Size | Type | Description
  3094. // ------------------------------------------------------
  3095. // 0 | 4 | char | Signature: "rGI "
  3096. // 4 | 2 | short | Version: 100
  3097. // 6 | 2 | short | reserved
  3098. // 8 | 2 | short | Num icons (N)
  3099. // 10 | 2 | short | Icons size (Options: 16, 32, 64) (S)
  3100. // Icons name id (32 bytes per name id)
  3101. // foreach (icon)
  3102. // {
  3103. // 12+32*i | 32 | char | Icon NameId
  3104. // }
  3105. // Icons data: One bit per pixel, stored as unsigned int array (depends on icon size)
  3106. // S*S pixels/32bit per unsigned int = K unsigned int per icon
  3107. // foreach (icon)
  3108. // {
  3109. // ... | K | unsigned int | Icon Data
  3110. // }
  3111. FILE *rgiFile = fopen(fileName, "rb");
  3112. char **guiIconsName = NULL;
  3113. if (rgiFile != NULL)
  3114. {
  3115. char signature[5] = { 0 };
  3116. short version = 0;
  3117. short reserved = 0;
  3118. short iconCount = 0;
  3119. short iconSize = 0;
  3120. fread(signature, 1, 4, rgiFile);
  3121. fread(&version, 1, sizeof(short), rgiFile);
  3122. fread(&reserved, 1, sizeof(short), rgiFile);
  3123. fread(&iconCount, 1, sizeof(short), rgiFile);
  3124. fread(&iconSize, 1, sizeof(short), rgiFile);
  3125. if ((signature[0] == 'r') &&
  3126. (signature[1] == 'G') &&
  3127. (signature[2] == 'I') &&
  3128. (signature[3] == ' '))
  3129. {
  3130. if (loadIconsName)
  3131. {
  3132. guiIconsName = (char **)RAYGUI_MALLOC(iconCount*sizeof(char **));
  3133. for (int i = 0; i < iconCount; i++)
  3134. {
  3135. guiIconsName[i] = (char *)RAYGUI_MALLOC(RAYGUI_ICON_MAX_NAME_LENGTH);
  3136. fread(guiIconsName[i], RAYGUI_ICON_MAX_NAME_LENGTH, 1, rgiFile);
  3137. }
  3138. }
  3139. else fseek(rgiFile, iconCount*RAYGUI_ICON_MAX_NAME_LENGTH, SEEK_CUR);
  3140. // Read icons data directly over guiIcons data array
  3141. fread(guiIcons, iconCount*(iconSize*iconSize/32), sizeof(unsigned int), rgiFile);
  3142. }
  3143. fclose(rgiFile);
  3144. }
  3145. return guiIconsName;
  3146. }
  3147. // Draw selected icon using rectangles pixel-by-pixel
  3148. void GuiDrawIcon(int iconId, int posX, int posY, int pixelSize, Color color)
  3149. {
  3150. #define BIT_CHECK(a,b) ((a) & (1u<<(b)))
  3151. for (int i = 0, y = 0; i < RAYGUI_ICON_SIZE*RAYGUI_ICON_SIZE/32; i++)
  3152. {
  3153. for (int k = 0; k < 32; k++)
  3154. {
  3155. if (BIT_CHECK(guiIcons[iconId*RAYGUI_ICON_DATA_ELEMENTS + i], k))
  3156. {
  3157. #if !defined(RAYGUI_STANDALONE)
  3158. DrawRectangle(posX + (k%RAYGUI_ICON_SIZE)*pixelSize, posY + y*pixelSize, pixelSize, pixelSize, color);
  3159. #endif
  3160. }
  3161. if ((k == 15) || (k == 31)) y++;
  3162. }
  3163. }
  3164. }
  3165. // Get icon bit data
  3166. // NOTE: Bit data array grouped as unsigned int (RAYGUI_ICON_SIZE*RAYGUI_ICON_SIZE/32 elements)
  3167. unsigned int *GuiGetIconData(int iconId)
  3168. {
  3169. static unsigned int iconData[RAYGUI_ICON_DATA_ELEMENTS] = { 0 };
  3170. memset(iconData, 0, RAYGUI_ICON_DATA_ELEMENTS*sizeof(unsigned int));
  3171. if (iconId < RAYGUI_ICON_MAX_ICONS) memcpy(iconData, &guiIcons[iconId*RAYGUI_ICON_DATA_ELEMENTS], RAYGUI_ICON_DATA_ELEMENTS*sizeof(unsigned int));
  3172. return iconData;
  3173. }
  3174. // Set icon bit data
  3175. // NOTE: Data must be provided as unsigned int array (RAYGUI_ICON_SIZE*RAYGUI_ICON_SIZE/32 elements)
  3176. void GuiSetIconData(int iconId, unsigned int *data)
  3177. {
  3178. if (iconId < RAYGUI_ICON_MAX_ICONS) memcpy(&guiIcons[iconId*RAYGUI_ICON_DATA_ELEMENTS], data, RAYGUI_ICON_DATA_ELEMENTS*sizeof(unsigned int));
  3179. }
  3180. // Set icon scale (1 by default)
  3181. void GuiSetIconScale(unsigned int scale)
  3182. {
  3183. guiIconScale = (scale < 1)? 1 : scale;
  3184. }
  3185. // Set icon pixel value
  3186. void GuiSetIconPixel(int iconId, int x, int y)
  3187. {
  3188. #define BIT_SET(a,b) ((a) |= (1u<<(b)))
  3189. // This logic works for any RAYGUI_ICON_SIZE pixels icons,
  3190. // For example, in case of 16x16 pixels, every 2 lines fit in one unsigned int data element
  3191. BIT_SET(guiIcons[iconId*RAYGUI_ICON_DATA_ELEMENTS + y/(sizeof(unsigned int)*8/RAYGUI_ICON_SIZE)], x + (y%(sizeof(unsigned int)*8/RAYGUI_ICON_SIZE)*RAYGUI_ICON_SIZE));
  3192. }
  3193. // Clear icon pixel value
  3194. void GuiClearIconPixel(int iconId, int x, int y)
  3195. {
  3196. #define BIT_CLEAR(a,b) ((a) &= ~((1u)<<(b)))
  3197. // This logic works for any RAYGUI_ICON_SIZE pixels icons,
  3198. // For example, in case of 16x16 pixels, every 2 lines fit in one unsigned int data element
  3199. BIT_CLEAR(guiIcons[iconId*RAYGUI_ICON_DATA_ELEMENTS + y/(sizeof(unsigned int)*8/RAYGUI_ICON_SIZE)], x + (y%(sizeof(unsigned int)*8/RAYGUI_ICON_SIZE)*RAYGUI_ICON_SIZE));
  3200. }
  3201. // Check icon pixel value
  3202. bool GuiCheckIconPixel(int iconId, int x, int y)
  3203. {
  3204. #define BIT_CHECK(a,b) ((a) & (1u<<(b)))
  3205. return (BIT_CHECK(guiIcons[iconId*8 + y/2], x + (y%2*16)));
  3206. }
  3207. #endif // !RAYGUI_NO_ICONS
  3208. //----------------------------------------------------------------------------------
  3209. // Module specific Functions Definition
  3210. //----------------------------------------------------------------------------------
  3211. // Gui get text width considering icon
  3212. static int GetTextWidth(const char *text)
  3213. {
  3214. #if !defined(ICON_TEXT_PADDING)
  3215. #define ICON_TEXT_PADDING 4
  3216. #endif
  3217. Vector2 size = { 0 };
  3218. int textIconOffset = 0;
  3219. if ((text != NULL) && (text[0] != '\0'))
  3220. {
  3221. if (text[0] == '#')
  3222. {
  3223. for (int i = 1; (text[i] != '\0') && (i < 5); i++)
  3224. {
  3225. if (text[i] == '#')
  3226. {
  3227. textIconOffset = i;
  3228. break;
  3229. }
  3230. }
  3231. }
  3232. // Make sure guiFont is set, GuiGetStyle() initializes it lazynessly
  3233. float fontSize = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
  3234. size = MeasureTextEx(guiFont, text + textIconOffset, fontSize, (float)GuiGetStyle(DEFAULT, TEXT_SPACING));
  3235. if (textIconOffset > 0) size.x += (RAYGUI_ICON_SIZE - ICON_TEXT_PADDING);
  3236. }
  3237. return (int)size.x;
  3238. }
  3239. // Get text bounds considering control bounds
  3240. static Rectangle GetTextBounds(int control, Rectangle bounds)
  3241. {
  3242. Rectangle textBounds = bounds;
  3243. textBounds.x = bounds.x + GuiGetStyle(control, BORDER_WIDTH);
  3244. textBounds.y = bounds.y + GuiGetStyle(control, BORDER_WIDTH);
  3245. textBounds.width = bounds.width - 2*GuiGetStyle(control, BORDER_WIDTH);
  3246. textBounds.height = bounds.height - 2*GuiGetStyle(control, BORDER_WIDTH);
  3247. // Consider TEXT_PADDING properly, depends on control type and TEXT_ALIGNMENT
  3248. switch (control)
  3249. {
  3250. case COMBOBOX: bounds.width -= (GuiGetStyle(control, COMBO_BUTTON_WIDTH) + GuiGetStyle(control, COMBO_BUTTON_SPACING)); break;
  3251. case VALUEBOX: break; // NOTE: ValueBox text value always centered, text padding applies to label
  3252. default:
  3253. {
  3254. if (GuiGetStyle(control, TEXT_ALIGNMENT) == TEXT_ALIGN_RIGHT) textBounds.x -= GuiGetStyle(control, TEXT_PADDING);
  3255. else textBounds.x += GuiGetStyle(control, TEXT_PADDING);
  3256. } break;
  3257. }
  3258. // TODO: Special cases (no label): COMBOBOX, DROPDOWNBOX, LISTVIEW (scrollbar?)
  3259. // More special cases (label on side): CHECKBOX, SLIDER, VALUEBOX, SPINNER
  3260. return textBounds;
  3261. }
  3262. // Get text icon if provided and move text cursor
  3263. // NOTE: We support up to 999 values for iconId
  3264. static const char *GetTextIcon(const char *text, int *iconId)
  3265. {
  3266. #if !defined(RAYGUI_NO_ICONS)
  3267. *iconId = -1;
  3268. if (text[0] == '#') // Maybe we have an icon!
  3269. {
  3270. char iconValue[4] = { 0 }; // Maximum length for icon value: 3 digits + '\0'
  3271. int pos = 1;
  3272. while ((pos < 4) && (text[pos] >= '0') && (text[pos] <= '9'))
  3273. {
  3274. iconValue[pos - 1] = text[pos];
  3275. pos++;
  3276. }
  3277. if (text[pos] == '#')
  3278. {
  3279. *iconId = TextToInteger(iconValue);
  3280. // Move text pointer after icon
  3281. // WARNING: If only icon provided, it could point to EOL character: '\0'
  3282. if (*iconId >= 0) text += (pos + 1);
  3283. }
  3284. }
  3285. #endif
  3286. return text;
  3287. }
  3288. // Gui draw text using default font
  3289. static void GuiDrawText(const char *text, Rectangle bounds, int alignment, Color tint)
  3290. {
  3291. #define TEXT_VALIGN_PIXEL_OFFSET(h) ((int)h%2) // Vertical alignment for pixel perfect
  3292. #if !defined(ICON_TEXT_PADDING)
  3293. #define ICON_TEXT_PADDING 4
  3294. #endif
  3295. if ((text != NULL) && (text[0] != '\0'))
  3296. {
  3297. int iconId = 0;
  3298. text = GetTextIcon(text, &iconId); // Check text for icon and move cursor
  3299. // Get text position depending on alignment and iconId
  3300. //---------------------------------------------------------------------------------
  3301. Vector2 position = { bounds.x, bounds.y };
  3302. // NOTE: We get text size after icon has been processed
  3303. // TODO: REVIEW: We consider text size in case of line breaks! -> MeasureTextEx() depends on raylib!
  3304. Vector2 textSize = MeasureTextEx(GuiGetFont(), text, GuiGetStyle(DEFAULT, TEXT_SIZE), GuiGetStyle(DEFAULT, TEXT_SPACING));
  3305. //int textWidth = GetTextWidth(text);
  3306. //int textHeight = GuiGetStyle(DEFAULT, TEXT_SIZE);
  3307. // If text requires an icon, add size to measure
  3308. if (iconId >= 0)
  3309. {
  3310. textSize.x += RAYGUI_ICON_SIZE*guiIconScale;
  3311. // WARNING: If only icon provided, text could be pointing to EOF character: '\0'
  3312. if ((text != NULL) && (text[0] != '\0')) textSize.x += ICON_TEXT_PADDING;
  3313. }
  3314. // Check guiTextAlign global variables
  3315. switch (alignment)
  3316. {
  3317. case TEXT_ALIGN_LEFT:
  3318. {
  3319. position.x = bounds.x;
  3320. position.y = bounds.y + bounds.height/2 - textSize.y/2 + TEXT_VALIGN_PIXEL_OFFSET(bounds.height);
  3321. } break;
  3322. case TEXT_ALIGN_CENTER:
  3323. {
  3324. position.x = bounds.x + bounds.width/2 - textSize.x/2;
  3325. position.y = bounds.y + bounds.height/2 - textSize.y/2 + TEXT_VALIGN_PIXEL_OFFSET(bounds.height);
  3326. } break;
  3327. case TEXT_ALIGN_RIGHT:
  3328. {
  3329. position.x = bounds.x + bounds.width - textSize.x;
  3330. position.y = bounds.y + bounds.height/2 - textSize.y/2 + TEXT_VALIGN_PIXEL_OFFSET(bounds.height);
  3331. } break;
  3332. default: break;
  3333. }
  3334. // NOTE: Make sure we get pixel-perfect coordinates,
  3335. // In case of decimals we got weird text positioning
  3336. position.x = (float)((int)position.x);
  3337. position.y = (float)((int)position.y);
  3338. //---------------------------------------------------------------------------------
  3339. // Draw text (with icon if available)
  3340. //---------------------------------------------------------------------------------
  3341. #if !defined(RAYGUI_NO_ICONS)
  3342. if (iconId >= 0)
  3343. {
  3344. // NOTE: We consider icon height, probably different than text size
  3345. GuiDrawIcon(iconId, (int)position.x, (int)(bounds.y + bounds.height/2 - RAYGUI_ICON_SIZE*guiIconScale/2 + TEXT_VALIGN_PIXEL_OFFSET(bounds.height)), guiIconScale, tint);
  3346. position.x += (RAYGUI_ICON_SIZE*guiIconScale + ICON_TEXT_PADDING);
  3347. }
  3348. #endif
  3349. DrawTextEx(guiFont, text, position, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), (float)GuiGetStyle(DEFAULT, TEXT_SPACING), tint);
  3350. //---------------------------------------------------------------------------------
  3351. }
  3352. }
  3353. // Gui draw rectangle using default raygui plain style with borders
  3354. static void GuiDrawRectangle(Rectangle rec, int borderWidth, Color borderColor, Color color)
  3355. {
  3356. if (color.a > 0)
  3357. {
  3358. // Draw rectangle filled with color
  3359. DrawRectangle((int)rec.x, (int)rec.y, (int)rec.width, (int)rec.height, color);
  3360. }
  3361. if (borderWidth > 0)
  3362. {
  3363. // Draw rectangle border lines with color
  3364. DrawRectangle((int)rec.x, (int)rec.y, (int)rec.width, borderWidth, borderColor);
  3365. DrawRectangle((int)rec.x, (int)rec.y + borderWidth, borderWidth, (int)rec.height - 2*borderWidth, borderColor);
  3366. DrawRectangle((int)rec.x + (int)rec.width - borderWidth, (int)rec.y + borderWidth, borderWidth, (int)rec.height - 2*borderWidth, borderColor);
  3367. DrawRectangle((int)rec.x, (int)rec.y + (int)rec.height - borderWidth, (int)rec.width, borderWidth, borderColor);
  3368. }
  3369. }
  3370. // Split controls text into multiple strings
  3371. // Also check for multiple columns (required by GuiToggleGroup())
  3372. static const char **GuiTextSplit(const char *text, int *count, int *textRow)
  3373. {
  3374. // NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter)
  3375. // inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated,
  3376. // all used memory is static... it has some limitations:
  3377. // 1. Maximum number of possible split strings is set by RAYGUI_TEXTSPLIT_MAX_ITEMS
  3378. // 2. Maximum size of text to split is RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE
  3379. // NOTE: Those definitions could be externally provided if required
  3380. #if !defined(RAYGUI_TEXTSPLIT_MAX_ITEMS)
  3381. #define RAYGUI_TEXTSPLIT_MAX_ITEMS 128
  3382. #endif
  3383. #if !defined(RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE)
  3384. #define RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE 1024
  3385. #endif
  3386. static const char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL };
  3387. static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 };
  3388. memset(buffer, 0, RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE);
  3389. result[0] = buffer;
  3390. int counter = 1;
  3391. if (textRow != NULL) textRow[0] = 0;
  3392. // Count how many substrings we have on text and point to every one
  3393. for (int i = 0; i < RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE; i++)
  3394. {
  3395. buffer[i] = text[i];
  3396. if (buffer[i] == '\0') break;
  3397. else if ((buffer[i] == ';') || (buffer[i] == '\n'))
  3398. {
  3399. result[counter] = buffer + i + 1;
  3400. if (textRow != NULL)
  3401. {
  3402. if (buffer[i] == '\n') textRow[counter] = textRow[counter - 1] + 1;
  3403. else textRow[counter] = textRow[counter - 1];
  3404. }
  3405. buffer[i] = '\0'; // Set an end of string at this point
  3406. counter++;
  3407. if (counter == RAYGUI_TEXTSPLIT_MAX_ITEMS) break;
  3408. }
  3409. }
  3410. *count = counter;
  3411. return result;
  3412. }
  3413. // Convert color data from RGB to HSV
  3414. // NOTE: Color data should be passed normalized
  3415. static Vector3 ConvertRGBtoHSV(Vector3 rgb)
  3416. {
  3417. Vector3 hsv = { 0 };
  3418. float min = 0.0f;
  3419. float max = 0.0f;
  3420. float delta = 0.0f;
  3421. min = (rgb.x < rgb.y)? rgb.x : rgb.y;
  3422. min = (min < rgb.z)? min : rgb.z;
  3423. max = (rgb.x > rgb.y)? rgb.x : rgb.y;
  3424. max = (max > rgb.z)? max : rgb.z;
  3425. hsv.z = max; // Value
  3426. delta = max - min;
  3427. if (delta < 0.00001f)
  3428. {
  3429. hsv.y = 0.0f;
  3430. hsv.x = 0.0f; // Undefined, maybe NAN?
  3431. return hsv;
  3432. }
  3433. if (max > 0.0f)
  3434. {
  3435. // NOTE: If max is 0, this divide would cause a crash
  3436. hsv.y = (delta/max); // Saturation
  3437. }
  3438. else
  3439. {
  3440. // NOTE: If max is 0, then r = g = b = 0, s = 0, h is undefined
  3441. hsv.y = 0.0f;
  3442. hsv.x = 0.0f; // Undefined, maybe NAN?
  3443. return hsv;
  3444. }
  3445. // NOTE: Comparing float values could not work properly
  3446. if (rgb.x >= max) hsv.x = (rgb.y - rgb.z)/delta; // Between yellow & magenta
  3447. else
  3448. {
  3449. if (rgb.y >= max) hsv.x = 2.0f + (rgb.z - rgb.x)/delta; // Between cyan & yellow
  3450. else hsv.x = 4.0f + (rgb.x - rgb.y)/delta; // Between magenta & cyan
  3451. }
  3452. hsv.x *= 60.0f; // Convert to degrees
  3453. if (hsv.x < 0.0f) hsv.x += 360.0f;
  3454. return hsv;
  3455. }
  3456. // Convert color data from HSV to RGB
  3457. // NOTE: Color data should be passed normalized
  3458. static Vector3 ConvertHSVtoRGB(Vector3 hsv)
  3459. {
  3460. Vector3 rgb = { 0 };
  3461. float hh = 0.0f, p = 0.0f, q = 0.0f, t = 0.0f, ff = 0.0f;
  3462. long i = 0;
  3463. // NOTE: Comparing float values could not work properly
  3464. if (hsv.y <= 0.0f)
  3465. {
  3466. rgb.x = hsv.z;
  3467. rgb.y = hsv.z;
  3468. rgb.z = hsv.z;
  3469. return rgb;
  3470. }
  3471. hh = hsv.x;
  3472. if (hh >= 360.0f) hh = 0.0f;
  3473. hh /= 60.0f;
  3474. i = (long)hh;
  3475. ff = hh - i;
  3476. p = hsv.z*(1.0f - hsv.y);
  3477. q = hsv.z*(1.0f - (hsv.y*ff));
  3478. t = hsv.z*(1.0f - (hsv.y*(1.0f - ff)));
  3479. switch (i)
  3480. {
  3481. case 0:
  3482. {
  3483. rgb.x = hsv.z;
  3484. rgb.y = t;
  3485. rgb.z = p;
  3486. } break;
  3487. case 1:
  3488. {
  3489. rgb.x = q;
  3490. rgb.y = hsv.z;
  3491. rgb.z = p;
  3492. } break;
  3493. case 2:
  3494. {
  3495. rgb.x = p;
  3496. rgb.y = hsv.z;
  3497. rgb.z = t;
  3498. } break;
  3499. case 3:
  3500. {
  3501. rgb.x = p;
  3502. rgb.y = q;
  3503. rgb.z = hsv.z;
  3504. } break;
  3505. case 4:
  3506. {
  3507. rgb.x = t;
  3508. rgb.y = p;
  3509. rgb.z = hsv.z;
  3510. } break;
  3511. case 5:
  3512. default:
  3513. {
  3514. rgb.x = hsv.z;
  3515. rgb.y = p;
  3516. rgb.z = q;
  3517. } break;
  3518. }
  3519. return rgb;
  3520. }
  3521. // Scroll bar control (used by GuiScrollPanel())
  3522. static int GuiScrollBar(Rectangle bounds, int value, int minValue, int maxValue)
  3523. {
  3524. GuiState state = guiState;
  3525. // Is the scrollbar horizontal or vertical?
  3526. bool isVertical = (bounds.width > bounds.height) ? false : true;
  3527. // The size (width or height depending on scrollbar type) of the spinner buttons
  3528. const int spinnerSize = GuiGetStyle(SCROLLBAR, ARROWS_VISIBLE) ? (isVertical ? (int)bounds.width - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH) : (int)bounds.height - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH)) : 0;
  3529. // Arrow buttons [<] [>] [∧] [∨]
  3530. Rectangle arrowUpLeft = { 0 };
  3531. Rectangle arrowDownRight = { 0 };
  3532. // Actual area of the scrollbar excluding the arrow buttons
  3533. Rectangle scrollbar = { 0 };
  3534. // Slider bar that moves --[///]-----
  3535. Rectangle slider = { 0 };
  3536. // Normalize value
  3537. if (value > maxValue) value = maxValue;
  3538. if (value < minValue) value = minValue;
  3539. const int range = maxValue - minValue;
  3540. int sliderSize = GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE);
  3541. // Calculate rectangles for all of the components
  3542. arrowUpLeft = RAYGUI_CLITERAL(Rectangle) { (float)bounds.x + GuiGetStyle(SCROLLBAR, BORDER_WIDTH), (float)bounds.y + GuiGetStyle(SCROLLBAR, BORDER_WIDTH), (float)spinnerSize, (float)spinnerSize };
  3543. if (isVertical)
  3544. {
  3545. arrowDownRight = RAYGUI_CLITERAL(Rectangle) { (float)bounds.x + GuiGetStyle(SCROLLBAR, BORDER_WIDTH), (float)bounds.y + bounds.height - spinnerSize - GuiGetStyle(SCROLLBAR, BORDER_WIDTH), (float)spinnerSize, (float)spinnerSize };
  3546. scrollbar = RAYGUI_CLITERAL(Rectangle) { bounds.x + GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_PADDING), arrowUpLeft.y + arrowUpLeft.height, bounds.width - 2*(GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_PADDING)), bounds.height - arrowUpLeft.height - arrowDownRight.height - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH) };
  3547. sliderSize = (sliderSize >= scrollbar.height) ? ((int)scrollbar.height - 2) : sliderSize; // Make sure the slider won't get outside of the scrollbar
  3548. slider = RAYGUI_CLITERAL(Rectangle) { (float)bounds.x + GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING), (float)scrollbar.y + (int)(((float)(value - minValue)/range)*(scrollbar.height - sliderSize)), (float)bounds.width - 2*(GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING)), (float)sliderSize };
  3549. }
  3550. else
  3551. {
  3552. arrowDownRight = RAYGUI_CLITERAL(Rectangle) { (float)bounds.x + bounds.width - spinnerSize - GuiGetStyle(SCROLLBAR, BORDER_WIDTH), (float)bounds.y + GuiGetStyle(SCROLLBAR, BORDER_WIDTH), (float)spinnerSize, (float)spinnerSize };
  3553. scrollbar = RAYGUI_CLITERAL(Rectangle) { arrowUpLeft.x + arrowUpLeft.width, bounds.y + GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_PADDING), bounds.width - arrowUpLeft.width - arrowDownRight.width - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH), bounds.height - 2*(GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_PADDING)) };
  3554. sliderSize = (sliderSize >= scrollbar.width) ? ((int)scrollbar.width - 2) : sliderSize; // Make sure the slider won't get outside of the scrollbar
  3555. slider = RAYGUI_CLITERAL(Rectangle) { (float)scrollbar.x + (int)(((float)(value - minValue)/range)*(scrollbar.width - sliderSize)), (float)bounds.y + GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING), (float)sliderSize, (float)bounds.height - 2*(GuiGetStyle(SCROLLBAR, BORDER_WIDTH) + GuiGetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING)) };
  3556. }
  3557. // Update control
  3558. //--------------------------------------------------------------------
  3559. if ((state != STATE_DISABLED) && !guiLocked)
  3560. {
  3561. Vector2 mousePoint = GetMousePosition();
  3562. if (CheckCollisionPointRec(mousePoint, bounds))
  3563. {
  3564. state = STATE_FOCUSED;
  3565. // Handle mouse wheel
  3566. int wheel = (int)GetMouseWheelMove();
  3567. if (wheel != 0) value += wheel;
  3568. if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
  3569. {
  3570. if (CheckCollisionPointRec(mousePoint, arrowUpLeft)) value -= range/GuiGetStyle(SCROLLBAR, SCROLL_SPEED);
  3571. else if (CheckCollisionPointRec(mousePoint, arrowDownRight)) value += range/GuiGetStyle(SCROLLBAR, SCROLL_SPEED);
  3572. state = STATE_PRESSED;
  3573. }
  3574. else if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
  3575. {
  3576. if (!isVertical)
  3577. {
  3578. Rectangle scrollArea = { arrowUpLeft.x + arrowUpLeft.width, arrowUpLeft.y, scrollbar.width, bounds.height - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH) };
  3579. if (CheckCollisionPointRec(mousePoint, scrollArea)) value = (int)(((float)(mousePoint.x - scrollArea.x - slider.width/2)*range)/(scrollArea.width - slider.width) + minValue);
  3580. }
  3581. else
  3582. {
  3583. Rectangle scrollArea = { arrowUpLeft.x, arrowUpLeft.y+arrowUpLeft.height, bounds.width - 2*GuiGetStyle(SCROLLBAR, BORDER_WIDTH), scrollbar.height };
  3584. if (CheckCollisionPointRec(mousePoint, scrollArea)) value = (int)(((float)(mousePoint.y - scrollArea.y - slider.height/2)*range)/(scrollArea.height - slider.height) + minValue);
  3585. }
  3586. }
  3587. }
  3588. // Normalize value
  3589. if (value > maxValue) value = maxValue;
  3590. if (value < minValue) value = minValue;
  3591. }
  3592. //--------------------------------------------------------------------
  3593. // Draw control
  3594. //--------------------------------------------------------------------
  3595. GuiDrawRectangle(bounds, GuiGetStyle(SCROLLBAR, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(LISTVIEW, BORDER + state*3)), guiAlpha), Fade(GetColor(GuiGetStyle(DEFAULT, BORDER_COLOR_DISABLED)), guiAlpha)); // Draw the background
  3596. GuiDrawRectangle(scrollbar, 0, BLANK, Fade(GetColor(GuiGetStyle(BUTTON, BASE_COLOR_NORMAL)), guiAlpha)); // Draw the scrollbar active area background
  3597. GuiDrawRectangle(slider, 0, BLANK, Fade(GetColor(GuiGetStyle(SLIDER, BORDER + state*3)), guiAlpha)); // Draw the slider bar
  3598. // Draw arrows (using icon if available)
  3599. if (GuiGetStyle(SCROLLBAR, ARROWS_VISIBLE))
  3600. {
  3601. #if defined(RAYGUI_NO_ICONS)
  3602. GuiDrawText(isVertical ? "^" : "<", RAYGUI_CLITERAL(Rectangle){ arrowUpLeft.x, arrowUpLeft.y, isVertical ? bounds.width : bounds.height, isVertical ? bounds.width : bounds.height },
  3603. TEXT_ALIGN_CENTER, Fade(GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + (state*3))), guiAlpha));
  3604. GuiDrawText(isVertical ? "v" : ">", RAYGUI_CLITERAL(Rectangle){ arrowDownRight.x, arrowDownRight.y, isVertical ? bounds.width : bounds.height, isVertical ? bounds.width : bounds.height },
  3605. TEXT_ALIGN_CENTER, Fade(GetColor(GuiGetStyle(DROPDOWNBOX, TEXT + (state*3))), guiAlpha));
  3606. #else
  3607. GuiDrawText(isVertical ? "#121#" : "#118#", RAYGUI_CLITERAL(Rectangle){ arrowUpLeft.x, arrowUpLeft.y, isVertical ? bounds.width : bounds.height, isVertical ? bounds.width : bounds.height },
  3608. TEXT_ALIGN_CENTER, Fade(GetColor(GuiGetStyle(SCROLLBAR, TEXT + state*3)), guiAlpha)); // ICON_ARROW_UP_FILL / ICON_ARROW_LEFT_FILL
  3609. GuiDrawText(isVertical ? "#120#" : "#119#", RAYGUI_CLITERAL(Rectangle){ arrowDownRight.x, arrowDownRight.y, isVertical ? bounds.width : bounds.height, isVertical ? bounds.width : bounds.height },
  3610. TEXT_ALIGN_CENTER, Fade(GetColor(GuiGetStyle(SCROLLBAR, TEXT + state*3)), guiAlpha)); // ICON_ARROW_DOWN_FILL / ICON_ARROW_RIGHT_FILL
  3611. #endif
  3612. }
  3613. //--------------------------------------------------------------------
  3614. return value;
  3615. }
  3616. #if defined(RAYGUI_STANDALONE)
  3617. // Returns a Color struct from hexadecimal value
  3618. static Color GetColor(int hexValue)
  3619. {
  3620. Color color;
  3621. color.r = (unsigned char)(hexValue >> 24) & 0xFF;
  3622. color.g = (unsigned char)(hexValue >> 16) & 0xFF;
  3623. color.b = (unsigned char)(hexValue >> 8) & 0xFF;
  3624. color.a = (unsigned char)hexValue & 0xFF;
  3625. return color;
  3626. }
  3627. // Returns hexadecimal value for a Color
  3628. static int ColorToInt(Color color)
  3629. {
  3630. return (((int)color.r << 24) | ((int)color.g << 16) | ((int)color.b << 8) | (int)color.a);
  3631. }
  3632. // Check if point is inside rectangle
  3633. static bool CheckCollisionPointRec(Vector2 point, Rectangle rec)
  3634. {
  3635. bool collision = false;
  3636. if ((point.x >= rec.x) && (point.x <= (rec.x + rec.width)) &&
  3637. (point.y >= rec.y) && (point.y <= (rec.y + rec.height))) collision = true;
  3638. return collision;
  3639. }
  3640. // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f
  3641. static Color Fade(Color color, float alpha)
  3642. {
  3643. if (alpha < 0.0f) alpha = 0.0f;
  3644. else if (alpha > 1.0f) alpha = 1.0f;
  3645. Color result = { color.r, color.g, color.b, (unsigned char)(255.0f*alpha) };
  3646. return result;
  3647. }
  3648. // Formatting of text with variables to 'embed'
  3649. static const char *TextFormat(const char *text, ...)
  3650. {
  3651. #if !defined(RAYGUI_TEXTFORMAT_MAX_SIZE)
  3652. #define RAYGUI_TEXTFORMAT_MAX_SIZE 256
  3653. #endif
  3654. static char buffer[RAYGUI_TEXTFORMAT_MAX_SIZE];
  3655. va_list args;
  3656. va_start(args, text);
  3657. vsprintf(buffer, text, args);
  3658. va_end(args);
  3659. return buffer;
  3660. }
  3661. // Draw rectangle with vertical gradient fill color
  3662. // NOTE: This function is only used by GuiColorPicker()
  3663. static void DrawRectangleGradientV(int posX, int posY, int width, int height, Color color1, Color color2)
  3664. {
  3665. Rectangle bounds = { (float)posX, (float)posY, (float)width, (float)height };
  3666. DrawRectangleGradientEx(bounds, color1, color2, color2, color1);
  3667. }
  3668. // Split string into multiple strings
  3669. const char **TextSplit(const char *text, char delimiter, int *count)
  3670. {
  3671. // NOTE: Current implementation returns a copy of the provided string with '\0' (string end delimiter)
  3672. // inserted between strings defined by "delimiter" parameter. No memory is dynamically allocated,
  3673. // all used memory is static... it has some limitations:
  3674. // 1. Maximum number of possible split strings is set by RAYGUI_TEXTSPLIT_MAX_ITEMS
  3675. // 2. Maximum size of text to split is RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE
  3676. #if !defined(RAYGUI_TEXTSPLIT_MAX_ITEMS)
  3677. #define RAYGUI_TEXTSPLIT_MAX_ITEMS 128
  3678. #endif
  3679. #if !defined(RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE)
  3680. #define RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE 1024
  3681. #endif
  3682. static const char *result[RAYGUI_TEXTSPLIT_MAX_ITEMS] = { NULL };
  3683. static char buffer[RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE] = { 0 };
  3684. memset(buffer, 0, RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE);
  3685. result[0] = buffer;
  3686. int counter = 0;
  3687. if (text != NULL)
  3688. {
  3689. counter = 1;
  3690. // Count how many substrings we have on text and point to every one
  3691. for (int i = 0; i < RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE; i++)
  3692. {
  3693. buffer[i] = text[i];
  3694. if (buffer[i] == '\0') break;
  3695. else if (buffer[i] == delimiter)
  3696. {
  3697. buffer[i] = '\0'; // Set an end of string at this point
  3698. result[counter] = buffer + i + 1;
  3699. counter++;
  3700. if (counter == RAYGUI_TEXTSPLIT_MAX_ITEMS) break;
  3701. }
  3702. }
  3703. }
  3704. *count = counter;
  3705. return result;
  3706. }
  3707. // Get integer value from text
  3708. // NOTE: This function replaces atoi() [stdlib.h]
  3709. static int TextToInteger(const char *text)
  3710. {
  3711. int value = 0;
  3712. int sign = 1;
  3713. if ((text[0] == '+') || (text[0] == '-'))
  3714. {
  3715. if (text[0] == '-') sign = -1;
  3716. text++;
  3717. }
  3718. for (int i = 0; ((text[i] >= '0') && (text[i] <= '9')); ++i) value = value*10 + (int)(text[i] - '0');
  3719. return value*sign;
  3720. }
  3721. // Encode codepoint into UTF-8 text (char array size returned as parameter)
  3722. static const char *CodepointToUTF8(int codepoint, int *byteSize)
  3723. {
  3724. static char utf8[6] = { 0 };
  3725. int size = 0;
  3726. if (codepoint <= 0x7f)
  3727. {
  3728. utf8[0] = (char)codepoint;
  3729. size = 1;
  3730. }
  3731. else if (codepoint <= 0x7ff)
  3732. {
  3733. utf8[0] = (char)(((codepoint >> 6) & 0x1f) | 0xc0);
  3734. utf8[1] = (char)((codepoint & 0x3f) | 0x80);
  3735. size = 2;
  3736. }
  3737. else if (codepoint <= 0xffff)
  3738. {
  3739. utf8[0] = (char)(((codepoint >> 12) & 0x0f) | 0xe0);
  3740. utf8[1] = (char)(((codepoint >> 6) & 0x3f) | 0x80);
  3741. utf8[2] = (char)((codepoint & 0x3f) | 0x80);
  3742. size = 3;
  3743. }
  3744. else if (codepoint <= 0x10ffff)
  3745. {
  3746. utf8[0] = (char)(((codepoint >> 18) & 0x07) | 0xf0);
  3747. utf8[1] = (char)(((codepoint >> 12) & 0x3f) | 0x80);
  3748. utf8[2] = (char)(((codepoint >> 6) & 0x3f) | 0x80);
  3749. utf8[3] = (char)((codepoint & 0x3f) | 0x80);
  3750. size = 4;
  3751. }
  3752. *byteSize = size;
  3753. return utf8;
  3754. }
  3755. // Get next codepoint in a UTF-8 encoded text, scanning until '\0' is found
  3756. // When a invalid UTF-8 byte is encountered we exit as soon as possible and a '?'(0x3f) codepoint is returned
  3757. // Total number of bytes processed are returned as a parameter
  3758. // NOTE: the standard says U+FFFD should be returned in case of errors
  3759. // but that character is not supported by the default font in raylib
  3760. static int GetCodepoint(const char *text, int *bytesProcessed)
  3761. {
  3762. /*
  3763. UTF-8 specs from https://www.ietf.org/rfc/rfc3629.txt
  3764. Char. number range | UTF-8 octet sequence
  3765. (hexadecimal) | (binary)
  3766. --------------------+---------------------------------------------
  3767. 0000 0000-0000 007F | 0xxxxxxx
  3768. 0000 0080-0000 07FF | 110xxxxx 10xxxxxx
  3769. 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
  3770. 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
  3771. */
  3772. // NOTE: on decode errors we return as soon as possible
  3773. int code = 0x3f; // Codepoint (defaults to '?')
  3774. int octet = (unsigned char)(text[0]); // The first UTF8 octet
  3775. *bytesProcessed = 1;
  3776. if (octet <= 0x7f)
  3777. {
  3778. // Only one octet (ASCII range x00-7F)
  3779. code = text[0];
  3780. }
  3781. else if ((octet & 0xe0) == 0xc0)
  3782. {
  3783. // Two octets
  3784. // [0]xC2-DF [1]UTF8-tail(x80-BF)
  3785. unsigned char octet1 = text[1];
  3786. if ((octet1 == '\0') || ((octet1 >> 6) != 2)) { *bytesProcessed = 2; return code; } // Unexpected sequence
  3787. if ((octet >= 0xc2) && (octet <= 0xdf))
  3788. {
  3789. code = ((octet & 0x1f) << 6) | (octet1 & 0x3f);
  3790. *bytesProcessed = 2;
  3791. }
  3792. }
  3793. else if ((octet & 0xf0) == 0xe0)
  3794. {
  3795. // Three octets
  3796. unsigned char octet1 = text[1];
  3797. unsigned char octet2 = '\0';
  3798. if ((octet1 == '\0') || ((octet1 >> 6) != 2)) { *bytesProcessed = 2; return code; } // Unexpected sequence
  3799. octet2 = text[2];
  3800. if ((octet2 == '\0') || ((octet2 >> 6) != 2)) { *bytesProcessed = 3; return code; } // Unexpected sequence
  3801. // [0]xE0 [1]xA0-BF [2]UTF8-tail(x80-BF)
  3802. // [0]xE1-EC [1]UTF8-tail [2]UTF8-tail(x80-BF)
  3803. // [0]xED [1]x80-9F [2]UTF8-tail(x80-BF)
  3804. // [0]xEE-EF [1]UTF8-tail [2]UTF8-tail(x80-BF)
  3805. if (((octet == 0xe0) && !((octet1 >= 0xa0) && (octet1 <= 0xbf))) ||
  3806. ((octet == 0xed) && !((octet1 >= 0x80) && (octet1 <= 0x9f)))) { *bytesProcessed = 2; return code; }
  3807. if ((octet >= 0xe0) && (0 <= 0xef))
  3808. {
  3809. code = ((octet & 0xf) << 12) | ((octet1 & 0x3f) << 6) | (octet2 & 0x3f);
  3810. *bytesProcessed = 3;
  3811. }
  3812. }
  3813. else if ((octet & 0xf8) == 0xf0)
  3814. {
  3815. // Four octets
  3816. if (octet > 0xf4) return code;
  3817. unsigned char octet1 = text[1];
  3818. unsigned char octet2 = '\0';
  3819. unsigned char octet3 = '\0';
  3820. if ((octet1 == '\0') || ((octet1 >> 6) != 2)) { *bytesProcessed = 2; return code; } // Unexpected sequence
  3821. octet2 = text[2];
  3822. if ((octet2 == '\0') || ((octet2 >> 6) != 2)) { *bytesProcessed = 3; return code; } // Unexpected sequence
  3823. octet3 = text[3];
  3824. if ((octet3 == '\0') || ((octet3 >> 6) != 2)) { *bytesProcessed = 4; return code; } // Unexpected sequence
  3825. // [0]xF0 [1]x90-BF [2]UTF8-tail [3]UTF8-tail
  3826. // [0]xF1-F3 [1]UTF8-tail [2]UTF8-tail [3]UTF8-tail
  3827. // [0]xF4 [1]x80-8F [2]UTF8-tail [3]UTF8-tail
  3828. if (((octet == 0xf0) && !((octet1 >= 0x90) && (octet1 <= 0xbf))) ||
  3829. ((octet == 0xf4) && !((octet1 >= 0x80) && (octet1 <= 0x8f)))) { *bytesProcessed = 2; return code; } // Unexpected sequence
  3830. if (octet >= 0xf0)
  3831. {
  3832. code = ((octet & 0x7) << 18) | ((octet1 & 0x3f) << 12) | ((octet2 & 0x3f) << 6) | (octet3 & 0x3f);
  3833. *bytesProcessed = 4;
  3834. }
  3835. }
  3836. if (code > 0x10ffff) code = 0x3f; // Codepoints after U+10ffff are invalid
  3837. return code;
  3838. }
  3839. #endif // RAYGUI_STANDALONE
  3840. #endif // RAYGUI_IMPLEMENTATION