12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157 |
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="utf-8">
- <meta name="generator" content="gendoc 1.0.0: https://gitlab.com/bztsrc/gendoc">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>State-Mode GUI</title>
- <style rel="logic">*{box-sizing:border-box;font-family:inherit;}body {background:rgba(0,0,0,0.05);font-weight:400;font-size:16px;}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:26px 0;padding:0;border-top:1px solid;}br:after,br:before{display:table;content:""}br{clear:both;}h1,h2,h3,h4,h5,h6{clear:both;margin:0px 0px 20px 0px;padding-top:4px;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;}p{margin:0 0 24px}a{cursor:pointer;}h1{font-size:175%}h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}pre,samp,code,var,kbd{font-family:Monaco,Consolas,Liberation Mono,Courier,monospace;font-variant-ligatures:none;}pre,code{display:block;overflow:auto;white-space:pre;font-size:14px;line-height:16px!important;}pre{padding:12px;margin:0px;}code{padding:0 0 12px 0;margin:12px 12px 0px 2px;background:url(data:type/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAgCAYAAADT5RIaAAAAFklEQVQI12NgYGDgZWJgYGCgDkFtAAAWnAAsyj4TxgAAAABJRU5ErkJggg==) 0 0 repeat;}.lineno{display:block;padding:0px 4px 0px 4px;margin:12px 0px 0px 0px;opacity:.4;text-align:right;float:left;white-space:pre;font-size:12px;line-height:16px!important;}pre .hl_b,samp .hl_b,code .hl_b{display:block;}blockquote{margin:0px;padding:12px;}blockquote>span:first-child::before{content:url(data:type/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAgCAYAAABU1PscAAABRElEQVRYw+3WTytEURjH8c/4l1JTpKxsyEbYWFkpG+UVKOWFeAts7eytbJSysLLVxIKNFAslwhSlUQabUdM0xm0e967Ot+7inPN8z+13z73nXBKJRCIRoJSxbggrmMMInlHBIWoF+KEAQ9jAaJuxe2zhJUe/Iz0ZahZ/uTmMYT1nPxxg/I/xWQzn6IcD1IIha//wkEIBKhlq+nP0wwHOsYuvDjWvOfod6c1Yd9O4ZjDQZvwAbzn6oRVofpKbqLf0P+GxAD8cAO7w0NJ3WqAfDlBCuan9gaMC/XCA+cbJ+sMRqgX6oQCTWGtqX2O/QL8tfRlqyljGUlPgW2y3+SDz8Lv6mRvEQmPbm25ZqQvs/LHtRf3wCkxgtaWvij2cZJg36ocD/Pw91nGJY5zhM+O8UT/8Ck01TswrvHcxb9RPJBKJRDF8AyNbWk4WFTIzAAAAAElFTkSuQmCC);float:left;vertical-align:top;}.ui1,.ui2,.ui3,.ui4,.ui5,.ui6{display:inline-block;height:24px!important;line-height:24px!important;padding:0px 4px;margin:-2px 0px -2px;}kbd{display:inline-block;font-weight:700;border:1px solid #888;height:24px!important;padding:0px 4px;margin:-2px 0px -2px;border-radius:4px;background-image:linear-gradient(#ddd 0%,#eee 10%,#bbb 10%,#ccc 30%,#fff 85%,#eee 85%,#888 100%);}.mouseleft,.mouseright,.mousewheel{display:inline-block;min-width:16px;height:24px!important;padding:0px;margin:-2px 0px 0px 0px;vertical-align:middle;}.mouseleft::before{content:url(data:type/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAYCAMAAADEfo0+AAAAe1BMVEUAAACoqKj9/f2zs7O1tbWRkZGlpaWsrKybm5u2traNjY2Wlpanp6empqaYmJiPj4+3t7f5+fmjo6P19fXu7u6ZmZnx8fHi4uLm5ube3t7q6uqwsLC0tLS7u7u4uLi/v7/W1tbDw8PLy8vPz8/T09Pa2trHx8eIiIhERkShhqFGAAAAAXRSTlMAQObYZgAAAI5JREFUGNNV0EcCwjAMRFEB6R2DKSGQUBLp/idEjsG23m7+cgAMIsJWwR8Z235pumDTnkUbv+lg7CIfTqvSbTquxsGFfjWXLlwsdOFs+XC1EHAWOEwCh4/A4S1weAkcFoHDU0CI8zGQx1Cpe0BVAO0j0PIfiR4cnZjLdHP7abQ9VRVZnaZ1VvjfO42o7edfH3EoHZS6XE4AAAAASUVORK5CYII=);}.mouseright::before{content:url(data:type/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAYCAMAAADEfo0+AAAAe1BMVEUAAACoqKj9/f2zs7O1tbWRkZGlpaWsrKybm5u2traNjY2Wlpanp6empqaYmJiPj4+3t7f5+fmjo6P19fXu7u6ZmZnx8fHi4uLm5ube3t7q6uqwsLC0tLS7u7u4uLi/v7/W1tbDw8PLy8vPz8/T09Pa2trHx8eIiIhERkShhqFGAAAAAXRSTlMAQObYZgAAAI9JREFUGNNV0NkWgjAMRdGozFOxWgdEcYLk/7/Q0EpL9tNd5/ECzLRCIoJF20zdlsinTbRn5Eu0O8zIl/Jk+dAPR4uWUo6d5QNenBDOTghXJ4RRQMCnwOErcPgIHN4Ch0ng8BIQ4nxYyWOo9H1FVwDqsaL4j8T0nknmy0xz+2uMO1UXWZ2mdVbo8LtBNK2dP/2+KB2shyfVAAAAAElFTkSuQmCC);}.mousewheel::before{content:url(data:type/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAYCAMAAADEfo0+AAAAe1BMVEUAAACzs7OoqKisrKyRkZGlpaX9/f22trabm5uNjY2mpqanp6ePj4+1tbWYmJi3t7eWlpajo6OZmZmwsLD5+fnu7u7x8fHi4uLW1tbm5ube3t7T09Pq6ur19fW4uLi7u7u0tLTa2trPz8+/v7/Dw8PLy8vHx8eIiIhERkS4354xAAAAAXRSTlMAQObYZgAAAKdJREFUGNNV0NkagiAUhdHjPAECzWWlWdL7P2Fno/nJumHzXx4iMMI5YeivVVOX592k2vkfy/1CxvjL6L6KJAd9ZF+GVxP144Eh4B170kPHEPAOmtwFEPxw5E6A4AeHKyD4wWEABD84nAHBDw43QPCDwyvA4RPgMAU4vAOO0mLcKFJqzHPDNETisSH4HpntVzbDyazaLZSdj2qqsk6Suqw2d7fO2fnmP7kAJW9a/HbiAAAAAElFTkSuQmCC);}footer{width:100%;padding:0 3.236em;}footer p{opacity:0.6;}footer small{opacity:0.5;}footer a{text-decoration:none;color:inherit;}footer a:hover{text-decoration:underline;}dl{margin:0 0 24px 0;padding:0px;}dt{font-weight:700;margin-bottom:12px;}dd{margin:0 0 12px 24px;}.table table{margin:0px;border-collapse:collapse;border-spacing:0;empty-cells:show;border:1px solid;width:100%;}th{font-weight:700;padding:8px 16px;overflow:visible;vertical-align:middle;white-space:nowrap;border:1px solid;}th.wide{width:100%;}td{padding:8px 16px;overflow:visible;vertical-align:middle;font-size:90%;border:1px solid;}td.right{text-align:right;}table.grid{margin:0px;padding:0px;border:none!important;background:none!important;border-spacing:0;border:0px!important;empty-cells:show;width:100%;}table.grid tr, table.grid td{margin:0px;padding:0px;overflow:hidden;vertical-align:top;background:none!important;border:0px!important;font-size:90%;}div.frame{position:absolute;width:100%;min-height:100%;margin:0px;padding:0px;max-width:1100px;top:0px;left:0px;}#_m{margin-left:300px;min-height:100%;}div.title{display:block;width:300px;padding-top:.809em;padding-bottom:.809em;margin-bottom:.809em;text-align:center;font-weight:700;}div.title>a{padding:4px 6px;margin-bottom:.809em;font-size:150%;}div.title>a:hover{background:transparent;}div.title>a>img{max-width:280px;border:0px;padding:0px;margin:0px;}div.title input{display:none;width:270px;border-radius:50px;padding:6px 12px;font-size:80%;box-shadow:inset 0 1px 3px #ddd;transition:border .3s linear;}div.title input:required:invalid{background:#fcfcfc url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAASFBMVEUAAAC6urq7u7y7vLy8vL3Dw8TLzM67urq8vL29vr69vr/AwMK5ubm5ubm4uLi5t7fAwMC/vr/FxMXBwsPExcW+u7vDw8S4uLiryZHFAAAAF3RSTlMA9vGttk4lfbWnpJQG0MpzYEIglFRCGzMa+EsAAAB0SURBVBjTbY5bCsMwDAQl2U6cR5s0fcz9b1oLpWBC52dhENqVRsmG5SIn60wwryEm0LQkbUacAveh5XGDh4uKfsQZlOqpJAkS5gHPUyzgYdeLjB6/H7lvGbzlssP2WDoRGGzxrVRD82sHRukZ/xhv7tns/QXrhgcaFdOKBwAAAABJRU5ErkJggg==) no-repeat 10px 50%;}div.title input:focus{background:#fcfcfc!important;}div.version{margin-top:.4045em;margin-bottom:.809em;font-size:90%;}nav.side {display:block;position:fixed;top:0;bottom:0;left:0;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;font-weight:400;z-index:999;}nav.mobile {display:none;font-weight:bold;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1;}nav a{color:inherit;text-decoration:none;display:block;}nav.side>div{position:relative;overflow-x:hidden;overflow-y:scroll;width:320px;height:100%;padding-bottom:64px;}div.nav p{height:32px;line-height:32px;padding:0 1.618em;margin:12px 0px 0px 0px;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap;-webkit-font-smoothing:antialiased}div.nav li>.current,div.nav li>ul{display:none;}div.nav li>a,div.nav li>label{display:block;}div.nav a,div.nav ul>li>label,div.nav ul>li>.current{width:300px;line-height:18px;padding:0.4045em 1.618em;}div.nav a,div.nav ul>li>label{cursor:pointer;}div.nav .current{font-weight:700;border-top:1px solid;border-bottom:1px solid #c9c9c9;}div.nav ul>li>ul>li>a{border-right:solid 1px #c9c9c9;font-size:90%;}div.nav ul>li>ul>li.h2>a{padding:0.4045em 2.427em;}div.nav ul>li>ul>li.h3>a{padding:.4045em 1.618em .4045em 4.045em;}div.nav ul>li>ul>li.h4>a{padding:.4045em 1.618em .4045em 5.663em;}div.nav ul>li>ul>li.h5>a{padding:.4045em 1.618em .4045em 7.281em;}div.nav ul>li>ul>li.h6>a{padding:.4045em 1.618em .4045em 8.899em;}div.nav ul,div.nav li,.breadcrumbs{margin:0px!important;padding:0px;list-style:none;}ul.breadcrumbs,.breadcrumbs li{display:inline-block;}.menu{display:inline-block;position:absolute;top:12px;right:20px;cursor:pointer;width:1.5em;height:1.5em;vertical-align:middle;padding:16px 24px 16px 24px;border:solid 1px rgba(255, 255, 255, 0.5);border-radius:5px;background:no-repeat center center url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E");}.home{display:inline-block;max-width:16px;max-height:16px;line-height:16px;margin:0 5px 0 0;cursor:pointer;}.home::before{content:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAS1BMVEUAAAD8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/PyxWsjVAAAAGHRSTlMAx6oLLRnYiXFEvPbey518NQbsj11QKhQ+J0ktAAAAbElEQVQY053ISQ7DMAwEwRYpavHurPz/SwMoMpD46L4MpvBTB0zTP+R9z55Ebh0yQL5DaDA+0WVR3h3Gikp9iPKF9MIkQhSDwUlGHCLQxhLGJkpLZcNYS/tdyorP/DQ7HgBqKRUgHBDcw2X4AFsJCSXB/5UVAAAAAElFTkSuQmCC);}h1>a,h2>a,h3>a,h4>a,h5>a,h6>a{display:none;max-width:16px;max-height:24px;margin:-8px 0 0 5px;vertical-align:middle;}h1:hover>a,h2:hover>a,h3:hover>a,h4:hover>a,h5:hover>a,h6:hover>a{display:inline-block;text-decoration:none!important;}h1>a::before,h2>a::before,h3>a::before,h4>a::before,h5>a::before,h6>a::before{content:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAiBAMAAACkb0T0AAAAMFBMVEUAAAD8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/PzS+N+gAAAAD3RSTlMABab5cVY73o4k2cJTPb1Q83MyAAAAh0lEQVQY02P4DwWkM7YxsNiDGJ8EGBgmgxiKDDkCLAwgAQn7hQxARiGj8v8/IIYDi2a9GZChHiAnMLmBjeGTaIBUAMcFaYaNvA2sC1kD9RkSOCwZF7IW/WdgSP4+yYHlP5Bx/r+RgDiIIfW5kVEfyHBgPMYgBLLdkoEBKABkfHZgyIa7h04MAOVty/RC/PhoAAAAAElFTkSuQmCC);}h1>a:hover::after,h2>a:hover::after,h3>a:hover::after,h4>a:hover::after,h5>a:hover::after,h6>a:hover::after{content:"Permalink to this headline";display:block;padding:12px;position:absolute;margin:-8px 8px;font-weight:400;font-size:14px;background:rgba(0,0,0,.8);color:#fff;border-radius:4px;}input[type=radio]{display:none;}input[type=radio]:checked ~ ul{display:block;}.fig{margin-top:-12px;padding-bottom:12px;display:block;text-align:center;font-style:italic;}div.page{width:100%;padding:1.618em 3.236em;margin:auto;line-height:24px;}div.page ol{margin:0 0 24px 12px;padding-left:0px;}div.page ul{margin:0 0 24px 24px;list-style:disc outside;padding-left:0px;}div.page ol{list-style-type:none;counter-reset:list;}div.page ol li:before{counter-increment:list;content:counters(list,".") ". ";}div.pre{overflow-x:auto;margin:1px 0px 24px;}div.table{overflow-x:auto;margin:0px 0px 24px;}div.info,div.hint,div.warn{padding:12px;line-height:24px;margin-bottom:24px;}div.info>p,div.hint>p,div.warn>p{margin:0px;}div.info>p:first-child,div.hint>p:first-child,div.warn>p:first-child{display:block;font-weight:700;padding:2px 8px 2px;margin:-12px -12px 8px -12px;vertical-align:middle;}div.info>p:first-child>span,div.hint>p:first-child>span,div.warn>p:first-child>span{display:block;max-height:20px;margin:0px;vertical-align:middle;}div.info>p:first-child>span::before,div.hint>p:first-child>span::before,div.warn>p:first-child>span::before{content:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAApUlEQVQ4y82TwQnDMAxFpVJyLPiSbbJETr13Fo+RZZxLRghkgnSEEni9ONS0sg1tDv3wwfjbX7Iki/wVAAd4IPBCiHuudrkHVvJYgb50eaOO7cMkpv0eeQGukYuRiUsNvBFpSvTJ0P2un0Sk+6Le3WEG58yBFrjt61r7Qqbij0gLIX3CaPgOqtqoaiMig6GPtTbOwCVyLraxMEj3yPIgHTLKv3ymJySzt16bW/sWAAAAAElFTkSuQmCC);}p>div:last-child,dd>*:last-child,td>*:last-child,li>ol,li>ul{margin-bottom:0px!important;}img{border:0px;}img.imgt{display:inline-block;max-height:22px!important;padding:0px;margin:-4px 0px 0px 0px;vertical-align:middle;}img.imgl{float:left;margin:0px 12px 12px 0px;}img.imgr{float:right;margin:0px 0px 12px 12px;}div.imgc{text-align:center;padding:0px;margin:0 0 12px 0;clear:both;}img.imgc{max-width:100%;}img.imgw{width:100%;margin-bottom:12px;clear:both;}.btn{border-radius:2px;line-height:normal;white-space:nowrap;color:inherit;text-align:center;cursor:pointer;font-size:100%;padding:4px 12px 8px;border:1px solid rgba(0,0,0,.1);text-decoration:none;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);vertical-align:middle;*zoom:1;user-select:none;transition:all .1s linear}.prev{float:left;}.prev::before{content:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAANlBMVEUAAABAQEBAQEBAQEBAQEBAQEBAQEBBQUFAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAWW5SEAAAAEnRSTlMA/fC9r2kXAjMN34F3ZlUu6B40Y5wGAAAAVElEQVQY08XPSw6AIAwEUIbS8lFE739Zq6luGtbM8iXTTMOCZGECiCX/MhIQTyCNz+SRrUc1MWKVvR5KYCN6pUFDRtqq4Sql9IYJ+aI/70f4qdOHblOhAuUcC5KnAAAAAElFTkSuQmCC);}.next{float:right;}.next::after{content:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASBAMAAACk4JNkAAAAJFBMVEUAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEC4lvDfAAAAC3RSTlMAx711ZjlFPh3zLASjkrYAAABDSURBVAjXY6AUsGhvcgAzOKR3797YAGIx7t5mvVsAxPLevZ159xYQS3v3zgLrTSDW7tTQBcy7ESyELEIHwhSEyQjbAAH1HsMY8tCHAAAAAElFTkSuQmCC);}@media screen and (max-width:991.98px){nav.mobile{display:block;}nav.side{display:none;}#menuchk:checked ~ nav.side{display:block;}#_m{margin-left:0px;}}#_window:checked ~ nav div ul li[rel=window]>.toc,#_localization:checked ~ nav div ul li[rel=localization]>.toc,#_fonts:checked ~ nav div ul li[rel=fonts]>.toc,#_look_and_feel:checked ~ nav div ul li[rel=look_and_feel]>.toc,#_event_handling:checked ~ nav div ul li[rel=event_handling]>.toc,#_no_event:checked ~ nav div ul li[rel=no_event]>.toc,#_mouse:checked ~ nav div ul li[rel=mouse]>.toc,#_gamepad:checked ~ nav div ul li[rel=gamepad]>.toc,#_keyboard:checked ~ nav div ul li[rel=keyboard]>.toc,#_dropped_file:checked ~ nav div ul li[rel=dropped_file]>.toc,#_window_resize:checked ~ nav div ul li[rel=window_resize]>.toc,#_clipboard:checked ~ nav div ul li[rel=clipboard]>.toc,#_layout:checked ~ nav div ul li[rel=layout]>.toc,#_containers:checked ~ nav div ul li[rel=containers]>.toc,#_labels:checked ~ nav div ul li[rel=labels]>.toc,#_inputs:checked ~ nav div ul li[rel=inputs]>.toc,#_buttons:checked ~ nav div ul li[rel=buttons]>.toc,#_lines:checked ~ nav div ul li[rel=lines]>.toc,#_custom:checked ~ nav div ul li[rel=custom]>.toc,#_example:checked ~ nav div ul li[rel=example]>.toc,#_fine_tuning:checked ~ nav div ul li[rel=fine_tuning]>.toc,#_smgui_license:checked ~ nav div ul li[rel=smgui_license]>.toc,div.page{display:none;}#_window:checked ~ nav div ul li[rel=window]>ul,#_window:checked ~ nav div ul li[rel=window]>.current,#_window:checked ~ div div[rel=window],#_localization:checked ~ nav div ul li[rel=localization]>ul,#_localization:checked ~ nav div ul li[rel=localization]>.current,#_localization:checked ~ div div[rel=localization],#_fonts:checked ~ nav div ul li[rel=fonts]>ul,#_fonts:checked ~ nav div ul li[rel=fonts]>.current,#_fonts:checked ~ div div[rel=fonts],#_look_and_feel:checked ~ nav div ul li[rel=look_and_feel]>ul,#_look_and_feel:checked ~ nav div ul li[rel=look_and_feel]>.current,#_look_and_feel:checked ~ div div[rel=look_and_feel],#_event_handling:checked ~ nav div ul li[rel=event_handling]>ul,#_event_handling:checked ~ nav div ul li[rel=event_handling]>.current,#_event_handling:checked ~ div div[rel=event_handling],#_no_event:checked ~ nav div ul li[rel=no_event]>ul,#_no_event:checked ~ nav div ul li[rel=no_event]>.current,#_no_event:checked ~ div div[rel=no_event],#_mouse:checked ~ nav div ul li[rel=mouse]>ul,#_mouse:checked ~ nav div ul li[rel=mouse]>.current,#_mouse:checked ~ div div[rel=mouse],#_gamepad:checked ~ nav div ul li[rel=gamepad]>ul,#_gamepad:checked ~ nav div ul li[rel=gamepad]>.current,#_gamepad:checked ~ div div[rel=gamepad],#_keyboard:checked ~ nav div ul li[rel=keyboard]>ul,#_keyboard:checked ~ nav div ul li[rel=keyboard]>.current,#_keyboard:checked ~ div div[rel=keyboard],#_dropped_file:checked ~ nav div ul li[rel=dropped_file]>ul,#_dropped_file:checked ~ nav div ul li[rel=dropped_file]>.current,#_dropped_file:checked ~ div div[rel=dropped_file],#_window_resize:checked ~ nav div ul li[rel=window_resize]>ul,#_window_resize:checked ~ nav div ul li[rel=window_resize]>.current,#_window_resize:checked ~ div div[rel=window_resize],#_clipboard:checked ~ nav div ul li[rel=clipboard]>ul,#_clipboard:checked ~ nav div ul li[rel=clipboard]>.current,#_clipboard:checked ~ div div[rel=clipboard],#_layout:checked ~ nav div ul li[rel=layout]>ul,#_layout:checked ~ nav div ul li[rel=layout]>.current,#_layout:checked ~ div div[rel=layout],#_containers:checked ~ nav div ul li[rel=containers]>ul,#_containers:checked ~ nav div ul li[rel=containers]>.current,#_containers:checked ~ div div[rel=containers],#_labels:checked ~ nav div ul li[rel=labels]>ul,#_labels:checked ~ nav div ul li[rel=labels]>.current,#_labels:checked ~ div div[rel=labels],#_inputs:checked ~ nav div ul li[rel=inputs]>ul,#_inputs:checked ~ nav div ul li[rel=inputs]>.current,#_inputs:checked ~ div div[rel=inputs],#_buttons:checked ~ nav div ul li[rel=buttons]>ul,#_buttons:checked ~ nav div ul li[rel=buttons]>.current,#_buttons:checked ~ div div[rel=buttons],#_lines:checked ~ nav div ul li[rel=lines]>ul,#_lines:checked ~ nav div ul li[rel=lines]>.current,#_lines:checked ~ div div[rel=lines],#_custom:checked ~ nav div ul li[rel=custom]>ul,#_custom:checked ~ nav div ul li[rel=custom]>.current,#_custom:checked ~ div div[rel=custom],#_example:checked ~ nav div ul li[rel=example]>ul,#_example:checked ~ nav div ul li[rel=example]>.current,#_example:checked ~ div div[rel=example],#_fine_tuning:checked ~ nav div ul li[rel=fine_tuning]>ul,#_fine_tuning:checked ~ nav div ul li[rel=fine_tuning]>.current,#_fine_tuning:checked ~ div div[rel=fine_tuning],#_smgui_license:checked ~ nav div ul li[rel=smgui_license]>ul,#_smgui_license:checked ~ nav div ul li[rel=smgui_license]>.current,#_smgui_license:checked ~ div div[rel=smgui_license],#_:checked ~ div div[rel=_]{display:block;}</style>
- <style rel="theme">hr,table,th,td{border-color:#e1e4e5;}th{background:#d6d6d6;}tr:nth-child(odd){background:#f3f6f6;}a{text-decoration:none;color:#2980B9;}samp{background:rgba(0,0,0,.1);color:#408040;}.content{background:#fcfcfc;color:#404040;font-family:Lato,Helvetica,Neue,Arial,Deja Vu,sans-serif;}.title,.home,h1>a,h2>a,h3>a,h4>a,h5>a,h6>a{background:#2980B9;color:#fcfcfc;}.version{color:rgba(255,255,255,0.3);}.search{border:1px solid #2472a4;background:#fcfcfc;}.nav{background:#343131;color:#d9d9d9;}.nav p{color:#55a5d9;}.nav label:hover,.nav a:hover{background:#4e4a4a;}.nav .current{background:#fcfcfc;color:#404040;}.nav li>ul>li{background:#e3e3e3;}.nav li>ul>li>a{color:#404040;}.nav li>ul>li>a:hover{background:#d6d6d6;}.pre {border:1px solid #e1e4e5;background:#f8f8f8;}.info{background:#e7f2fa;}.info>p:first-child{background:#6ab0de;color:#fff;}.hint{background:#dbfaf4;}.hint>p:first-child{background:#1abc9c;color:#fff;}.warn{background:#ffedcc;}.warn>p:first-child{background:#f0b37e;color:#fff;}.btn{background:#f3f6f6;}.btn:hover{background:#e5ebeb;}.hl_h{background-color:#ccffcc;}.hl_c{color:#808080;font-style:italic;}.hl_p{color:#1f7199;}.hl_o{color:#404040;}.hl_n{color:#0164eb;}.hl_s{color:#986801;}.hl_t{color:#60A050;}.hl_k{color:#a626a4;}.hl_f{color:#2a9292;}.hl_v{color:#e95649;}.ui1{border:1px outset #a0a0a0;background:#a0a0a0;color:#222;}</style>
- </head>
- <body>
- <div class="frame content">
- <input type="radio" name="page" id="_" checked><input type="radio" name="page" id="_window"><input type="radio" name="page" id="_localization"><input type="radio" name="page" id="_fonts"><input type="radio" name="page" id="_look_and_feel"><input type="radio" name="page" id="_event_handling"><input type="radio" name="page" id="_no_event"><input type="radio" name="page" id="_mouse"><input type="radio" name="page" id="_gamepad"><input type="radio" name="page" id="_keyboard"><input type="radio" name="page" id="_dropped_file"><input type="radio" name="page" id="_window_resize"><input type="radio" name="page" id="_clipboard"><input type="radio" name="page" id="_layout"><input type="radio" name="page" id="_containers"><input type="radio" name="page" id="_labels"><input type="radio" name="page" id="_inputs"><input type="radio" name="page" id="_buttons"><input type="radio" name="page" id="_lines"><input type="radio" name="page" id="_custom"><input type="radio" name="page" id="_example"><input type="radio" name="page" id="_fine_tuning"><input type="radio" name="page" id="_smgui_license">
- <input type="checkbox" id="menuchk" style="display:none;"><nav class="side nav"><div>
- <div class="title"><a href="https://gitlab.com/bztsrc/smgui">State-Mode GUI</a><div class="version">0.0.1</div><input id="_q" class="search" type="text" required="required" onkeyup="s(this.value);"></div> <div id="_s" class="nav"></div>
- <div id="_t" class="nav">
- <p>Basics</p>
- <ul>
- <li rel="window"><label class="toc" for="_window">Window</label><div class="current">Window</div><ul>
- <li class="h2"><a href="#initializing" onclick="m()">Initializing</a></li>
- <li class="h2"><a href="#releasing" onclick="m()">Releasing</a></li>
- <li class="h2"><a href="#fullscreen" onclick="m()">Fullscreen</a></li>
- <li class="h2"><a href="#backend_window" onclick="m()">Backend Window</a></li>
- <li class="h2"><a href="#general_structure" onclick="m()">General Structure</a></li>
- </ul></li>
- <li rel="localization"><label class="toc" for="_localization">Localization</label><div class="current">Localization</div><ul>
- <li class="h2"><a href="#changing_the_language" onclick="m()">Changing the Language</a></li>
- </ul></li>
- <li rel="fonts"><label class="toc" for="_fonts">Fonts</label><div class="current">Fonts</div><ul>
- <li class="h2"><a href="#setting_up_a_custom_implementation" onclick="m()">Setting up a Custom Implementation</a></li>
- <li class="h2"><a href="#loading_a_font" onclick="m()">Loading a Font</a></li>
- </ul></li>
- <li rel="look_and_feel"><label class="toc" for="_look_and_feel">Look and Feel</label><div class="current">Look and Feel</div><ul>
- <li class="h2"><a href="#mouse_pointer" onclick="m()">Mouse Pointer</a></li>
- <li class="h2"><a href="#color_theme" onclick="m()">Color Theme</a></li>
- <li class="h2"><a href="#skin" onclick="m()">Skin</a></li>
- </ul></li>
- </ul>
- <p>Events</p>
- <ul>
- <li rel="event_handling"><label class="toc" for="_event_handling">Event Handling</label><div class="current">Event Handling</div><ul>
- </ul></li>
- <li rel="no_event"><label class="toc" for="_no_event">No Event</label><div class="current">No Event</div><ul>
- </ul></li>
- <li rel="mouse"><label class="toc" for="_mouse">Mouse</label><div class="current">Mouse</div><ul>
- </ul></li>
- <li rel="gamepad"><label class="toc" for="_gamepad">Gamepad</label><div class="current">Gamepad</div><ul>
- </ul></li>
- <li rel="keyboard"><label class="toc" for="_keyboard">Keyboard</label><div class="current">Keyboard</div><ul>
- </ul></li>
- <li rel="dropped_file"><label class="toc" for="_dropped_file">Dropped File</label><div class="current">Dropped File</div><ul>
- </ul></li>
- <li rel="window_resize"><label class="toc" for="_window_resize">Window Resize</label><div class="current">Window Resize</div><ul>
- </ul></li>
- <li rel="clipboard"><label class="toc" for="_clipboard">Clipboard</label><div class="current">Clipboard</div><ul>
- <li class="h2"><a href="#paste" onclick="m()">Paste</a></li>
- <li class="h2"><a href="#copy" onclick="m()">Copy</a></li>
- </ul></li>
- </ul>
- <p>Forms</p>
- <ul>
- <li rel="layout"><label class="toc" for="_layout">Layout</label><div class="current">Layout</div><ul>
- <li class="h2"><a href="#field_flags" onclick="m()">Field Flags</a></li>
- <li class="h2"><a href="#positioning" onclick="m()">Positioning</a></li>
- <li class="h2"><a href="#multithreading" onclick="m()">Multithreading</a></li>
- <li class="h2"><a href="#redrawing" onclick="m()">Redrawing</a></li>
- </ul></li>
- <li rel="containers"><label class="toc" for="_containers">Containers</label><div class="current">Containers</div><ul>
- <li class="h2"><a href="#popup" onclick="m()">Popup</a></li>
- <li class="h2"><a href="#menu" onclick="m()">Menu</a></li>
- <li class="h2"><a href="#division" onclick="m()">Division</a></li>
- <li class="h2"><a href="#table" onclick="m()">Table</a></li>
- </ul></li>
- <li rel="labels"><label class="toc" for="_labels">Labels</label><div class="current">Labels</div><ul>
- <li class="h2"><a href="#label" onclick="m()">Label</a></li>
- <li class="h2"><a href="#status" onclick="m()">Status</a></li>
- <li class="h2"><a href="#decimal" onclick="m()">Decimal</a></li>
- <li class="h2"><a href="#hexadecimal" onclick="m()">Hexadecimal</a></li>
- <li class="h2"><a href="#progressbar" onclick="m()">Progressbar</a></li>
- <li class="h2"><a href="#floating_point" onclick="m()">Floating Point</a></li>
- <li class="h2"><a href="#image" onclick="m()">Image</a></li>
- </ul></li>
- <li rel="inputs"><label class="toc" for="_inputs">Inputs</label><div class="current">Inputs</div><ul>
- <li class="h2"><a href="#text" onclick="m()">Text</a></li>
- <li class="h2"><a href="#selectbox" onclick="m()">Selectbox</a></li>
- <li class="h2"><a href="#optionlist" onclick="m()">Optionlist</a></li>
- <li class="h2"><a href="#float" onclick="m()">Float</a></li>
- <li class="h2"><a href="#integer" onclick="m()">Integer</a></li>
- <li class="h2"><a href="#slider" onclick="m()">Slider</a></li>
- <li class="h2"><a href="#vertical_scrollbar" onclick="m()">Vertical Scrollbar</a></li>
- <li class="h2"><a href="#horizontal_scrollbar" onclick="m()">Horizontal Scrollbar</a></li>
- <li class="h2"><a href="#color" onclick="m()">Color</a></li>
- <li class="h2"><a href="#file" onclick="m()">File</a></li>
- <li class="h2"><a href="#path" onclick="m()">Path</a></li>
- </ul></li>
- <li rel="buttons"><label class="toc" for="_buttons">Buttons</label><div class="current">Buttons</div><ul>
- <li class="h2"><a href="#toggle" onclick="m()">Toggle</a></li>
- <li class="h2"><a href="#checkbox" onclick="m()">Checkbox</a></li>
- <li class="h2"><a href="#radiobutton" onclick="m()">Radiobutton</a></li>
- <li class="h2"><a href="#button" onclick="m()">Button</a></li>
- <li class="h2"><a href="#button_toggle" onclick="m()">Button Toggle</a></li>
- <li class="h2"><a href="#button_icon" onclick="m()">Button Icon</a></li>
- </ul></li>
- <li rel="lines"><label class="toc" for="_lines">Lines</label><div class="current">Lines</div><ul>
- <li class="h2"><a href="#polyline" onclick="m()">Polyline</a></li>
- <li class="h2"><a href="#horizontal_connect" onclick="m()">Horizontal Connect</a></li>
- <li class="h2"><a href="#vertical_connect" onclick="m()">Vertical Connect</a></li>
- <li class="h2"><a href="#bezier_curve" onclick="m()">Bezier Curve</a></li>
- </ul></li>
- <li rel="custom"><label class="toc" for="_custom">Custom</label><div class="current">Custom</div><ul>
- <li class="h2"><a href="#bounding" onclick="m()">Bounding</a></li>
- <li class="h2"><a href="#view" onclick="m()">View</a></li>
- <li class="h2"><a href="#controller" onclick="m()">Controller</a></li>
- <li class="h2"><a href="#destructor" onclick="m()">Destructor</a></li>
- </ul></li>
- </ul>
- <p>Appendix</p>
- <ul>
- <li rel="example"><label class="toc" for="_example">Example</label><div class="current">Example</div><ul>
- </ul></li>
- <li rel="fine_tuning"><label class="toc" for="_fine_tuning">Fine Tuning</label><div class="current">Fine Tuning</div><ul>
- <li class="h2"><a href="#base" onclick="m()">Base</a></li>
- <li class="h3"><a href="#ui_implementation" onclick="m()">UI_IMPLEMENTATION</a></li>
- <li class="h3"><a href="#ui_noaa" onclick="m()">UI_NOAA</a></li>
- <li class="h3"><a href="#ui_maxevents" onclick="m()">UI_MAXEVENTS</a></li>
- <li class="h3"><a href="#ui_maxpopups" onclick="m()">UI_MAXPOPUPS</a></li>
- <li class="h3"><a href="#ui_backend_initialized" onclick="m()">UI_BACKEND_INITIALIZED</a></li>
- <li class="h3"><a href="#ui_backend_noflush" onclick="m()">UI_BACKEND_NOFLUSH</a></li>
- <li class="h2"><a href="#glfw3" onclick="m()">GLFW3</a></li>
- <li class="h3"><a href="#ui_glfw_noshader" onclick="m()">UI_GLFW_NOSHADER</a></li>
- <li class="h3"><a href="#ui_glfw_gles2" onclick="m()">UI_GLFW_GLES2</a></li>
- <li class="h3"><a href="#ui_glfw_customhooks" onclick="m()">UI_GLFW_CUSTOMHOOKS</a></li>
- </ul></li>
- <li rel="smgui_license"><label class="toc" for="_smgui_license">SMGUI License</label><div class="current">SMGUI License</div><ul>
- </ul>
- </div>
- </div></nav>
- <div id="_m">
- <nav class="mobile title">State-Mode GUI<label for="menuchk" class="menu"></label></nav>
- <div class="page" rel="_">
- <h1>State-Mode GUI API</h1>
- <p>Welcome to the manual for the <a href="https://bztsrc.gitlab.io/smgui" target="new">SMGUI</a>, the state-mode graphical user interface toolkit.</p>
- <p>The main concept of a <b>state-mode UI</b> is, that you already have your variables, so you reference
- those from a layout, which has no callbacks neither requires immediate-mode calls, it is just uses
- those already existing variables for rendering the GUI states.</p>
- <div class="hint"><p><span>Hint</span></p><p> This manual can be used off-line. From the <span class="mouseright"></span> right-click pop-up menu, choose "Save As".</p></div>
- <h2>Including</h2>
- <p>This library is self-contained in one single header file and can be used either in header-only mode or in
- implementation mode. The header-only mode is used by default when included and allows including this header
- in other headers and does not contain the actual implementation. The implementation mode requires defining
- the preprocessor macro <samp>UI_IMPLEMENTATION</samp> in exactly one .c/.cpp file right before including this file.</p>
- <p>The base library is entirely platform and backend agnostic. You can select which backend and font driver
- module to use just by including before <b>ui.h</b>.</p>
- <div class="pre"><pre class="lineno">1<br>2<br>3<br>4<br></pre><code><span class="hl_p">#include "ui_glfw.h"</span>
- <span class="hl_p">#include "ui_psf2.h"</span>
- <span class="hl_p">#define UI_IMPLEMENTATION</span>
- <span class="hl_p">#include "ui.h"</span></code></div>
- <p>The reference implementation for backend uses <a href="https://www.glfw.org" target="new">GLFW3</a>, <a href="https://libsdl.org" target="new">SDL2/3</a> and
- <a href="https://www.x.org" target="new">X11</a>; for fonts PC-Screen-Font (same that Linux Console uses), and
- <a href="https://gitlab.com/bztsrc/scalable-font2" target="new">Scalable Screen Font</a> (much more efficient than TTF or OTF, and any font,
- be it bitmap, vector or pixel font, can be converted into SSFN).</p>
- <p>By default, if no other modules included beforehand, then <b>ui.h</b> includes the <i>GLFW3 backend</i> and <i>PSF2 fonts</i> and
- also embeds a minimal ASCII-only font (2080 bytes compiled).</p>
- <h2>Return Codes</h2>
- <p>Unless stated otherwise, all functions return a negative error code.</p>
- <div class="table"><table><tr><th>Define </th><th>Description </th></tr>
- <tr><td><samp>UI_OK</samp> </td><td>Successful, no error </td></tr>
- <tr><td><samp>UI_ERR_BADINP</samp> </td><td>Bad input argument </td></tr>
- <tr><td><samp>UI_ERR_BACKEND</samp> </td><td>Error intializing the backend </td></tr>
- <tr><td><samp>UI_ERR_NOMEM</samp> </td><td>Memory allocation error </td></tr></table></div><br style="clear:both;"><label class="btn next" accesskey="n" for="_window" title="Window">Next</label></div>
- <div class="page" rel="window"><div><ul class="breadcrumbs"><li><label class="home" for="_" title="Home"></label> »</li><li> Window</li></ul><hr></div>
- <h1 id="window">Window<a href="#window"></a></h1>
- <h2 id="initializing">Initializing<a href="#initializing"></a></h2>
- <div class="pre"><pre class="lineno">1<br></pre><code><span class="hl_t">int</span> <span class="hl_f">ui_init</span>(<span class="hl_v">ui_t</span> <span class="hl_o">*</span><span class="hl_v">ctx</span>, <span class="hl_t">int</span> <span class="hl_v">txtc</span>, <span class="hl_t">char</span> <span class="hl_o">**</span><span class="hl_v">txtv</span>, <span class="hl_t">int</span> <span class="hl_v">w</span>, <span class="hl_t">int</span> <span class="hl_v">h</span>, <span class="hl_v">ui_image_t</span> <span class="hl_o">*</span><span class="hl_v">icon</span>);</code></div>
- <p>Initializes the UI context and opens a window. The very first string in the <samp>txtv[]</samp> string array must be the window's title,
- the rest is up to you.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>ctx</samp> </td><td>Pointer to UI context </td></tr>
- <tr><td><samp>txtc</samp> </td><td>Number of strings </td></tr>
- <tr><td><samp>txtv</samp> </td><td>Strings array for <a href="#localization" onclick="c('localization')">localization</a> </td></tr>
- <tr><td><samp>w</samp> </td><td>Window width </td></tr>
- <tr><td><samp>h</samp> </td><td>Window height </td></tr>
- <tr><td><samp>icon</samp> </td><td>Window icon <a href="#image" onclick="c('image')">image</a> (or NULL) </td></tr></table></div>
- <p>Returns 0 on success, an error code otherwise.</p>
- <h2 id="releasing">Releasing<a href="#releasing"></a></h2>
- <div class="pre"><pre class="lineno">1<br></pre><code><span class="hl_t">int</span> <span class="hl_f">ui_free</span>(<span class="hl_v">ui_t</span> <span class="hl_o">*</span><span class="hl_v">ctx</span>);</code></div>
- <p>Closes the window and frees internal buffers.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>ctx</samp> </td><td>Pointer to UI context </td></tr></table></div>
- <p>Returns 0 on success, an error code otherwise.</p>
- <h2 id="fullscreen">Fullscreen<a href="#fullscreen"></a></h2>
- <div class="pre"><pre class="lineno">1<br></pre><code><span class="hl_t">int</span> <span class="hl_f">ui_fullscreen</span>(<span class="hl_v">ui_t</span> <span class="hl_o">*</span><span class="hl_v">ctx</span>);</code></div>
- <p>Toggle context between fullscreen and windowed mode (after initialization it's windowed).</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>ctx</samp> </td><td>Pointer to UI context </td></tr></table></div>
- <p>Returns 0 on success, an error code otherwise.</p>
- <h2 id="backend_window">Backend Window<a href="#backend_window"></a></h2>
- <div class="pre"><pre class="lineno">1<br></pre><code><span class="hl_t">void</span> <span class="hl_o">*</span><span class="hl_f">ui_getwindow</span>(<span class="hl_v">ui_t</span> <span class="hl_o">*</span><span class="hl_v">ctx</span>);</code></div>
- <p>In case there's a need, you can query the underlying backend's window handle with this function.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>ctx</samp> </td><td>Pointer to UI context </td></tr></table></div>
- <p>Returns an implementation specific handle.</p>
- <h2 id="general_structure">General Structure<a href="#general_structure"></a></h2>
- <p>General structure of your program should look like this:</p>
- <div class="pre"><pre class="lineno">1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br>31<br>32<br></pre><code><span class="hl_c">/* UI context, one per window */</span>
- <span class="hl_v">ui_t</span> <span class="hl_v">ctx</span>;
- <span class="hl_c">/* provide a localization strings array */</span>
- <span class="hl_t">enum</span> { <span class="hl_v">WINDOW_TITLE</span>, <span class="hl_v">HELLO_WORLD</span> };
- <span class="hl_t">char</span> <span class="hl_o">*</span><span class="hl_v">english</span>[] <span class="hl_o">=</span> { <span class="hl_s">"Window title"</span>, <span class="hl_s">"Hello World!"</span> };
- <span class="hl_c">/* open a window and initialize the context */</span>
- <span class="hl_f">ui_init</span>(<span class="hl_o">&</span><span class="hl_v">ctx</span>, <span class="hl_n">2</span>, <span class="hl_v">english</span>, <span class="hl_n">640</span>, <span class="hl_n">480</span>, <span class="hl_t">NULL</span>);
- <span class="hl_c">/* your main game loop */</span>
- <span class="hl_k">do</span> {
- <span class="hl_c">/* do your thing, draw what you want to draw */</span>
- <span class="hl_f">glClearColor</span>(<span class="hl_n">0.0</span>, <span class="hl_n">0.0</span>, <span class="hl_n">0.0</span>, <span class="hl_n">1.0</span>);
- <span class="hl_f">glClear</span>(<span class="hl_v">GL_COLOR_BUFFER_BIT</span> <span class="hl_o">|</span> <span class="hl_v">GL_DEPTH_BUFFER_BIT</span>);
- <span class="hl_c">/* ... */</span>
- <span class="hl_c">/* get events and add an UI layer with your desired form on top */</span>
- <span class="hl_c">/* if this returns NULL, you should exit */</span>
- <span class="hl_k">if</span>(<span class="hl_o">!</span>(<span class="hl_v">evt</span> <span class="hl_o">=</span> <span class="hl_f">ui_event</span>(<span class="hl_o">&</span><span class="hl_v">ctx</span>, <span class="hl_v">form</span>))) <span class="hl_k">break</span>;
- <span class="hl_c">/* parse the events */</span>
- <span class="hl_k">switch</span>(<span class="hl_v">evt</span><span class="hl_o">-></span><span class="hl_v">type</span>) {
- <span class="hl_k">case</span> <span class="hl_v">UI_EVT_KEY</span>: <span class="hl_c">/* key press */</span> <span class="hl_k">break</span>;
- <span class="hl_k">case</span> <span class="hl_v">UI_EVT_MOUSE</span>: <span class="hl_c">/* mouse button event */</span> <span class="hl_k">break</span>;
- <span class="hl_k">case</span> <span class="hl_v">UI_EVT_GAMEPAD</span>: <span class="hl_c">/* gamepad event */</span> <span class="hl_k">break</span>;
- <span class="hl_c">/* ... */</span>
- }
- } <span class="hl_k">while</span>(<span class="hl_n">1</span>);
- <span class="hl_c">/* close the window */</span>
- <span class="hl_f">ui_free</span>(<span class="hl_o">&</span><span class="hl_v">ctx</span>);</code></div><br style="clear:both;"><label class="btn prev" accesskey="p" for="_">Previous</label><label class="btn next" accesskey="n" for="_localization" title="Localization">Next</label></div>
- <div class="page" rel="localization"><div><ul class="breadcrumbs"><li><label class="home" for="_" title="Home"></label> »</li><li> Localization</li></ul><hr></div>
- <h1 id="localization">Localization<a href="#localization"></a></h1>
- <p>SMGUI supports localization, and for that you must gather all the strings in an array. I also suggest to create an <samp>enum</samp>
- for the indeces.</p>
- <div class="pre"><pre>
- char *dictionary[];
- </pre></div>
- <p>You must pass this array when you open the <a href="#window" onclick="c('window')">window</a>. The very first string in the array must be the window's title, the
- rest is up to you.</p>
- <h2 id="changing_the_language">Changing the Language<a href="#changing_the_language"></a></h2>
- <div class="pre"><pre class="lineno">1<br></pre><code><span class="hl_t">int</span> <span class="hl_f">ui_settxt</span>(<span class="hl_v">ui_t</span> <span class="hl_o">*</span><span class="hl_v">ctx</span>, <span class="hl_t">char</span> <span class="hl_o">**</span><span class="hl_v">txtv</span>);</code></div>
- <p>You can change the language any time you want. The new <samp>txtv[]</samp> array must have exactly the same number of elements as
- the one you have used for initialization.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>ctx</samp> </td><td>Pointer to UI context </td></tr>
- <tr><td><samp>txtv</samp> </td><td>Strings array </td></tr></table></div>
- <p>Returns 0 on success, an error code otherwise.</p><br style="clear:both;"><label class="btn prev" accesskey="p" for="_window" title="Window">Previous</label><label class="btn next" accesskey="n" for="_fonts" title="Fonts">Next</label></div>
- <div class="page" rel="fonts"><div><ul class="breadcrumbs"><li><label class="home" for="_" title="Home"></label> »</li><li> Fonts</li></ul><hr></div>
- <h1 id="fonts">Fonts<a href="#fonts"></a></h1>
- <p>SMGUI supports any kind of fonts, and ships two reference implementations, <b>ui_psf2.h</b> (default, simple bitmap fonts) and
- <b>ui_ssfn.h</b> (vector fonts, scaled bitmap and pixelmap fonts), but you can also add your own.</p>
- <h2 id="setting_up_a_custom_implementation">Setting up a Custom Implementation<a href="#setting_up_a_custom_implementation"></a></h2>
- <div class="pre"><pre class="lineno">1<br></pre><code><span class="hl_t">int</span> <span class="hl_f">ui_fonthook</span>(<span class="hl_v">ui_t</span> <span class="hl_o">*</span><span class="hl_v">ctx</span>, <span class="hl_v">ui_font_bbox</span> <span class="hl_v">bbox</span>, <span class="hl_v">ui_font_draw</span> <span class="hl_v">draw</span>);</code></div>
- <p>For a custom font format you'll have to pass two hooks to the context.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>ctx</samp> </td><td>Pointer to UI context </td></tr>
- <tr><td><samp>bbox</samp> </td><td>Bounding box function </td></tr>
- <tr><td><samp>draw</samp> </td><td>Font renderer function </td></tr></table></div>
- <p>Returns 0 on success, an error code otherwise.</p>
- <p>The hooks are:</p>
- <div class="pre"><pre class="lineno">1<br>2<br></pre><code><span class="hl_t">typedef</span> <span class="hl_t">int</span> (<span class="hl_o">*</span><span class="hl_f">ui_font_bbox</span>)(<span class="hl_t">void</span> <span class="hl_o">*</span><span class="hl_v">fnt</span>, <span class="hl_t">char</span> <span class="hl_o">*</span><span class="hl_v">str</span>, <span class="hl_t">char</span> <span class="hl_o">*</span><span class="hl_v">end</span>,
- <span class="hl_t">int</span> <span class="hl_o">*</span><span class="hl_v">w</span>, <span class="hl_t">int</span> <span class="hl_o">*</span><span class="hl_v">h</span>, <span class="hl_t">int</span> <span class="hl_o">*</span><span class="hl_v">l</span>, <span class="hl_t">int</span> <span class="hl_o">*</span><span class="hl_v">t</span>);</code></div>
- <p>Measures the string and returns its width in <samp>w</samp>, height in <samp>h</samp> in pixels. If there's a left bearing, <samp>l</samp> is set. Baseline
- is set from the top in <samp>t</samp> (both <samp>l</samp> and <samp>t</samp> can be NULL if not interested). The string is a zero terminated UTF-8 string
- in <samp>str</samp>, but if <samp>end</samp> is not NULL, then it must stop at <samp>end</samp>.</p>
- <div class="pre"><pre class="lineno">1<br>2<br>3<br></pre><code><span class="hl_t">typedef</span> <span class="hl_t">int</span> (<span class="hl_o">*</span><span class="hl_f">ui_font_draw</span>)(<span class="hl_t">void</span> <span class="hl_o">*</span><span class="hl_v">fnt</span>, <span class="hl_t">char</span> <span class="hl_o">*</span><span class="hl_v">str</span>, <span class="hl_t">char</span> <span class="hl_o">*</span><span class="hl_v">end</span>,
- <span class="hl_t">uint8_t</span> <span class="hl_o">*</span><span class="hl_v">dst</span>, <span class="hl_t">uint32_t</span> <span class="hl_v">color</span>, <span class="hl_t">int</span> <span class="hl_v">x</span>, <span class="hl_t">int</span> <span class="hl_v">y</span>, <span class="hl_t">int</span> <span class="hl_v">l</span>, <span class="hl_t">int</span> <span class="hl_v">t</span>, <span class="hl_t">int</span> <span class="hl_v">p</span>,
- <span class="hl_t">int</span> <span class="hl_v">cx0</span>, <span class="hl_t">int</span> <span class="hl_v">cy0</span>, <span class="hl_t">int</span> <span class="hl_v">cx1</span>, <span class="hl_t">int</span> <span class="hl_v">cy1</span>);</code></div>
- <p>Renders the string at <samp>x</samp>, <samp>y</samp> (with left bearing <samp>l</samp> and baseline from top <samp>t</samp>) into a pixel buffer <samp>dst</samp> which has <samp>p</samp>
- bytes in a line (pitch). It is very important that this function must not modify pixels outside of the <samp>cx0</samp>, <samp>cy0</samp> to
- <samp>cx1</samp>, <samp>cy1</samp> crop region. The implementation specific font is passed in <samp>fnt</samp>, the font's color in <samp>color</samp>, the zero
- terminated UTF-8 string itself in <samp>str</samp>, but if <samp>end</samp> is not NULL, then it must stop at <samp>end</samp>.</p>
- <h2 id="loading_a_font">Loading a Font<a href="#loading_a_font"></a></h2>
- <div class="warn"><p><span>Warning</span></p><p> This function does not initialize the font, it just stores the pointer and passes it to the hooks. Font
- initialization and releasing is platform specific and up to the user (PSF2 needs none).</p></div>
- <div class="pre"><pre class="lineno">1<br></pre><code><span class="hl_t">int</span> <span class="hl_f">ui_font</span>(<span class="hl_v">ui_t</span> <span class="hl_o">*</span><span class="hl_v">ctx</span>, <span class="hl_t">void</span> <span class="hl_o">*</span><span class="hl_v">fnt</span>);</code></div>
- <p>Sets the current font to be used.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>ctx</samp> </td><td>Pointer to UI context </td></tr>
- <tr><td><samp>fnt</samp> </td><td>Font to be used </td></tr></table></div>
- <p>Returns 0 on success, an error code otherwise.</p><br style="clear:both;"><label class="btn prev" accesskey="p" for="_localization" title="Localization">Previous</label><label class="btn next" accesskey="n" for="_look_and_feel" title="Look and Feel">Next</label></div>
- <div class="page" rel="look_and_feel"><div><ul class="breadcrumbs"><li><label class="home" for="_" title="Home"></label> »</li><li> Look and Feel</li></ul><hr></div>
- <h1 id="look_and_feel">Look and Feel<a href="#look_and_feel"></a></h1>
- <h2 id="mouse_pointer">Mouse Pointer<a href="#mouse_pointer"></a></h2>
- <div class="pre"><pre class="lineno">1<br></pre><code><span class="hl_t">int</span> <span class="hl_f">ui_swcursor</span>(<span class="hl_v">ui_t</span> <span class="hl_o">*</span><span class="hl_v">ctx</span>, <span class="hl_v">ui_image_t</span> <span class="hl_o">*</span><span class="hl_v">cursor</span>);</code></div>
- <p>Disables hardware mouse cursor and replaces it with an image cursor from software.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>ctx</samp> </td><td>Pointer to UI context </td></tr>
- <tr><td><samp>cursor</samp> </td><td>A cursor <a href="#image" onclick="c('image')">image</a> </td></tr></table></div>
- <p>Returns 0 on success, an error code otherwise.</p>
- <div class="pre"><pre class="lineno">1<br></pre><code><span class="hl_t">int</span> <span class="hl_f">ui_hwcursor</span>(<span class="hl_v">ui_t</span> <span class="hl_o">*</span><span class="hl_v">ctx</span>);</code></div>
- <p>Disables software cursor and enables hardware mouse cursor.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>ctx</samp> </td><td>Pointer to UI context </td></tr></table></div>
- <p>Returns 0 on success, an error code otherwise.</p>
- <h2 id="color_theme">Color Theme<a href="#color_theme"></a></h2>
- <p>SMGUI supports color themes, which are basically palettes. Each palette entry corresponds to a specific UI element's color.
- These are in order:</p>
- <ul><li>foreground color</li>
- <li>popup and menu title color</li>
- <li>popup and menu background color</li>
- <li>popup and menu shadow color</li>
- <li><a href="#toggle" onclick="c('toggle')">toggle</a> active foreground color</li>
- <li>toggle active background color</li>
- <li><a href="#menu" onclick="c('menu')">menu</a> highlight foreground color</li>
- <li>menu highlight background color</li>
- <li>disabled foreground color</li>
- <li>disabled background color</li>
- <li>scrollbar background color</li>
- <li>input box foreground color</li>
- <li>input box light border color</li>
- <li>input box dark border color</li>
- <li>input box background color</li>
- <li>input box selected foreground color</li>
- <li>input box selected border color</li>
- <li>input box selected cursor color</li>
- <li>button foreground color</li>
- <li>button shadow color</li>
- <li>button normal outter border color</li>
- <li>button selected foreground color</li>
- <li>button selected shadow color</li>
- <li>button selected outter border color</li>
- <li>button light inner border color</li>
- <li>button dark inner border color</li>
- <li>button light background color</li>
- <li>button dark background color</li>
- <li>progressbar light color</li>
- <li>progressbar background color</li>
- <li>progressbar dark color</li></ul>
- <div class="pre"><pre class="lineno">1<br></pre><code><span class="hl_t">int</span> <span class="hl_f">ui_theme</span>(<span class="hl_v">ui_t</span> <span class="hl_o">*</span><span class="hl_v">ctx</span>, <span class="hl_t">uint32_t</span> <span class="hl_o">*</span><span class="hl_v">theme</span>);</code></div>
- <p>Sets a custom theme. The <samp>theme[]</samp> array has as many elements as UI colors, see the list above.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>ctx</samp> </td><td>Pointer to UI context </td></tr>
- <tr><td><samp>theme</samp> </td><td>Pointer to a palette </td></tr></table></div>
- <p>Returns 0 on success, an error code otherwise.</p>
- <h2 id="skin">Skin<a href="#skin"></a></h2>
- <p>SMGUI supports skins, which are images, each corresponding to a specific part of the UI. These are in order:</p>
- <ul><li>the mouse cursor (hotspot at the centre)</li>
- <li>popup and menu top left corner</li>
- <li>popup and menu top middle</li>
- <li>popup and menu top right corner</li>
- <li>popup and menu left</li>
- <li>popup and menu background</li>
- <li>popup and menu right</li>
- <li>popup and menu bottom left corner</li>
- <li>popup and menu bottom middle</li>
- <li>popup and menu bottom right corner</li>
- <li>popup and menu title background</li>
- <li>popup and menu close button</li>
- <li>popup and menu alternative top left corner</li>
- <li>popup and menu alternative top middle</li>
- <li>popup and menu alternative top right corner</li>
- <li>popup and menu alternative left</li>
- <li>popup and menu alternative background</li>
- <li>popup and menu alternative right</li>
- <li>popup and menu alternative bottom left corner</li>
- <li>popup and menu alternative bottom middle</li>
- <li>popup and menu alternative bottom right corner</li>
- <li>popup and menu alternative title background</li>
- <li>popup and menu alternative close button</li>
- <li>menu alternative left side</li>
- <li>menu alternative background</li>
- <li>menu alternative right side</li>
- <li>menu highlight background</li>
- <li>input box background</li>
- <li>progressbar button background</li>
- <li>slider left side</li>
- <li>slider background</li>
- <li>slider right side</li>
- <li>slider button</li>
- <li>vertical scrollbar top</li>
- <li>vertical scrollbar background</li>
- <li>vertical scrollbar bottom</li>
- <li>vertical scrollbar button top</li>
- <li>vertical scrollbar button middle</li>
- <li>vertical scrollbar button bottom</li>
- <li>horizontal scrollbar top</li>
- <li>horizontal scrollbar background</li>
- <li>horizontal scrollbar bottom</li>
- <li>horizontal scrollbar button top</li>
- <li>horizontal scrollbar button middle</li>
- <li>horizontal scrollbar button bottom</li>
- <li>checkbox unchecked</li>
- <li>checkbox checked</li>
- <li>radiobutton unchecked</li>
- <li>radiobutton checked</li>
- <li>normal button left side</li>
- <li>normal button background</li>
- <li>normal button right side</li>
- <li>pressed button left side</li>
- <li>pressed button background</li>
- <li>pressed button right side</li>
- <li>selected button left side</li>
- <li>selected button background</li>
- <li>selected button right side</li>
- <li>left arrow button</li>
- <li>down arrow button</li>
- <li>right arrow button</li>
- <li>pressed left arrow button</li>
- <li>pressed down arrow button</li>
- <li>pressed right arrow button</li>
- <li>selected left arrow button</li>
- <li>selected down arrow button</li>
- <li>selected right arrow button</li></ul>
- <div class="pre"><pre class="lineno">1<br></pre><code><span class="hl_t">int</span> <span class="hl_f">ui_skin</span>(<span class="hl_v">ui_t</span> <span class="hl_o">*</span><span class="hl_v">ctx</span>, <span class="hl_v">ui_image_t</span> <span class="hl_o">*</span><span class="hl_v">skin</span>);</code></div>
- <p>Sets a custom skin. The <samp>skin[]</samp> array has as many elements as UI elements, see the list above.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>ctx</samp> </td><td>Pointer to UI context </td></tr>
- <tr><td><samp>skin</samp> </td><td>Array of skin <a href="#image" onclick="c('image')">image</a>s </td></tr></table></div>
- <p>Returns 0 on success, an error code otherwise.</p>
- <p>If you include <samp>stb_image.h</samp> <i>before</i> <b>ui.h</b>, then you can also use the following function to load skin from a single PNG file:</p>
- <div class="pre"><pre class="lineno">1<br></pre><code><span class="hl_t">int</span> <span class="hl_f">ui_pngskin</span>(<span class="hl_v">ui_t</span> <span class="hl_o">*</span><span class="hl_v">ctx</span>, <span class="hl_t">uint8_t</span> <span class="hl_o">*</span><span class="hl_v">png</span>, <span class="hl_t">int</span> <span class="hl_v">size</span>);</code></div>
- <p>Sets a custom skin from a packed PNG file.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>ctx</samp> </td><td>Pointer to UI context </td></tr>
- <tr><td><samp>png</samp> </td><td>Pointer to a PNG image </td></tr>
- <tr><td><samp>size</samp> </td><td>Size of the PNG image </td></tr></table></div>
- <p>Returns 0 on success, an error code otherwise.</p>
- <p>The packed PNG must have a comment, with <samp>x</samp>, <samp>y</samp>, <samp>w</samp>, <samp>h</samp> ASCII decimal numbers in each line that describe areas on the image.
- To create such packed skin PNGs, you can use for example <a href="https://gitlab.com/bztsrc/spratlas" target="new">sprpack</a> with the <samp>-cdt</samp> flags, like:</p>
- <div class="pre"><pre>
- sprpack -cdt skin.png mouse.png popup_topleft.png popup_topmiddle.png ...
- </pre></div>
- <p>You must list all separate UI element PNGs and in the exact same order as listed above, otherwise the skin PNG won't work.</p><br style="clear:both;"><label class="btn prev" accesskey="p" for="_fonts" title="Fonts">Previous</label><label class="btn next" accesskey="n" for="_event_handling" title="Event Handling">Next</label></div>
- <div class="page" rel="event_handling"><div><ul class="breadcrumbs"><li><label class="home" for="_" title="Home"></label> »</li><li> Event Handling</li></ul><hr></div>
- <h1 id="event_handling">Event Handling<a href="#event_handling"></a></h1>
- <div class="pre"><pre class="lineno">1<br></pre><code><span class="hl_v">ui_event_t</span> <span class="hl_o">*</span><span class="hl_f">ui_event</span>(<span class="hl_v">ui_t</span> <span class="hl_o">*</span><span class="hl_v">ctx</span>, <span class="hl_v">ui_form_t</span> <span class="hl_o">*</span><span class="hl_v">form</span>);</code></div>
- <p>This is the heart of SMGUI, this function queries the events and also adds an UI layer on top with the desired form <a href="#layout" onclick="c('layout')">layout</a> to
- the window.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>ctx</samp> </td><td>Pointer to UI context </td></tr>
- <tr><td><samp>form</samp> </td><td>Form <a href="#layout" onclick="c('layout')">layout</a> </td></tr></table></div>
- <p>Returns NULL if the main loop should exit, an event otherwise.</p>
- <p>If you change one of the variables that the passed <samp>form</samp> references, then you must call <samp>ui_refresh()</samp> before calling
- <samp>ui_event()</samp> to force a <a href="#redrawing" onclick="c('redrawing')">redrawing</a>.</p>
- <p>The returned event should be parsed with a switch on <samp>evt->type</samp>, because most fields depend on the type.</p><br style="clear:both;"><label class="btn prev" accesskey="p" for="_look_and_feel" title="Look and Feel">Previous</label><label class="btn next" accesskey="n" for="_no_event" title="No Event">Next</label></div>
- <div class="page" rel="no_event"><div><ul class="breadcrumbs"><li><label class="home" for="_" title="Home"></label> »</li><li> No Event</li></ul><hr></div>
- <h1 id="no_event">No Event<a href="#no_event"></a></h1>
- <p>Nothing happened.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>evt->type</samp> </td><td><samp>UI_EVT_NONE</samp> (0) </td></tr></table></div><br style="clear:both;"><label class="btn prev" accesskey="p" for="_event_handling" title="Event Handling">Previous</label><label class="btn next" accesskey="n" for="_mouse" title="Mouse">Next</label></div>
- <div class="page" rel="mouse"><div><ul class="breadcrumbs"><li><label class="home" for="_" title="Home"></label> »</li><li> Mouse</li></ul><hr></div>
- <h1 id="mouse">Mouse<a href="#mouse"></a></h1>
- <p>This is generated whenever a mouse button is pressed or released.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>evt->type</samp> </td><td><samp>UI_EVT_MOUSE</samp> </td></tr>
- <tr><td><samp>evt->btn</samp> </td><td>Current button's state </td></tr>
- <tr><td><samp>evt->x</samp> </td><td>Current mouse X position </td></tr>
- <tr><td><samp>evt->y</samp> </td><td>Current mouse Y position </td></tr></table></div>
- <p>The <samp>btn</samp> field is a bitfield with the following values:</p>
- <div class="table"><table><tr><th>Define </th><th>Description </th></tr>
- <tr><td><samp>UI_BTN_L</samp> </td><td>Left mouse button </td></tr>
- <tr><td><samp>UI_BTN_M</samp> </td><td>Middle mouse button </td></tr>
- <tr><td><samp>UI_BTN_R</samp> </td><td>Right mouse button </td></tr>
- <tr><td><samp>UI_BTN_U</samp> </td><td>Wheel scrolled up </td></tr>
- <tr><td><samp>UI_BTN_D</samp> </td><td>Wheel scrolled down </td></tr>
- <tr><td><samp>UI_BTN_A</samp> </td><td>Wheel scrolled left </td></tr>
- <tr><td><samp>UI_BTN_B</samp> </td><td>Wheel scrolled right </td></tr>
- <tr><td><samp>UI_BTN_RELEASE</samp> </td><td>set if this is a release event </td></tr></table></div>
- <p>If you want to know the mouse's position without an event, then you can use</p>
- <div class="pre"><pre class="lineno">1<br></pre><code><span class="hl_t">int</span> <span class="hl_f">ui_getmouse</span>(<span class="hl_v">ui_t</span> <span class="hl_o">*</span><span class="hl_v">ctx</span>, <span class="hl_t">int</span> <span class="hl_o">*</span><span class="hl_v">x</span>, <span class="hl_t">int</span> <span class="hl_o">*</span><span class="hl_v">y</span>);</code></div>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>ctx</samp> </td><td>Pointer to UI context </td></tr>
- <tr><td><samp>x</samp> </td><td>Pointer to store X position </td></tr>
- <tr><td><samp>y</samp> </td><td>Pointer to store Y position </td></tr></table></div>
- <p>Returns 0 on success, error code otherwise.</p><br style="clear:both;"><label class="btn prev" accesskey="p" for="_no_event" title="No Event">Previous</label><label class="btn next" accesskey="n" for="_gamepad" title="Gamepad">Next</label></div>
- <div class="page" rel="gamepad"><div><ul class="breadcrumbs"><li><label class="home" for="_" title="Home"></label> »</li><li> Gamepad</li></ul><hr></div>
- <h1 id="gamepad">Gamepad<a href="#gamepad"></a></h1>
- <p>This is generated whenever the gamepad state changes.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>evt->type</samp> </td><td><samp>UI_EVT_GAMEPAD</samp> </td></tr>
- <tr><td><samp>evt->btn</samp> </td><td>Current button's state </td></tr>
- <tr><td><samp>evt->x</samp> </td><td>Left joystick X position </td></tr>
- <tr><td><samp>evt->y</samp> </td><td>Left joystick Y position </td></tr>
- <tr><td><samp>evt->rx</samp> </td><td>Right joystick X position </td></tr>
- <tr><td><samp>evt->ry</samp> </td><td>Right joystick Y position </td></tr>
- <tr><td><samp>evt->key[0]</samp> </td><td>Gamepad's index if there's more than one </td></tr></table></div>
- <p>Joystick coordinates are signed, and in the range -32768 .. +32768. The <samp>btn</samp> field is a bitfield with the following values:</p>
- <div class="table"><table><tr><th>Define </th><th>Description </th></tr>
- <tr><td><samp>UI_BTN_A</samp> </td><td>The 'A'/cross button state </td></tr>
- <tr><td><samp>UI_BTN_B</samp> </td><td>The 'B'/circle button state </td></tr>
- <tr><td><samp>UI_BTN_X</samp> </td><td>The 'X'/square button state </td></tr>
- <tr><td><samp>UI_BTN_Y</samp> </td><td>The 'Y'/triangle button state </td></tr>
- <tr><td><samp>UI_BTN_L</samp> </td><td>DPad left button state </td></tr>
- <tr><td><samp>UI_BTN_R</samp> </td><td>DPad right button state </td></tr>
- <tr><td><samp>UI_BTN_U</samp> </td><td>DPad up button state </td></tr>
- <tr><td><samp>UI_BTN_D</samp> </td><td>DPad down button state </td></tr>
- <tr><td><samp>UI_BTN_BA</samp> </td><td>Back button state </td></tr>
- <tr><td><samp>UI_BTN_ST</samp> </td><td>Start button state </td></tr>
- <tr><td><samp>UI_BTN_GU</samp> </td><td>Guide button state </td></tr>
- <tr><td><samp>UI_BTN_LT</samp> </td><td>Left thumb button state </td></tr>
- <tr><td><samp>UI_BTN_RT</samp> </td><td>Right thumb button state </td></tr>
- <tr><td><samp>UI_BTN_LS</samp> </td><td>Left shoulder button state </td></tr>
- <tr><td><samp>UI_BTN_RS</samp> </td><td>Right shoulder button state </td></tr></table></div><br style="clear:both;"><label class="btn prev" accesskey="p" for="_mouse" title="Mouse">Previous</label><label class="btn next" accesskey="n" for="_keyboard" title="Keyboard">Next</label></div>
- <div class="page" rel="keyboard"><div><ul class="breadcrumbs"><li><label class="home" for="_" title="Home"></label> »</li><li> Keyboard</li></ul><hr></div>
- <h1 id="keyboard">Keyboard<a href="#keyboard"></a></h1>
- <p>This is generated whenever a key is pressed on the keyboard.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>evt->type</samp> </td><td><samp>UI_EVT_KEY</samp> </td></tr>
- <tr><td><samp>evt->btn</samp> </td><td>Modifier key's state </td></tr>
- <tr><td><samp>evt->key</samp> </td><td>Pressed key </td></tr></table></div>
- <p>The returned key is an UTF-8 character, or (in case of special keys) an invalid UTF-8 sequence with the key's name. To
- distinguish, check if <samp>key[1]</samp> is non-zero and the most significant bit in <samp>key[0]</samp> is set (valid UTF-8) or clear (a key name).</p>
- <div class="hint"><p><span>Hint</span></p><p> There's no mapping with magic defines, to figure out what code a certain key generates, just print <samp>evt->key</samp>.</p></div>
- <p>The <samp>btn</samp> field is a bitfield with the following values:</p>
- <div class="table"><table><tr><th>Define </th><th>Description </th></tr>
- <tr><td><samp>UI_BTN_SHIFT</samp> </td><td>One of the <kbd>Shift</kbd> keys is pressed </td></tr>
- <tr><td><samp>UI_BTN_CONTROL</samp> </td><td>One of the <kbd>Control</kbd> keys is pressed </td></tr>
- <tr><td><samp>UI_BTN_ALT</samp> </td><td>One of the <kbd>Alt</kbd> keys is pressed (right key is often called <kbd>AltGr</kbd>) </td></tr>
- <tr><td><samp>UI_BTN_GUI</samp> </td><td>One of the <kbd>GUI</kbd> keys is pressed </td></tr></table></div>
- <p>For the modifier keys (<samp>LShift</samp>, <samp>RShift</samp>, <samp>LCtrl</samp>, <samp>RCtrl</samp>, <samp>LAlt</samp>, <samp>RAlt</samp>, <samp>LGui</samp> and <samp>RGui</samp>) you'll also receive
- a key release event, with <samp>UI_BTN_RELEASE</samp> being set. Other keys only generate a key press event.</p><br style="clear:both;"><label class="btn prev" accesskey="p" for="_gamepad" title="Gamepad">Previous</label><label class="btn next" accesskey="n" for="_dropped_file" title="Dropped File">Next</label></div>
- <div class="page" rel="dropped_file"><div><ul class="breadcrumbs"><li><label class="home" for="_" title="Home"></label> »</li><li> Dropped File</li></ul><hr></div>
- <h1 id="dropped_file">Dropped File<a href="#dropped_file"></a></h1>
- <p>This is generated whenever a file is dropped on the window.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>evt->type</samp> </td><td><samp>UI_EVT_DROP</samp> </td></tr>
- <tr><td><samp>evt->x</samp> </td><td>Current mouse X position </td></tr>
- <tr><td><samp>evt->y</samp> </td><td>Current mouse Y position </td></tr>
- <tr><td><samp>evt->fn</samp> </td><td>Path of the file </td></tr></table></div><br style="clear:both;"><label class="btn prev" accesskey="p" for="_keyboard" title="Keyboard">Previous</label><label class="btn next" accesskey="n" for="_window_resize" title="Window Resize">Next</label></div>
- <div class="page" rel="window_resize"><div><ul class="breadcrumbs"><li><label class="home" for="_" title="Home"></label> »</li><li> Window Resize</li></ul><hr></div>
- <h1 id="window_resize">Window Resize<a href="#window_resize"></a></h1>
- <p>This is generated whenever the window is resized.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>evt->type</samp> </td><td><samp>UI_EVT_RESIZE</samp> </td></tr>
- <tr><td><samp>evt->x</samp> </td><td>New window width </td></tr>
- <tr><td><samp>evt->y</samp> </td><td>New window height </td></tr></table></div><br style="clear:both;"><label class="btn prev" accesskey="p" for="_dropped_file" title="Dropped File">Previous</label><label class="btn next" accesskey="n" for="_clipboard" title="Clipboard">Next</label></div>
- <div class="page" rel="clipboard"><div><ul class="breadcrumbs"><li><label class="home" for="_" title="Home"></label> »</li><li> Clipboard</li></ul><hr></div>
- <h1 id="clipboard">Clipboard<a href="#clipboard"></a></h1>
- <h2 id="paste">Paste<a href="#paste"></a></h2>
- <p>To query the clipboard (after you have received a <a href="#keyboard" onclick="c('keyboard')">keyboard</a> event with <samp>Paste</samp> key), call</p>
- <div class="pre"><pre class="lineno">1<br></pre><code><span class="hl_t">char</span> <span class="hl_o">*</span><span class="hl_f">ui_getclipboard</span>(<span class="hl_v">ui_t</span> <span class="hl_o">*</span><span class="hl_v">ctx</span>);</code></div>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>ctx</samp> </td><td>Pointer to UI context </td></tr></table></div>
- <p>Returns NULL if the clipboard is empty, otherwise the content in a newly allocated buffer. It is the caller's duty to
- free this buffer after finished using it.</p>
- <h2 id="copy">Copy<a href="#copy"></a></h2>
- <p>To set the clipboard (after you have received <samp>Cut</samp> or <samp>Copy</samp> key), call</p>
- <div class="pre"><pre class="lineno">1<br></pre><code><span class="hl_t">char</span> <span class="hl_o">*</span><span class="hl_f">ui_setclipboard</span>(<span class="hl_v">ui_t</span> <span class="hl_o">*</span><span class="hl_v">ctx</span>, <span class="hl_t">char</span> <span class="hl_o">*</span><span class="hl_v">str</span>);</code></div>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>ctx</samp> </td><td>Pointer to UI context </td></tr>
- <tr><td><samp>str</samp> </td><td>String to copy to clipboard </td></tr></table></div>
- <p>Returns 0 on success, error code otherwise.</p><br style="clear:both;"><label class="btn prev" accesskey="p" for="_window_resize" title="Window Resize">Previous</label><label class="btn next" accesskey="n" for="_layout" title="Layout">Next</label></div>
- <div class="page" rel="layout"><div><ul class="breadcrumbs"><li><label class="home" for="_" title="Home"></label> »</li><li> Layout</li></ul><hr></div>
- <h1 id="layout">Layout<a href="#layout"></a></h1>
- <p>The SMGUI is not an immediate-mode GUI, but neither uses callbacks. Instead it expects that you already have your
- variables, and you provide a form which references those variables.</p>
- <p>The form is an array of <samp>ui_form_t</samp> elements, and the last element's type <i>MUST</i> be <samp>UI_END</samp>. Some of the fields
- are common, others are type specific. The common fields are as follows:</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to data </td></tr>
- <tr><td><samp>form->type</samp> </td><td>Form element type </td></tr>
- <tr><td><samp>form->align</samp> </td><td>Form element alignment </td></tr>
- <tr><td><samp>form->flags</samp> </td><td>Form element flags (like visibility) </td></tr>
- <tr><td><samp>form->x</samp> </td><td>Form element desired position </td></tr>
- <tr><td><samp>form->y</samp> </td><td>Form element desired position </td></tr>
- <tr><td><samp>form->w</samp> </td><td>Form element desired width </td></tr>
- <tr><td><samp>form->h</samp> </td><td>Form element desired height </td></tr>
- <tr><td><samp>form->m</samp> </td><td>Form element margin </td></tr>
- <tr><td><samp>form->p</samp> </td><td>Form element padding (containers only) </td></tr></table></div>
- <h2 id="field_flags">Field Flags<a href="#field_flags"></a></h2>
- <p>These control how a certain field is displayed.</p>
- <ul><li><samp>UI_HIDDEN</samp> not shown, does not influence normal flow</li>
- <li><samp>UI_NOBULLET</samp> for <a href="#toggle" onclick="c('toggle')">toggle</a>s, <a href="#checkbox" onclick="c('checkbox')">checkbox</a>es and <a href="#radiobutton" onclick="c('radiobutton')">radiobutton</a>s only display the label</li>
- <li><samp>UI_NOHEADER</samp> for <a href="#table" onclick="c('table')">table</a>s and grids, do not show the header</li>
- <li><samp>UI_NOBR</samp> forces the next field in the same line, no line break</li>
- <li><samp>UI_FORCEBR</samp> opposite, breaks flow and forces the next field into a new line</li>
- <li><samp>UI_ALTSKIN</samp> for fields which support multiple skins (eg. tab instead of menu)</li>
- <li><samp>UI_NOBORDER</samp> for containers, do not display the borders</li>
- <li><samp>UI_NOSHADOW</samp> for popups, do not display shadows</li>
- <li><samp>UI_HSCROLL</samp> for containers, display horizontal scrollbar</li>
- <li><samp>UI_VSCROLL</samp> for containers, display vertical scrollbar</li>
- <li><samp>UI_SCROLL</samp> same as <samp>UI_HSCROLL</samp> + <samp>UI_VSCROLL</samp></li>
- <li><samp>UI_DRAGGABLE</samp> for popups, allows the user to move them around</li>
- <li><samp>UI_RESIZABLE</samp> for popups, allows the user to resize them</li>
- <li><samp>UI_SELECTED</samp> make the input box selected</li>
- <li><samp>UI_DISABLED</samp> make the field inactive, different style and non-clickable</li></ul>
- <h2 id="positioning">Positioning<a href="#positioning"></a></h2>
- <p>SMGUI does not use the classic packed rows / columns / grid layout, instead it utilizes a HTML-like flexible flow. You
- can specify coordinates in <samp>form->x</samp> and <samp>form->y</samp> three different ways: relative, absolute and percentage.</p>
- <ul><li>Relative positioning is the default, but for convenience you can also use the <samp>UI_REL()</samp> macro. A field positioned like this affects the normal flow.</li>
- <li>For absolute positioning, use the <samp>UI_ABS()</samp> macro. You can also change the gravity and use <samp>UI_ABS_RIGHT()</samp> or <samp>UI_ABS_BOTTOM()</samp> to specify the position relative to the parent container's width or height. Outside of normal flow.</li>
- <li>For percentage, use the <samp>UI_PERCENT()</samp> macro. This calculates the position as a parcentage to the parent container's width or height. Outside of normal flow.</li>
- <li>For percentage plus some pixels, use the <samp>UI_PERPLUS()</samp> macro.</li></ul>
- <p>If you leave <samp>form->w</samp> and <samp>form->h</samp> as 0, then the element's width and height will be automatically calculated. If <samp>UI_ABS()</samp>
- macro is used on them, then the parent container's width (or height) minus the value will be the width (or height).</p>
- <p>You can also use <samp>form->align</samp> to specify alignment on the given x, y coordinates. This is an OR'd bitmask.</p>
- <ul><li><samp>UI_LEFT</samp> places the element as <samp>form->x</samp> is on the left (default)</li>
- <li><samp>UI_RIGHT</samp> places the element as <samp>form->x</samp> is on the right</li>
- <li><samp>UI_CENTER</samp> places the element so that <samp>form->x</samp> will be in the middle</li>
- <li><samp>UI_TOP</samp> places the element as <samp>form->y</samp> will be at the top (default)</li>
- <li><samp>UI_BOTTOM</samp> places the element as <samp>form->y</samp> will be at the bottom</li>
- <li><samp>UI_MIDDLE</samp> places the element so that <samp>form->y</samp> will be in the middle</li></ul>
- <p>Examples:</p>
- <div class="pre"><pre class="lineno">1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br></pre><code><span class="hl_v">ui_form_t</span> <span class="hl_v">form</span>[] <span class="hl_o">=</span> {
- <span class="hl_c">/* these will be placed one after another, left to right,
- * break to the next line if necessary, tightly packed */</span>
- { <span class="hl_o">.</span><span class="hl_v">type</span> <span class="hl_o">=</span> <span class="hl_v">UI_LABEL</span>, <span class="hl_o">.</span><span class="hl_v">label</span> <span class="hl_o">=</span> <span class="hl_n">1</span> },
- { <span class="hl_o">.</span><span class="hl_v">type</span> <span class="hl_o">=</span> <span class="hl_v">UI_LABEL</span>, <span class="hl_o">.</span><span class="hl_v">label</span> <span class="hl_o">=</span> <span class="hl_n">1</span> },
- <span class="hl_c">/* this will also be placed after the other but with a spacing */</span>
- { <span class="hl_o">.</span><span class="hl_v">type</span> <span class="hl_o">=</span> <span class="hl_v">UI_LABEL</span>, <span class="hl_o">.</span><span class="hl_v">x</span> <span class="hl_o">=</span> <span class="hl_f">UI_REL</span>(<span class="hl_n">10</span>), <span class="hl_o">.</span><span class="hl_v">label</span> <span class="hl_o">=</span> <span class="hl_n">1</span> },
- <span class="hl_c">/* this will be placed at absolute position */</span>
- { <span class="hl_o">.</span><span class="hl_v">type</span> <span class="hl_o">=</span> <span class="hl_v">UI_LABEL</span>, <span class="hl_o">.</span><span class="hl_v">x</span> <span class="hl_o">=</span> <span class="hl_f">UI_ABS</span>(<span class="hl_n">100</span>), <span class="hl_o">.</span><span class="hl_v">y</span> <span class="hl_o">=</span> <span class="hl_f">UI_ABS</span>(<span class="hl_n">100</span>), <span class="hl_o">.</span><span class="hl_v">label</span> <span class="hl_o">=</span> <span class="hl_n">1</span> },
- <span class="hl_c">/* this will be placed at the centre of the window */</span>
- { <span class="hl_o">.</span><span class="hl_v">type</span> <span class="hl_o">=</span> <span class="hl_v">UI_LABEL</span>, <span class="hl_o">.</span><span class="hl_v">align</span> <span class="hl_o">=</span> <span class="hl_v">UI_CENTER</span> <span class="hl_o">|</span> <span class="hl_v">UI_MIDDLE</span>,
- <span class="hl_o">.</span><span class="hl_v">x</span> <span class="hl_o">=</span> <span class="hl_f">UI_PERCENT</span>(<span class="hl_n">50</span>), <span class="hl_o">.</span><span class="hl_v">y</span> <span class="hl_o">=</span> <span class="hl_f">UI_PERCENT</span>(<span class="hl_n">50</span>), <span class="hl_o">.</span><span class="hl_v">label</span> <span class="hl_o">=</span> <span class="hl_n">1</span> },
- <span class="hl_c">/* this will be screen width - 20 and screen height - 20 in size */</span>
- { <span class="hl_o">.</span><span class="hl_v">type</span> <span class="hl_o">=</span> <span class="hl_v">UI_POPUP</span>, <span class="hl_o">.</span><span class="hl_v">x</span> <span class="hl_o">=</span> <span class="hl_f">UI_ABS</span>(<span class="hl_n">10</span>), <span class="hl_o">.</span><span class="hl_v">y</span> <span class="hl_o">=</span> <span class="hl_f">UI_ABS</span>(<span class="hl_n">10</span>),
- <span class="hl_o">.</span><span class="hl_v">w</span> <span class="hl_o">=</span> <span class="hl_f">UI_ABS</span>(<span class="hl_n">20</span>), <span class="hl_o">.</span><span class="hl_v">h</span> <span class="hl_o">=</span> <span class="hl_f">UI_ABS</span>(<span class="hl_n">20</span>), <span class="hl_o">.</span><span class="hl_v">ptr</span> <span class="hl_o">=</span> <span class="hl_o">&</span><span class="hl_v">popupform</span> },
- <span class="hl_c">/* it is important to close the list */</span>
- { <span class="hl_o">.</span><span class="hl_v">type</span> <span class="hl_o">=</span> <span class="hl_v">UI_END</span> }
- };</code></div>
- <h2 id="multithreading">Multithreading<a href="#multithreading"></a></h2>
- <p>Since the form just references your variables, it is perfectly fine if you have a thread that displays the layout and
- you handle your variables from another thread, this will just work. On the other hand if you wish to dynamically change
- your form from another thread, then it is your job to properly protect your form with semaphores. For example:</p>
- <div class="pre"><pre class="lineno">1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br></pre><code><span class="hl_v">ui_form_t</span> <span class="hl_v">form</span>[];
- <span class="hl_c">/* this function can be called from any thread */</span>
- <span class="hl_t">void</span> <span class="hl_f">regenerate_form</span>()
- {
- <span class="hl_f">mutex_lock</span>(<span class="hl_o">&</span><span class="hl_v">my_form_mutex</span>);
- <span class="hl_c">/* do changes to the form[] array here */</span>
- <span class="hl_f">mutex_unlock</span>(<span class="hl_o">&</span><span class="hl_v">my_form_mutex</span>);
- }
- <span class="hl_c">/* and in the main thread in your main loop */</span>
- <span class="hl_f">mutex_lock</span>(<span class="hl_o">&</span><span class="hl_v">my_form_mutex</span>);
- <span class="hl_v">evt</span> <span class="hl_o">=</span> <span class="hl_f">ui_event</span>(<span class="hl_o">&</span><span class="hl_v">ctx</span>, <span class="hl_v">form</span>);
- <span class="hl_f">mutex_unlock</span>(<span class="hl_o">&</span><span class="hl_v">my_form_mutex</span>);</code></div>
- <p>Note that since SMGUI itself does not use any threading, therefore you can use whatever threading and mutex implementation
- you want to use. The SDL backend for example provides <samp>SDL_Mutex</samp>, and for GLFW one could use the pthread library.</p>
- <h2 id="redrawing">Redrawing<a href="#redrawing"></a></h2>
- <p>Redrawing the form happens automatically in <a href="#event_handling" onclick="c('event_handling')">event handling</a> when needed, and that's it. However if you change one of
- the referenced variables outside of the UI's scope, then you must call</p>
- <div class="pre"><pre class="lineno">1<br></pre><code><span class="hl_t">int</span> <span class="hl_f">ui_refresh</span>(<span class="hl_v">ui_t</span> <span class="hl_o">*</span><span class="hl_v">ctx</span>);</code></div>
- <p>Informs UI that it must redraw the UI layer.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>ctx</samp> </td><td>Pointer to UI context </td></tr></table></div>
- <p>Returns 0 on success, error code otherwise.</p><br style="clear:both;"><label class="btn prev" accesskey="p" for="_clipboard" title="Clipboard">Previous</label><label class="btn next" accesskey="n" for="_containers" title="Containers">Next</label></div>
- <div class="page" rel="containers"><div><ul class="breadcrumbs"><li><label class="home" for="_" title="Home"></label> »</li><li> Containers</li></ul><hr></div>
- <h1 id="containers">Containers<a href="#containers"></a></h1>
- <p>If a container is preceeded by a <a href="#toggle" onclick="c('toggle')">toggle</a> field, then that toggle controls the visibility of that container.</p>
- <h2 id="popup">Popup<a href="#popup"></a></h2>
- <img class="imgl" width="40" height="31" alt="ui_popup.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAfCAYAAACVgY94AAAAuklEQVRYw+3X0QnEIAwG4Hi4iBPEiZyls7mAyQaO4Aa9lxMKp54cV81B/qealvoRS6AmhHCCkOScIcZorjVbb0hIKeWtZuuF9/6WTYlo6t1E1Kw/QHjsys2YGRCxu37l2NZBRARmHuH2H3FFzuC2ACuudlIU8Nq5WeTyb3C0/u8x0xuUvxrW30Z8BxWoQAUqUIFC4pyTC+zhRABHuO3AT7itwBkcAIDNOTd/mO9OSmnqOdOoHTpmFLgwT81vPn3xojzHAAAAAElFTkSuQmCC">
- <p>Draws a popup.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_POPUP</samp> </td></tr>
- <tr><td><samp>form->flags</samp> </td><td>Might want <samp>UI_HIDDEN</samp>, <samp>UI_DRAGGABLE</samp> or <samp>UI_RESIZABLE</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to another <samp>ui_form_t</samp> buffer </td></tr>
- <tr><td><samp>form->m</samp> </td><td>Margin in pixels </td></tr>
- <tr><td><samp>form->p</samp> </td><td>Padding in pixels </td></tr>
- <tr><td><samp>form->label</samp> </td><td>Title, index to the localized strings array (or 0) </td></tr></table></div>
- <h2 id="menu">Menu<a href="#menu"></a></h2>
- <img class="imgl" width="40" height="31" alt="ui_menu.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAfCAYAAACVgY94AAAAYUlEQVRYw+3XsQnAQAxD0XO4OT1LZvMkGsEbJFUgkMClCaj4Ku3mgSpFZh7DJJJGVcX9Nq+HQ7r7cduGeeyB09C0UzFAgAABAgQIECBAgAABfl11kl4Hs0tiNfuoGODPOQHi4RMjCDG2swAAAABJRU5ErkJggg==">
- <p>Same as popup, but by default its state is <samp>UI_HIDDEN</samp>, and there can be only one menu visible at any time. Its
- <a href="#checkbox" onclick="c('checkbox')">checkbox</a> and <a href="#radiobutton" onclick="c('radiobutton')">radiobutton</a> children are highlighted when you hover the mouse over them.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_MENU</samp> </td></tr>
- <tr><td><samp>form->flags</samp> </td><td>Might want <samp>UI_SCROLL</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to another <samp>ui_form_t</samp> buffer </td></tr>
- <tr><td><samp>form->m</samp> </td><td>Margin in pixels </td></tr>
- <tr><td><samp>form->p</samp> </td><td>Padding in pixels </td></tr></table></div>
- <h2 id="division">Division<a href="#division"></a></h2>
- <p>Does not draw anything, just provides a way to group further fields, hide / show and position them together.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_DIV</samp> </td></tr>
- <tr><td><samp>form->flags</samp> </td><td>Might want <samp>UI_SCROLL</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to another <samp>ui_form_t</samp> buffer </td></tr>
- <tr><td><samp>form->m</samp> </td><td>Margin in pixels </td></tr>
- <tr><td><samp>form->p</samp> </td><td>Padding in pixels </td></tr></table></div>
- <h2 id="table">Table<a href="#table"></a></h2>
- <p>Displays fields as a table or grid. Requires including the <b>ui_table.h</b> module.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_TABLE</samp> </td></tr>
- <tr><td><samp>form->flags</samp> </td><td>Might want <samp>UI_SCROLL</samp> or <samp>UI_NOHEADER</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to data records </td></tr>
- <tr><td><samp>form->tblsel</samp> </td><td>Index of the selected data record </td></tr>
- <tr><td><samp>form->tblnum</samp> </td><td>Number of data records </td></tr>
- <tr><td><samp>form->tblsiz</samp> </td><td>Size of one data record in bytes </td></tr>
- <tr><td><samp>form->tblrow</samp> </td><td>Row size in pixels </td></tr>
- <tr><td><samp>form->tblcol</samp> </td><td>Column size in pixels (if grid, otherwise 0) </td></tr>
- <tr><td><samp>form->data</samp> </td><td>Pointer to <samp>ui_form_t</samp> headers </td></tr>
- <tr><td><samp>form->cmps</samp> </td><td>Comparators for sorting (or NULL) </td></tr>
- <tr><td><samp>form->m</samp> </td><td>Cellmargin in pixels </td></tr></table></div>
- <p>The <samp>form->ptr</samp> points to the data records, which in case of a table is probably an array of structs. The <samp>form->data</samp> list
- must have at least one UI field and <i>MUST</i> always end in an <samp>UI_END</samp> field. This contains the <samp>hdr</samp> headers and also
- specifies how to display a certain column. For a table, set <samp>form->tblcol</samp> to 0, and you probably want multiple headers in
- <samp>form->data</samp>. For a grid, set <samp>form->tblcol</samp> to non-zero and then only the first header used in <samp>form->data</samp> for all cells.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>hdr->type</samp> </td><td>The cell's display type </td></tr>
- <tr><td><samp>hdr->tblhdr</samp> </td><td>Header title, index to the localized strings array </td></tr>
- <tr><td><samp>hdr->tblofs</samp> </td><td>Offset of field within the data record (table only) </td></tr>
- <tr><td><samp>hdr->flags</samp> </td><td>Set <samp>UI_POINTER</samp> if this column's field is a pointer </td></tr>
- <tr><td><samp>hdr->w</samp> </td><td>Column width, might use <samp>UI_PERCENT</samp> </td></tr></table></div>
- <p>To enable sorting, you must provide twice as many comparator functions as header fields. First is for ascending,
- the second is for descending order per column.</p>
- <div class="pre"><pre class="lineno">1<br></pre><code><span class="hl_t">typedef</span> <span class="hl_t">int</span> (<span class="hl_o">*</span><span class="hl_f">ui_comp</span>)(<span class="hl_v">const</span> <span class="hl_t">void</span> <span class="hl_o">*</span><span class="hl_v">a</span>, <span class="hl_v">const</span> <span class="hl_t">void</span> <span class="hl_o">*</span><span class="hl_v">b</span>);</code></div>
- <p>The prototype is a standard POSIX comparator, used as libc <samp>qsort()</samp> function's parameter.</p><br style="clear:both;"><label class="btn prev" accesskey="p" for="_layout" title="Layout">Previous</label><label class="btn next" accesskey="n" for="_labels" title="Labels">Next</label></div>
- <div class="page" rel="labels"><div><ul class="breadcrumbs"><li><label class="home" for="_" title="Home"></label> »</li><li> Labels</li></ul><hr></div>
- <h1 id="labels">Labels<a href="#labels"></a></h1>
- <h2 id="label">Label<a href="#label"></a></h2>
- <img class="imgl" width="48" height="19" alt="ui_label.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAATAQMAAADs9BxcAAAABlBMVEUAAAD///+l2Z/dAAAAOUlEQVQI12NgIAz4mYBEAgMbG5B6AKYYgZR8+/EEkCBP+gcQxf9sA5jHhkydSQNS/Mztxwx/4LMAAGNjD5BvmPyHAAAAAElFTkSuQmCC">
- <p>Draws a text label. If <samp>form->label</samp> is 0, then <samp>form->ptr</samp> should point to a zero terminated UTF-8 string.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_LABEL</samp> </td></tr>
- <tr><td><samp>form->label</samp> </td><td>Index to the localized strings array (or 0) </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Only if <samp>label</samp> is 0, pointer to a string </td></tr></table></div>
- <h2 id="status">Status<a href="#status"></a></h2>
- <img class="imgl" width="48" height="19" alt="ui_label.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAATAQMAAADs9BxcAAAABlBMVEUAAAD///+l2Z/dAAAAOUlEQVQI12NgIAz4mYBEAgMbG5B6AKYYgZR8+/EEkCBP+gcQxf9sA5jHhkydSQNS/Mztxwx/4LMAAGNjD5BvmPyHAAAAAElFTkSuQmCC">
- <p>Draws a text label. Same as <samp>UI_LABEL</samp>, but instead of <samp>form->label</samp> uses the <samp>form->desc</samp> field of the element the mouse
- is hovering over. If this is 0, then <samp>form->ptr</samp> should point to a zero terminated UTF-8 string.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_STATUS</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Only if <samp>hover->desc</samp> is 0, pointer to a string </td></tr>
- <tr><td><samp>hover->desc</samp> </td><td>Index to the localized strings array (or 0) </td></tr></table></div>
- <h2 id="decimal">Decimal<a href="#decimal"></a></h2>
- <img class="imgl" width="48" height="19" alt="ui_dec.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAATAQMAAADs9BxcAAAABlBMVEUAAAD///+l2Z/dAAAAKUlEQVQI12NgIAowfjAAUcwSBWCuxAcIBRZkgMjBeCgUM4Ri/PAHn+kAsxwHLTWt8L4AAAAASUVORK5CYII=">
- <p>Draws an integer as a decimal number label. The number in the define specifies how many bits used to store the variable.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_DEC8</samp> / <samp>UI_DEC16</samp> / <samp>UI_DEC32</samp> / <samp>UI_DEC64</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to the value </td></tr></table></div>
- <h2 id="hexadecimal">Hexadecimal<a href="#hexadecimal"></a></h2>
- <img class="imgl" width="48" height="19" alt="ui_hex.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAATAQMAAADs9BxcAAAABlBMVEUAAAD///+l2Z/dAAAAKUlEQVQI12NgIA4ceAAiGQ9uAFHMByeABQ82gKnDB5B52CjmzwfwGQ4AVQ4N5XDbuLQAAAAASUVORK5CYII=">
- <p>Draws an integer as a hexadecimal number label. The number in the define specifies how many bits used to store the variable.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_HEX8</samp> / <samp>UI_HEX16</samp> / <samp>UI_HEX32</samp> / <samp>UI_HEX64</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to the value </td></tr></table></div>
- <h2 id="progressbar">Progressbar<a href="#progressbar"></a></h2>
- <img class="imgl" width="66" height="24" alt="ui_pbar.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAAAYBAMAAAC8bzZKAAAAGFBMVEUAAAAAAF4AAH4AAK0eHh4uLi5eXl7///+0lNv+AAAAnklEQVQoz73SQQrDIBAF0Kyy7xE6G/ftFULdhoZeoQcQ4V+/f9TiaIMECvkxbnzojDhN5+Q1zEqx3WtuS5+HCqm5DgQ4ELLw2BEO4oIgC/j4K4A0J8F18FuiFS4gzVb4RkDr4F9E1ELQnAJWqYUYUWppexGpp5QtGsEtjPi20wn2oiswxtxHcCwmC59a7cSBW/9PPC8mu2J+D3PSO/4AcAiTNmDMxCEAAAAASUVORK5CYII=">
- <p>Draws an integer (64 bit) as a progressbar.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_PBAR</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to the int64 value </td></tr>
- <tr><td><samp>form->max</samp> </td><td>Total value </td></tr></table></div>
- <h2 id="floating_point">Floating Point<a href="#floating_point"></a></h2>
- <img class="imgl" width="48" height="19" alt="ui_dec_float.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAATAQMAAADs9BxcAAAABlBMVEUAAAD///+l2Z/dAAAAQElEQVQI12NgIALwNzAcMGBgkDjAeKAAyD3AfOADiGI4uIGBgb2B4bABmHf4B5g6YACnJA42gCj+xuYPFfjMBwDUaBRG4IU5mAAAAABJRU5ErkJggg==">
- <p>Draws a floating point number label.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_DEC_FLOAT</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to the value </td></tr></table></div>
- <h2 id="image">Image<a href="#image"></a></h2>
- <img class="imgl" width="23" height="24" alt="ui_image.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAAYCAMAAAAmopZHAAAC/VBMVEUAAAAFAAAAAgAVBQAQBwAUDQMjEQApEwAqFAArFAAnFgguFwAuGwApHAcxHQA4HwMxIgJAJgZBJwdELxpIOSF/RgCBRwB8SRGMSwCUVxyaVw2cWAOYWg2ZWw+aXAOaXBChXQmEYz2fYACTZhKiYwCTZDakZAGlZQKmZgSsZQmnZwWqagu3aQCobQurayGhbiaobimicwupbyqjdA2bdFqqdSafdlfIcQCbe0Cxexu8fQjJeBvPdxPReASLhH7LehLSeQbOfAShgnDPfQbHfS+6gyzEhAK1iRvRfyzdggXPgy3egwfEhzq1jx/ghAnhhQDCjgnDjwDShjjHjQ7GiUOoj3vLkACfko3hiwDijADeiiezmCXniwHojAPjjRTZjT7mjwO8myDjkgPJmgnLmwvOngDcmRjanASsnpndmhnRoADwlwDrmgDunAHQpQXloADknxLvnQTloBTwngfmoRbzoADyoAvuogrpoxn/nwLLrR7KrSnwpCvupw+zrabOsCLzphP1pwDoqR39oxi8rKH1pxXpqh/Isj74pS/5qwburhbYtDTrsRf8rQ3srkn9rxD/sBPmtEL6shH8sxP9sED+tRfquE7FvK/+vB3Ewcb/vR//vCv/viH9wS7Nxr//xCb9xiXRycLrzyL/ySn/yTX9zCru0ifUzcX/zzj/0C7/0Dn80i390yH/0Ev/0U3+1DD/1ST22SL91EX81E361zHc1M382DL92Sf/1k/92TP/2ij63Cf/11n/2yr+12D83ir/3EL+3FP+3Fvi29T/4S/Z3uH93mvj3dzb3+Ld39zc4OP05lb+41f941/+5zP151je4+X95G/851H/6TX/6UD86zX87EH96WP+7Tfq5eT77FT96mz96nP87VX/6YH+7k388kX+8Gj97ov/8Wn782H98Jr99WP79nP893T793v+9ZD++G36+Ir8+IP/9pH/+W7/9az796X/9qb/+Jn8+Kb9+af/+aH8+a78+rX7+739+7b6/MP9+9H9/Nj+/dnCdRsJAAAB3UlEQVQoz2Ngwg4YoDSrgMW0idMsBFhRxZVTVtz7+OHjo3Upykji/H0rnv75++/v379/Pq3o44eKM/JVHPry49fP379///zx4/uxfB5GsLhIzdpX7z5//vb169dvnz+/e7WvRgQkzqg3++Kd5y/fvn375u3bly+f374zW48RKM47ZfPZ6w9fv3/x8uXLF+8fP7x+dk8HF1Ccs3nTjjO3znc/efbs2d3285fOHNxcyQkUN+pdsunAFUOx6gcP7kdL+F47sGnJBAOguGPv3JXbjhgqVd84dzVRxf3c+pVzex2B4g69sxas3LWoaveRI0c21i/btXLBrF5boLht44z5i9ds2LVr134g3rBm8fxZnQ5AcfPSqU09q7dt2wkE2zZsW9rVNrXUHCjukj3ZNdzMMjArLy8vNcDUxC54UqE1UFwwpjNs5olTF5bPmzdv+YUTJ+rSG2IFgeLMOjm1qqEtCw8fv3ly6/QMJ/3enCg2UPiIepanySlIy8rKy0pJq2mUFHpLQsLZI7IwTUlDW0MDiNWKCuO8hCHhzGkTkVtkpauhpKHr1pobZ8/JCI0XznjvpNyyooKissIk7yBueHwxMolrevsnJMT6e2uKA3lI8c7CqRjiE6LIyYKWHtABAHI8zlZkUGOOAAAAAElFTkSuQmCC">
- <p>This field draws an image icon. If <samp>form->ptr</samp> is not NULL, then also clickable and acts as a <a href="#button" onclick="c('button')">button</a>.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_IMAGE</samp> </td></tr>
- <tr><td><samp>form->icon</samp> </td><td>Pointer to an <samp>ui_image_t</samp> struct </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to the int value (or NULL) </td></tr>
- <tr><td><samp>form->value</samp> </td><td>Int value for this label </td></tr></table></div>
- <p>The <samp>ui_image_t</samp> image structure looks like:</p>
- <div class="table"><table><tr><th>Field </th><th>Description </th></tr>
- <tr><td><samp>w</samp> </td><td>Width in pixels </td></tr>
- <tr><td><samp>h</samp> </td><td>Height in pixels </td></tr>
- <tr><td><samp>p</samp> </td><td>Pitch in bytes (bytes in a row, at least w * 4) </td></tr>
- <tr><td><samp>buf</samp> </td><td>Pixel buffer with 32-bit RGBA packed pixels </td></tr></table></div><br style="clear:both;"><label class="btn prev" accesskey="p" for="_containers" title="Containers">Previous</label><label class="btn next" accesskey="n" for="_inputs" title="Inputs">Next</label></div>
- <div class="page" rel="inputs"><div><ul class="breadcrumbs"><li><label class="home" for="_" title="Home"></label> »</li><li> Inputs</li></ul><hr></div>
- <h1 id="inputs">Inputs<a href="#inputs"></a></h1>
- <h2 id="text">Text<a href="#text"></a></h2>
- <img class="imgl" width="161" height="20" alt="ui_text.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKEAAAAUAgMAAACYOLXjAAAADFBMVEUeHh4uLi5eXl7AwMB3Lt90AAAAvklEQVQoz73SwQ3CMAwFUEse4O/BlaulsAT7dB6msNQBukqkXi0ZO6QFBIhcwJc27VPtn5TOg0V0orGafiPtcc36/B63S2lSBiRe5YfapOtaYVjykYqx86xWo4FH2xI35GQpWWsRAVyzOwCeZ/UYH7GiGj15Ye1SpDiOXbLGN1dpQ4fMTrhLEtolWZdk3yQ2ibcSu2xzptzn7NIju1Nkz71EbEJEttqCRHbN7LyqvZ4mhs99XBb95193uIzVdAUnAJPWDFHitgAAAABJRU5ErkJggg==">
- <p>Draws a text input box. The buffer should store an editable UTF-8 string. Normally it accepts all keys as input except
- control characters, but you can further filter the keys: <samp>UI_FILTER_ID</samp> (a UNIX id), <samp>UI_FILTER_VAR</samp> (a variable name,
- same as UNIX id but first character can't be 0-9), <samp>UI_FILTER_EXPR</samp> (an expression, same as variable plus parenthesis
- and operators), and <samp>UI_FILTER_HEX</samp> (only allows hexadecimal 0-9A-F keys). The <samp>UI_FILTER_PASS</samp> filters not the input,
- but the output, displays asterisks. Copy'n'paste works too. If the <b>ui_textosk.h</b> module is included, then on input
- an on-screen keyboard is displayed from software, otherwise OS-native OSK is only shown if the platform supports it.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_TEXT</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to a buffer </td></tr>
- <tr><td><samp>form->max</samp> </td><td>Size of the buffer </td></tr>
- <tr><td><samp>form->inc</samp> </td><td>0 for all, or a <samp>UI_FILTER_x</samp> key filter </td></tr></table></div>
- <h2 id="selectbox">Selectbox<a href="#selectbox"></a></h2>
- <img class="imgl" width="72" height="24" alt="ui_select.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAAAYBAMAAACrTaaDAAAAG1BMVEUAAAAeHh4fHx8uLi4vLy9GRkZeXl5fX1/AwMDtzPodAAAAb0lEQVQoz2NgoB4wJgQMgYoMBbEDsTQoCMOnKBQKzAatoo6ORsEOiQ5BMAOHIgmgEkGJRhAEMpAVhbi4uGAo6uhAU6SkpI7FJDQ3OSmVElYUok7YTaGhpSi+gyjB7bshFHeisJQJUgRPgTgBFfMKABq3e4922WHmAAAAAElFTkSuQmCC">
- <p>Draws a selectbox. When the users clicks on it, opens a selection popup.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_SELECT</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to an int value </td></tr>
- <tr><td><samp>form->optc</samp> </td><td>Maximum value plus 1, number of options </td></tr>
- <tr><td><samp>form->optv</samp> </td><td>Pointer to a string array, options </td></tr>
- <tr><td><samp>form->m</samp> </td><td>Right margin </td></tr></table></div>
- <h2 id="optionlist">Optionlist<a href="#optionlist"></a></h2>
- <img class="imgl" width="92" height="24" alt="ui_option.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFwAAAAYBAMAAACFCIcRAAAAG1BMVEUAAAAeHh4fHx8uLi4vLy9GRkZeXl5fX1/AwMDtzPodAAAAmElEQVQ4y2NgoC0wJh4YApWbpUFBoCAOIAZTEQZSHgoFhjiVw1SYDUrlToSUqyArD1EHK+/oaBTskOgQBDNQlSu5Iil3AiuXACoWlGgEQSADTbkKQnmIEpryjg4M5UqlCNOVMExHdztYBUx5EGHlpcghQ9Dt6ljCHRQgEMUYITOIEwHxyk3heQWXclGYCpByeF4hAtC4HAAAsFCzh5Bm2IEAAAAASUVORK5CYII=">
- <p>Draws an option selector. Same as a selectbox, just with a number input box visual, no popup.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_OPTION</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to an int value </td></tr>
- <tr><td><samp>form->optc</samp> </td><td>Maximum value plus 1, number of options </td></tr>
- <tr><td><samp>form->optv</samp> </td><td>Pointer to a string array, options </td></tr>
- <tr><td><samp>form->m</samp> </td><td>Left and right margin </td></tr></table></div>
- <h2 id="float">Float<a href="#float"></a></h2>
- <img class="imgl" width="98" height="24" alt="ui_float.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGIAAAAYBAMAAADzMjWaAAAAG1BMVEUAAAAeHh4fHx8uLi4vLy9GRkZeXl5fX1/AwMDtzPodAAAAs0lEQVQ4y2NgoAcwJgkYAnWYpUFBoCBuIAZTFAbSEQoFhvh0wBSZUUOHREcHVJVEI5QAYnw6OiAqQaxGKNGBTYcTkqugOiRAikGEBFSHCrKOEHVMHWC6A8lVSq5IOpyQdCD7Q6IRWYcKQkeIEg47gMHQgdChVIqwA5cOlLACK4LpCCJKRylyWKmjhW4HFh3qeGOwA8xoBIcDiEHdVDJIdJjCsxceHaIwRSAd8OxFHKBLSQIA8mzA3UyVUPEAAAAASUVORK5CYII=">
- <p>Draws a floating point number input box.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_FLOAT</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to the value </td></tr>
- <tr><td><samp>form->fmin</samp> </td><td>Minimum value </td></tr>
- <tr><td><samp>form->fmax</samp> </td><td>Maximum value </td></tr>
- <tr><td><samp>form->finc</samp> </td><td>Increment value </td></tr>
- <tr><td><samp>form->m</samp> </td><td>Left and right margin </td></tr></table></div>
- <h2 id="integer">Integer<a href="#integer"></a></h2>
- <img class="imgl" width="62" height="24" alt="ui_int.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAAAYBAMAAABQGlNcAAAAG1BMVEUAAAAeHh4fHx8uLi4vLy9GRkZeXl5fX1/AwMDtzPodAAAAjklEQVQoz2NgoBQY4wGGQHmzNCgIFIQBMZhQGEg+FAoMEfIwITPS5Ds6GgUFJRpxyQNlOgQFO7DJO0HN7xCUgMqrIMuHqMPlYeYruSLJO0HkJZDsV1JByIcoYdGvVIrQj01eHcn8ICzypcjuV0f4DyqvjiN8JIAEueFLE3lTeGKBy4vChEDy8MSCDVCcegHJ4ZIZC8f3vAAAAABJRU5ErkJggg==">
- <p>Draws an integer input box. The number in the define specifies how many bits used to store the variable.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_INT8</samp> / <samp>UI_INT16</samp> / <samp>UI_INT32</samp> / <samp>UI_INT64</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to the value </td></tr>
- <tr><td><samp>form->min</samp> </td><td>Minimum value </td></tr>
- <tr><td><samp>form->max</samp> </td><td>Maximum value </td></tr>
- <tr><td><samp>form->inc</samp> </td><td>Increment value </td></tr>
- <tr><td><samp>form->m</samp> </td><td>Left and right margin </td></tr></table></div>
- <h2 id="slider">Slider<a href="#slider"></a></h2>
- <img class="imgl" width="141" height="15" alt="ui_slider.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAI0AAAAPBAMAAAArCFFFAAAAElBMVEUAAAAeHh42NjZeXl79/f3///8QGCJjAAAARElEQVQ4y2NgGCGANTSUKuaEhoYGkKVREAWIAs0JFSQRCIDMEXFBBq4gc5RIBMqD0RxmY2RgCjLHmFRAzfiiUfoZJgAAtkM6ZgnR4WUAAAAASUVORK5CYII=">
- <p>Draws an integer slider box (32 bit only).</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_SLIDER</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to the int value </td></tr>
- <tr><td><samp>form->min</samp> </td><td>Minimum value </td></tr>
- <tr><td><samp>form->max</samp> </td><td>Maximum value </td></tr>
- <tr><td><samp>form->inc</samp> </td><td>Increment value </td></tr></table></div>
- <h2 id="vertical_scrollbar">Vertical Scrollbar<a href="#vertical_scrollbar"></a></h2>
- <img class="imgl" width="14" height="44" alt="ui_vscrbar.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAsBAMAAACnApTfAAAAD1BMVEUAAAAPDw8eHh5GRkZeXl4bv8Y0AAAAJklEQVQY02NgQAeCIEBF2gUIHIC0s7GxsREdaSYlIKCBfwjRqAAAzmsYlwi8KXUAAAAASUVORK5CYII=">
- <p>Draws an integer as a vertical scroll bar (32 bit only). The <a href="#containers" onclick="c('containers')">containers</a> have their own scrollbars, so
- this is only if you want to use for whatever other reason.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_VSCRBAR</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to the int value </td></tr>
- <tr><td><samp>form->max</samp> </td><td>Maximum value </td></tr></table></div>
- <h2 id="horizontal_scrollbar">Horizontal Scrollbar<a href="#horizontal_scrollbar"></a></h2>
- <img class="imgl" width="44" height="14" alt="ui_hscrbar.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAOBAMAAACmzuMPAAAAD1BMVEUAAAAPDw8eHh5GRkZeXl4bv8Y0AAAAJElEQVQY02NgIA0IgoALBDgIQgBM2NkYDIyGmjCTEgQghEkBAMWXGD2YDAi1AAAAAElFTkSuQmCC">
- <p>Draws an integer as a horizontal scroll bar (32 bit only).</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_HSCRBAR</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to the int value </td></tr>
- <tr><td><samp>form->max</samp> </td><td>Maximum value </td></tr></table></div>
- <h2 id="color">Color<a href="#color"></a></h2>
- <img class="imgl" width="96" height="24" alt="ui_color.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAAAYBAMAAAD3x+WnAAAAFVBMVEUAAAAeHh4uLi47VnJHYn5eXl7AwMBXrPqpAAAApUlEQVQ4y72U3Q3CMAyEu4IF9XvZAGUCpKzAAHm5/UfoKabGgT40FcFSVOt0Xy4/badpfN16aiGwSEfNp4BLSinn/DgJoIgCEI7ijcDkHUALOIQ+Pthwhqq+lD1AxV0OuNICNbfIYcByYTnVorZ8SspGPvdQXZaA7y4kXOkmc38DYSm/BtAC8XzDsW6A2BbjlNt9tRfnwNFXYzww/HuYnz31h3/GCjIRhZl96HmvAAAAAElFTkSuQmCC">
- <p>Draws an integer as color (32 bit only). When the users clicks on it, opens a color picker.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_COLOR</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to the int value </td></tr></table></div>
- <h2 id="file">File<a href="#file"></a></h2>
- <img class="imgl" width="161" height="20" alt="ui_file.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKEAAAAUAgMAAACYOLXjAAAADFBMVEUeHh4uLi5eXl7AwMB3Lt90AAAAzUlEQVQoz9XSwQnDMAwFUIGvAe3RU6FXgQuZoftknk4hyABZ5Q9gUL9MWlPIIbdSH5xv+8W2QuRxsonc5Vxbfi/bGNfspgw4kjbGml2O1b7hlPI6Jqe3nFQPJAzadJNwMYXG2oOW4AxQrUTZvFEWr8aFWB0CZco9oaScoQwtfOaeXEl5WwPFuzPJkFIA2zR2aW/prIcSlBmG5BFdYkgSHtV3PZCzfyTQgVsG2+9Jud9z5pc31l48nOc33koZKnrtWSwDX13+5l+6PM+15QVVEqQ1F1fd7QAAAABJRU5ErkJggg==">
- <p>Draws a text input box. The buffer should store an editable UTF-8 string, a file path. When the user clicks on it, opens a
- <a href="#path" onclick="c('path')">path</a> picker, which can be used to easily edit the string. See the description of the <samp>str</samp> parameter there. Requires including
- the <b>ui_file.h</b> module.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_FILE</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to a buffer with path </td></tr>
- <tr><td><samp>form->max</samp> </td><td>Size of the buffer </td></tr>
- <tr><td><samp>form->min</samp> </td><td>Minimum height of the path picker </td></tr>
- <tr><td><samp>form->str</samp> </td><td>Index to the localized strings array (or 0) </td></tr></table></div>
- <h2 id="path">Path<a href="#path"></a></h2>
- <img class="imgl" width="290" height="102" alt="ui_path.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASIAAABmBAMAAACdLoFLAAAAJ1BMVEUAAAAPDw8WFhYeHh4uLi4vLy9GRkZeXl5fX199fX6goKDAwMD///8lwbWUAAAGFElEQVRo3u2avY7jNhCACSiF21TpXbrSgU7WkJrg9oBDugOCfYXkAbbY1oAavYIBVVY3rUo9gQA+VDgzJEV5tRL1czkF0Sykpcjh8OP8UPZihdhlXN6G5HV4uCuxtvbTl+ny7EG8ahuvckDOw8Nd+R2J5HR58iDOO9F/jSgdIKrHiepqVaK0rqpUVkuI0tWJUu2kkahVE4jSZURpjVKlTKRbOga1pBv+aGCz5tkO40NtVNIKI4ZEOJTWtfHqIiLnAnzABQmw4qaNWk1RS5mnZsSa+Wp6MOqp4VtEpDemN2ryiBDS9JEIFzmzPzmPCSZNPSIc4ujVcjkRbpuJMEY9RLW0PuLK4uEOkR3i1lIidJLJbLNSl4gWCSHCh1quQVQbIl7iHVEtZTePeok4jxhtNSK/mDA3KEEqWdnzqB2u6laPK8/UWirXJRo49frPo3r9t0g/kfX+jyCSBFQ/ntl1HfSmTd+/0vZPI/97ovPgp/KR4Y4gUfQ2Q3yI/atYkHzZlOjvbuLrjMC/Dg0+vS2QJySaUR3noQqcY7CdvBMFEgkZR5OJ9NEj++f5BmOhb3RFpkEiohGiKD5MJYoPubbfOw8NCjsgMrrigzAPDHoYIRJziMh+3k8kOkQXJIq5EUqkDQiBzsSbiIKihva1Kv7RCG/viMiOQP+wM01D0G2M6Ko1LtcILUUcjgF5eXn5UxNRhuiF4sP1kIn8GvlE1+uB7OhgcdSYGBuoKa5jRBlt6cCWhHDh7pVvehxrDRnQ+7nI/TARUYZEaDd3eZQZIq2JmxgjilnL7C0fJPpVL07VbzIbFxN5nneIYkOUOSLnozynwQCi2BKNJdG3DDM7sgtpF8mOV4eJMtzDVKLhPJKXttYojzKBFqJQojgKI6I6w/hjQmVBJ+SBEpbyTt8eo0YKsYixGiPO7JhLM+eaHiLSZZzLS37JTCMPqX5Su+iUy3O6ZR5RayfP8JaTIjVIE9fa37Q70Xcmep7zcXjoO9Pzks/ZRCS3JE+bJPrjthGh7zB/b4roLy1fmUiphjvt74lSKIWT3XyyRxd1qJuzrjWVnXPzhh6JGjtSzCNSOBGX4PlFQz2KG2btm9dDc1C3+JioaRYTKeXNV9zHjlOelnULo6kBooI9SX7VV9GYUIQTkTuajpeoga75gMgN9RHdGuNJ1KNoq3CPFZw4N7cEbr8wlKqNk2Fkoka1Q315pOwOdasx6hNiaH2kGvdUkH9ubJC26BjdEsovpS6RtmKJ2g3MJlIut25eQXH+NzcvjwZ8tBZRo2x9KJdUoUS/2ffaO6JiRtSMdYZ4qP6bV/1eNRbNA9Gnn7X80iHSR5jiWiOT4bVW8Gmod8FElJXuPCz889cR0VFU+HnUR/RjxSdSSoU75F8h2oZsmOjzcSOybSKAO3fa33MEjZj5ZI8u6oCjs34CME8nwAs+ILrbSaf5RCc0wvNNE7hBa3O37SE8b0If0f2+lIh84eaDfQB0VGcY2g0ch4hO7Enyq75O99alXd+OEHW8RA10zRyi493zJEXb7RjCXEfbMaujZ044C9hdJk6GkYnunvv68gjHaIe6dSd1jyg8amBdxOtTAw3SFh2jXWLIR3rMEtkNLCAC61nwDcDRMAZFbS2iduNtUi0nOvlRg9A8clPfVf/Rq36vGkeqn4j0EQZca6QMxlpgrfEJSUSUle48PPnnr0MYOyGZaEtvEQDYFNH+7h8h2sxftLZNBFByp/09URIAnOzmkz26qAOks641wc6R3tAjUWlHknlEgBNxCZ6flNQD3DBrS6+H5qBu8jFRWS4mAvDmA/ex48DTsm5hNBggStiTWi8xmhDOx6pE1PESNdA1HxC5oT4iWRpPJmAsTSBKOHGkWwI3lBhKaONkLDNRCe1QXx6B3SHdgJw1IYbWR1C6p4SMob+hpIRuGbGHiMAvpS6RtuKITGMBEbjckl5Bcf6X0sujAR+tRURRM+lik2o9IphwOhnrDPFQ/dKrfq8ak3KcSB9hwAUJ5WMhjGQ254sEJqKsdOdh4p+/joiOomQkjzb1FgGATRHt7/4Rov0T27iPFv374vqy/8tsgPwDQbbPhQEgSNYAAAAASUVORK5CYII=">
- <p>Draws a path picker. The <samp>str</samp> parameter is the first index in the localized strings array of 8 strings, which must contain:
- file name, size, modification date/time, just now, N minutes ago, an hour ago, N hours ago, yesterday. Requires including the
- <b>ui_file.h</b> module.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_PATH</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to a buffer with path </td></tr>
- <tr><td><samp>form->max</samp> </td><td>Size of the buffer </td></tr>
- <tr><td><samp>form->str</samp> </td><td>Index to the localized strings array (or 0) </td></tr>
- <tr><td><samp>form->data</samp> </td><td>Pointer to an <samp>ui_path_t</samp> context </td></tr></table></div>
- <p>The <samp>ui_path_t</samp> structure looks like:</p>
- <div class="table"><table><tr><th>Field </th><th>Description </th></tr>
- <tr><td><samp>flags</samp> </td><td>Path flags </td></tr>
- <tr><td><samp>exts</samp> </td><td>Extension list (or NULL) </td></tr>
- <tr><td><samp>select</samp> </td><td>Selection okay callback (or NULL) </td></tr></table></div>
- <p>The flags are:</p>
- <div class="table"><table><tr><th>Define </th><th>Description </th></tr>
- <tr><td><samp>UI_PATH_SEARCH</samp> </td><td>Display a search field too </td></tr>
- <tr><td><samp>UI_PATH_NEWDIR</samp> </td><td>Display an add new directory button </td></tr>
- <tr><td><samp>UI_PATH_ONLYDIR</samp> </td><td>Only list directories </td></tr>
- <tr><td><samp>UI_PATH_HIDDEN</samp> </td><td>Display hidden files too </td></tr></table></div>
- <p>The extension list is a zero terminated string list, and the whole string is terminated by two null bytes, for example
- <samp>png\0jpg\0\0</samp>. If given, then only files with extensions listed here are shown.</p>
- <p>If the <samp>select</samp> callback is NULL, then simply sub-directories are entered, and files are returned. If it's given with</p>
- <div class="pre"><pre class="lineno">1<br></pre><code><span class="hl_t">typedef</span> <span class="hl_t">int</span> (<span class="hl_o">*</span><span class="hl_f">ui_form_select</span>)(<span class="hl_t">char</span> <span class="hl_o">*</span><span class="hl_v">path</span>, <span class="hl_t">int</span> <span class="hl_v">isdir</span>);</code></div>
- <p>then it's supposed to return 1 if the selected path should be returned, or 0 if not. If 0 returned, then sub-directories are
- entered and nothing happens with files. The <samp>path</samp> argument ends in a directory separator if it's a directory and then <samp>isdir</samp>
- is 1. This can be used to add a further criteria to selecting a path, like a directory containing a certain file or a file
- starting with a certain magic or not. The callback might implement whatever additional checks it wants.</p><br style="clear:both;"><label class="btn prev" accesskey="p" for="_labels" title="Labels">Previous</label><label class="btn next" accesskey="n" for="_buttons" title="Buttons">Next</label></div>
- <div class="page" rel="buttons"><div><ul class="breadcrumbs"><li><label class="home" for="_" title="Home"></label> »</li><li> Buttons</li></ul><hr></div>
- <h1 id="buttons">Buttons<a href="#buttons"></a></h1>
- <h2 id="toggle">Toggle<a href="#toggle"></a></h2>
- <img class="imgl" width="64" height="40" alt="ui_toggle.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAAoAQMAAAB0AG6qAAAABlBMVEUAAAD///+l2Z/dAAAAgUlEQVQY02NgIA8wPnBgYOBhYGBmOHCAgUEGyGgAMWyAjAOHP/x4A5J6cOBgzz8Q48CBg3+u8YDVHGy4BtEFYTAwHLjZA2YwPij4ccyegYES99iBDQQ6IxnGYGZgYP8Acg8biAFzzwOQeySAmg6AnGEAVAt2WALMPckw99QzUAsAAFZbPk+0LEdkAAAAAElFTkSuQmCC">
- <p>This is a special field, should be followed by a <a href="#containers" onclick="c('containers')">container field</a>, and it controls that container's visibility.
- If by any chance the next field isn't a container, then <samp>form->value</samp> is an index to the form passed to <samp>ui_event()</samp>.
- If <samp>form->label</samp> is 0, then <samp>form->ptr</samp> should point to a zero terminated UTF-8 string, displayed as label. Normally before
- that there's a right or down triangle, but with <samp>UI_NOBULLET</samp> there's no triangle rather the label is displayed with a different
- color (see <a href="#color_theme" onclick="c('color_theme')">color theme</a>, this is to provide menu toggles).</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_TOGGLE</samp> </td></tr>
- <tr><td><samp>form->flags</samp> </td><td>Might want <samp>UI_NOBULLET</samp> </td></tr>
- <tr><td><samp>form->label</samp> </td><td>Index to the localized strings array (or 0) </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Only if <samp>label</samp> is 0, pointer to a string </td></tr>
- <tr><td><samp>form->value</samp> </td><td>Only if next field isn't a container, <samp>ui_event()</samp> form's index </td></tr></table></div>
- <h2 id="checkbox">Checkbox<a href="#checkbox"></a></h2>
- <img class="imgl" width="64" height="40" alt="ui_check.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAAoBAMAAAC84OHaAAAAD1BMVEUAAAAeHh42NjZeXl7///8gMbKdAAAAoUlEQVQ4y92SwQ3DIAxFHckDlBVcNugCVvT3n6lOMK1pcA49Yikgw9MPJI9orQJs0LjCrdtKKQ9veQDggIg8ZwB3oEp1gIFzsCfgm+x7TLBtNQgBqMMrbE9ZFTcJxxyB7xkSYLgF2hkiQC+r/qH6LfTgAKXl6uIDnys3PsDb1Ae6Aj8+EKZGTXyQxIcWMEnw390PlAIekPvwych8wJI+/FtvnbYxa3C+9qYAAAAASUVORK5CYII=">
- <p>Draws a checkbox with label. The pointed value tells if it's checked. When clicked, int <samp>value</samp> is XOR'd at that address.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_CHECK</samp> </td></tr>
- <tr><td><samp>form->flags</samp> </td><td>Might want <samp>UI_NOBULLET</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to the int value </td></tr>
- <tr><td><samp>form->value</samp> </td><td>Bitmask for this button </td></tr>
- <tr><td><samp>form->label</samp> </td><td>Index to the localized strings array </td></tr></table></div>
- <h2 id="radiobutton">Radiobutton<a href="#radiobutton"></a></h2>
- <img class="imgl" width="64" height="40" alt="ui_radio.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAAoBAMAAAC84OHaAAAAD1BMVEUAAAAeHh42NjZeXl7///8gMbKdAAAApklEQVQ4y92SwQ2DMAxFHdUDlI5gOkBVFrCqv/9MdUOcBog5cIylRPzwZJnwiMYqwDZtT7ikNE0eeQOgpIfIvQdwAZLgM68AA3mz1eDpCcxNB3utBiEGrA2rngD5uQX+M/QBeou8KoB1hg1wW5Z6Uf4V+uMApeHq4APnkxMf4DHywWMSkb4PBNoBgQ97oPrgMx46lN9dpY4A+KyRD7VH5AOG9OFqfQG2UjEf5ieLywAAAABJRU5ErkJggg==">
- <p>Draws a radiobutton with label. The pointed value tells if it's checked. When clicked, int <samp>value</samp> is stored at that address.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_RADIO</samp> </td></tr>
- <tr><td><samp>form->flags</samp> </td><td>Might want <samp>UI_NOBULLET</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to the int value </td></tr>
- <tr><td><samp>form->value</samp> </td><td>Int value for this button </td></tr>
- <tr><td><samp>form->label</samp> </td><td>Index to the localized strings array </td></tr></table></div>
- <h2 id="button">Button<a href="#button"></a></h2>
- <img class="imgl" width="62" height="57" alt="ui_button.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAAA5BAMAAACc6oXPAAAAGFBMVEUAAAAPDw8eHh4fHx82NjZGRkZeXl5fX18xIiCsAAABGUlEQVQ4y83UwWrDMAwG4H8Qo2vWw85jT2KGWa5m4Oa6U8852Oj1J7lNsJO4DEZDBVadfLFRwTLw6Hh5bYf626UZP716aMb3UQ5IMiV5U7qnJKN0UO2hdr9xDxhNMnTvabN+Ig7gycg3uO222V8eyRMhtZyZ73rS35U75yzpgEO0nRWP+Y37nB3QRNECbGmATrrCB46anGOZsBskMRfeiKfw/qMd/R/O96P759Qu713rO7X/39ezeD4/XSE2v1nc0u3EzSGN0FXuah+iPl59t7+kFUI4F77pr7Tyur90+Y7P/ZWX7/jcX3n52iHuzdWTFrl4vn9ASWqT/Udx6AWy+MhJUwgsEw5jGqWQwhtxiPft+/1yRP/8L34BaxtPbQtIP+UAAAAASUVORK5CYII=">
- <p>Draws a button. The pointed value tells if it's pressed. When clicked, int <samp>value</samp> is stored at that address. Might have
- an icon, a localized string, or both. When using skins, buttons might have a shadow which misaligns the button title
- vertically. If that happens, set the top margin in <samp>m</samp> (which could be negative as well).</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_BUTTON</samp> </td></tr>
- <tr><td><samp>form->flags</samp> </td><td>Might want <samp>UI_NOBORDER</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to the int value </td></tr>
- <tr><td><samp>form->value</samp> </td><td>Int value for this button </td></tr>
- <tr><td><samp>form->label</samp> </td><td>Index to the localized strings array </td></tr>
- <tr><td><samp>form->icon</samp> </td><td>Pointer to an <samp>ui_image_t</samp> struct </td></tr>
- <tr><td><samp>form->m</samp> </td><td>Top margin if skinned </td></tr></table></div>
- <h2 id="button_toggle">Button Toggle<a href="#button_toggle"></a></h2>
- <img class="imgl" width="62" height="57" alt="ui_button.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAAA5BAMAAACc6oXPAAAAGFBMVEUAAAAPDw8eHh4fHx82NjZGRkZeXl5fX18xIiCsAAABGUlEQVQ4y83UwWrDMAwG4H8Qo2vWw85jT2KGWa5m4Oa6U8852Oj1J7lNsJO4DEZDBVadfLFRwTLw6Hh5bYf626UZP716aMb3UQ5IMiV5U7qnJKN0UO2hdr9xDxhNMnTvabN+Ig7gycg3uO222V8eyRMhtZyZ73rS35U75yzpgEO0nRWP+Y37nB3QRNECbGmATrrCB46anGOZsBskMRfeiKfw/qMd/R/O96P759Qu713rO7X/39ezeD4/XSE2v1nc0u3EzSGN0FXuah+iPl59t7+kFUI4F77pr7Tyur90+Y7P/ZWX7/jcX3n52iHuzdWTFrl4vn9ASWqT/Udx6AWy+MhJUwgsEw5jGqWQwhtxiPft+/1yRP/8L34BaxtPbQtIP+UAAAAASUVORK5CYII=">
- <p>Draws a button which acts like a <a href="#toggle" onclick="c('toggle')">toggle</a>. When clicked, toggles the pointed <a href="#containers" onclick="c('containers')">container field</a>'s visibility.
- If <samp>ptr</samp> is NULL, then <samp>form->value</samp> is an index to the form passed to <samp>ui_event()</samp>.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_BTNTGL</samp> </td></tr>
- <tr><td><samp>form->flags</samp> </td><td>Might want <samp>UI_NOBORDER</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to an <samp>ui_form_t</samp> container field </td></tr>
- <tr><td><samp>form->value</samp> </td><td>Only if <samp>ptr</samp> is NULL, <samp>ui_event()</samp> form's index </td></tr>
- <tr><td><samp>form->label</samp> </td><td>Index to the localized strings array </td></tr>
- <tr><td><samp>form->icon</samp> </td><td>Pointer to an <samp>ui_image_t</samp> struct </td></tr>
- <tr><td><samp>form->m</samp> </td><td>Top margin if skinned </td></tr></table></div>
- <h2 id="button_icon">Button Icon<a href="#button_icon"></a></h2>
- <img class="imgl" width="23" height="24" alt="ui_image.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAAYCAMAAAAmopZHAAAC/VBMVEUAAAAFAAAAAgAVBQAQBwAUDQMjEQApEwAqFAArFAAnFgguFwAuGwApHAcxHQA4HwMxIgJAJgZBJwdELxpIOSF/RgCBRwB8SRGMSwCUVxyaVw2cWAOYWg2ZWw+aXAOaXBChXQmEYz2fYACTZhKiYwCTZDakZAGlZQKmZgSsZQmnZwWqagu3aQCobQurayGhbiaobimicwupbyqjdA2bdFqqdSafdlfIcQCbe0Cxexu8fQjJeBvPdxPReASLhH7LehLSeQbOfAShgnDPfQbHfS+6gyzEhAK1iRvRfyzdggXPgy3egwfEhzq1jx/ghAnhhQDCjgnDjwDShjjHjQ7GiUOoj3vLkACfko3hiwDijADeiiezmCXniwHojAPjjRTZjT7mjwO8myDjkgPJmgnLmwvOngDcmRjanASsnpndmhnRoADwlwDrmgDunAHQpQXloADknxLvnQTloBTwngfmoRbzoADyoAvuogrpoxn/nwLLrR7KrSnwpCvupw+zrabOsCLzphP1pwDoqR39oxi8rKH1pxXpqh/Isj74pS/5qwburhbYtDTrsRf8rQ3srkn9rxD/sBPmtEL6shH8sxP9sED+tRfquE7FvK/+vB3Ewcb/vR//vCv/viH9wS7Nxr//xCb9xiXRycLrzyL/ySn/yTX9zCru0ifUzcX/zzj/0C7/0Dn80i390yH/0Ev/0U3+1DD/1ST22SL91EX81E361zHc1M382DL92Sf/1k/92TP/2ij63Cf/11n/2yr+12D83ir/3EL+3FP+3Fvi29T/4S/Z3uH93mvj3dzb3+Ld39zc4OP05lb+41f941/+5zP151je4+X95G/851H/6TX/6UD86zX87EH96WP+7Tfq5eT77FT96mz96nP87VX/6YH+7k388kX+8Gj97ov/8Wn782H98Jr99WP79nP893T793v+9ZD++G36+Ir8+IP/9pH/+W7/9az796X/9qb/+Jn8+Kb9+af/+aH8+a78+rX7+739+7b6/MP9+9H9/Nj+/dnCdRsJAAAB3UlEQVQoz2Ngwg4YoDSrgMW0idMsBFhRxZVTVtz7+OHjo3Upykji/H0rnv75++/v379/Pq3o44eKM/JVHPry49fP379///zx4/uxfB5GsLhIzdpX7z5//vb169dvnz+/e7WvRgQkzqg3++Kd5y/fvn375u3bly+f374zW48RKM47ZfPZ6w9fv3/x8uXLF+8fP7x+dk8HF1Ccs3nTjjO3znc/efbs2d3285fOHNxcyQkUN+pdsunAFUOx6gcP7kdL+F47sGnJBAOguGPv3JXbjhgqVd84dzVRxf3c+pVzex2B4g69sxas3LWoaveRI0c21i/btXLBrF5boLht44z5i9ds2LVr134g3rBm8fxZnQ5AcfPSqU09q7dt2wkE2zZsW9rVNrXUHCjukj3ZNdzMMjArLy8vNcDUxC54UqE1UFwwpjNs5olTF5bPmzdv+YUTJ+rSG2IFgeLMOjm1qqEtCw8fv3ly6/QMJ/3enCg2UPiIepanySlIy8rKy0pJq2mUFHpLQsLZI7IwTUlDW0MDiNWKCuO8hCHhzGkTkVtkpauhpKHr1pobZ8/JCI0XznjvpNyyooKissIk7yBueHwxMolrevsnJMT6e2uKA3lI8c7CqRjiE6LIyYKWHtABAHI8zlZkUGOOAAAAAElFTkSuQmCC">
- <p>Draws an icon if value is checked, otherwise nothing. When clicked, int <samp>value</samp> is XOR'd at that address. Acts as a <a href="#checkbox" onclick="c('checkbox')">checkbox</a>.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_BTNICN</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to the int value </td></tr>
- <tr><td><samp>form->value</samp> </td><td>Bitmask for this button </td></tr>
- <tr><td><samp>form->icon</samp> </td><td>Pointer to an <samp>ui_image_t</samp> struct </td></tr></table></div><br style="clear:both;"><label class="btn prev" accesskey="p" for="_inputs" title="Inputs">Previous</label><label class="btn next" accesskey="n" for="_lines" title="Lines">Next</label></div>
- <div class="page" rel="lines"><div><ul class="breadcrumbs"><li><label class="home" for="_" title="Home"></label> »</li><li> Lines</li></ul><hr></div>
- <h1 id="lines">Lines<a href="#lines"></a></h1>
- <h2 id="polyline">Polyline<a href="#polyline"></a></h2>
- <img class="imgl" width="114" height="38" alt="ui_lines.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHIAAAAmCAMAAAAvHD+uAAABAlBMVEUAAAACAgIHBwcLCwsSEhIUFBQWFhYYGBgbGxsgICAiIiIjIyMmJiYqKiosLCwuLi4wMDAxMTE0NDQ2NjY4ODhDQ0NERERFRUVISEhLS0tMTExOTk5PT09VVVVWVlZbW1tcXFxgYGBkZGRlZWVnZ2doaGhqamptbW1vb29ycnJ0dHR6enp+fn6AgICCgoKIiIiLi4uMjIySkpKYmJiZmZmampqbm5ucnJyioqKmpqanp6eqqqqurq6wsLCysrK0tLS2tra3t7e5ubm6urrAwMDDw8PLy8vMzMzNzc3Q0NDT09PU1NTX19fa2trh4eHl5eXm5ubn5+fr6+v19fX9/f3+/v4m0jMJAAABnElEQVRYw+2X127CMBSGQ4GwygirZoe9wgh7bwg7jPr9X6VAZagqII0wvqj4b/Lbx9Inn5zjOBT10kv/Wgq2BYVyxEqK58iOYIt9s0bKAgQkgFk4yjrQAECefjYwuqlof45pXsZG9SBe6K2gLKB32rX9ngNQYp9qxhXmSh1BhKteIQ70coC27tR7ZZrnTw+lxmC2O9z+YCzF5QrVens4ni7Xuz0UhU6JC7sYteyUaiub6NUADT8O9bTfrZfT8bBdrxZyXCoW9LsddrNBo3zgJaZh9kYEfAqXesInz7yhux451E8vgh+oa8w9N4E8HSljJ6Zh+lZOT21pFYjl9ED87klIk8nphYjaBI/AzZweNwfObYKTeOc0U4vIqbZkiBRzrhrTjAyRcnWQcw4wES0S34hwCblADRNyErof5zjkknk8xGJRYkEpjFw+iYUYmkit6LiQqwXwlI5FaonAIDdwPr9YTxLP39yZiQzxcvhQWxUZ4mFVi1UcTeKx887oyzQXf7y0He/PLZbp998fIcJFM+Mzyru1J14/Ly+R1hf+3jchTRgY+QAAAABJRU5ErkJggg==">
- <p>Draws a series of anti-aliased lines. <samp>form->ptr</samp> must point to an array of int16_t (short int) values, multiple <samp>x</samp> and <samp>y</samp>
- pairs, and the last pair must be 0,0.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_LINES</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to the int16_t array </td></tr>
- <tr><td><samp>form->value</samp> </td><td>32 bit RGBA color </td></tr></table></div>
- <h2 id="horizontal_connect">Horizontal Connect<a href="#horizontal_connect"></a></h2>
- <img class="imgl" width="64" height="38" alt="ui_hconnect.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAAmAgMAAAAJqnUKAAAACVBMVEUAAABISEj+/v45K09pAAAAT0lEQVQoz2NgIB1wrVq1agG6oNYSdBGpBnSRFRgmYSjBMFcDXYADwxB0ASb6CDigCTBieIY+AhhBpkAwDDGDDDM+MZRgxt4KolKGAOEUBQBwag++OdOl7wAAAABJRU5ErkJggg==">
- <p>Connects two points horizontally with a curve. <samp>form->ptr</samp> must point to an array of exactly 4 int16_t values,
- <samp>x0</samp> and <samp>y0</samp> starting point, <samp>x1</samp> and <samp>y1</samp> end point pair.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_HCONNECT</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to int16_t array with 4 elements </td></tr>
- <tr><td><samp>form->value</samp> </td><td>32 bit RGBA color </td></tr></table></div>
- <h2 id="vertical_connect">Vertical Connect<a href="#vertical_connect"></a></h2>
- <img class="imgl" width="64" height="38" alt="ui_vconnect.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAAmAgMAAAAJqnUKAAAACVBMVEUAAABISEj+/v45K09pAAAARklEQVQoz2NgIAg46CLAhS7AhCHQgC6yAF1Ag7CpE9BFsjCUrMIUAQIHNEFGkCCGkzBFVqILsFHFHxiGEDZVgS4CAgykAwCF0g7pSVnJ/AAAAABJRU5ErkJggg==">
- <p>Connects two points vertically with a curve. <samp>form->ptr</samp> must point to an array of exactly 4 int16_t values,
- <samp>x0</samp> and <samp>y0</samp> starting point, <samp>x1</samp> and <samp>y1</samp> end point pair.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_VCONNECT</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to int16_t array with 4 elements </td></tr>
- <tr><td><samp>form->value</samp> </td><td>32 bit RGBA color </td></tr></table></div>
- <h2 id="bezier_curve">Bezier Curve<a href="#bezier_curve"></a></h2>
- <img class="imgl" width="64" height="38" alt="ui_curve.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAAmAgMAAAAJqnUKAAAACVBMVEUAAABISEj+/v45K09pAAAAYElEQVQoz2NgIB1wrQIBdFGmVQ3oQiswdDqgCTBi6EEXYMIQwDAUXSAD3ZIJhJyhgW7HAlLtYEK3QwpdxxJCHsOwQwJdQAVdQIF0AQ2M4MOIAmKidtUqjKhcBQENZKQoAIH/FUTePN+ZAAAAAElFTkSuQmCC">
- <p>Draws an arbitrary Bezier curve. <samp>form->ptr</samp> must point to an array of exactly 8 int16_t values, <samp>x0</samp> and <samp>y0</samp>
- starting point, <samp>x1</samp> and <samp>y1</samp> end point, <samp>cx0</samp> and <samp>cy0</samp> first control point, <samp>cx1</samp> and <samp>cy1</samp> second control
- point's coordinate pair.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_CURVE</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to int16_t array with 8 elements </td></tr>
- <tr><td><samp>form->value</samp> </td><td>32 bit RGBA color </td></tr></table></div><br style="clear:both;"><label class="btn prev" accesskey="p" for="_buttons" title="Buttons">Previous</label><label class="btn next" accesskey="n" for="_custom" title="Custom">Next</label></div>
- <div class="page" rel="custom"><div><ul class="breadcrumbs"><li><label class="home" for="_" title="Home"></label> »</li><li> Custom</li></ul><hr></div>
- <h1 id="custom">Custom<a href="#custom"></a></h1>
- <p>User specified custom widgets can be added as well, it only needs 4 hooks per kind.</p>
- <div class="table"><table><tr><th>Parameter </th><th>Description </th></tr>
- <tr><td><samp>form->type</samp> </td><td><samp>UI_CUSTOM</samp> </td></tr>
- <tr><td><samp>form->flags</samp> </td><td>You must respect <samp>UI_HIDDEN</samp> and <samp>UI_DISABLED</samp> </td></tr>
- <tr><td><samp>form->ptr</samp> </td><td>Pointer to an arbitrary data buffer </td></tr>
- <tr><td><samp>form->data</samp> </td><td>Pointer to an arbitrary data context </td></tr>
- <tr><td><samp>form->str</samp> </td><td>Index to the localized strings array (or 0) </td></tr>
- <tr><td><samp>form->bbox</samp> </td><td>Pointer to a bounding box callback </td></tr>
- <tr><td><samp>form->view</samp> </td><td>Pointer to a renderer callback </td></tr>
- <tr><td><samp>form->ctrl</samp> </td><td>Pointer to an event handler callback </td></tr>
- <tr><td><samp>form->fini</samp> </td><td>Pointer to an optional finish callback </td></tr></table></div>
- <h2 id="bounding">Bounding<a href="#bounding"></a></h2>
- <div class="pre"><pre class="lineno">1<br>2<br></pre><code><span class="hl_t">typedef</span> <span class="hl_t">int</span> (<span class="hl_o">*</span><span class="hl_f">ui_bbox</span>)(<span class="hl_v">ui_t</span> <span class="hl_o">*</span><span class="hl_v">ctx</span>, <span class="hl_t">int</span> <span class="hl_v">x</span>, <span class="hl_t">int</span> <span class="hl_v">y</span>, <span class="hl_t">int</span> <span class="hl_v">w</span>, <span class="hl_t">int</span> <span class="hl_v">h</span>,
- <span class="hl_v">ui_form_t</span> <span class="hl_o">*</span><span class="hl_v">form</span>, <span class="hl_t">int</span> <span class="hl_o">*</span><span class="hl_v">dw</span>, <span class="hl_t">int</span> <span class="hl_o">*</span><span class="hl_v">dh</span>);</code></div>
- <p>This function receives the calculated area <samp>x</samp>, <samp>y</samp>, <samp>w</samp>, <samp>h</samp> where the widget should be located, the form element in <samp>form</samp>,
- and must return the destination width in <samp>dw</samp> and destination height in <samp>dh</samp>.</p>
- <h2 id="view">View<a href="#view"></a></h2>
- <div class="pre"><pre class="lineno">1<br>2<br></pre><code><span class="hl_t">typedef</span> <span class="hl_t">int</span> (<span class="hl_o">*</span><span class="hl_f">ui_view</span>)(<span class="hl_v">ui_t</span> <span class="hl_o">*</span><span class="hl_v">ctx</span>, <span class="hl_t">int</span> <span class="hl_v">x</span>, <span class="hl_t">int</span> <span class="hl_v">y</span>, <span class="hl_t">int</span> <span class="hl_v">w</span>, <span class="hl_t">int</span> <span class="hl_v">h</span>,
- <span class="hl_v">ui_form_t</span> <span class="hl_o">*</span><span class="hl_v">form</span>);</code></div>
- <p>This function receives the effective area <samp>x</samp>, <samp>y</samp>, <samp>w</samp>, <samp>h</samp> where the widget is located, the form element in <samp>form</samp>, and should
- render the widget there. It might use the low level functions like <samp>_ui_line()</samp>, <samp>_ui_cbez()</samp>, <samp>_ui_rect()</samp>, <samp>_ui_blit()</samp> etc.,
- or might directly set pixels on the <samp>ctx->screen</samp> <a href="#image" onclick="c('image')">image</a>. It is very important that it <i><b>must not</b></i> draw outside of the
- designated area.</p>
- <h2 id="controller">Controller<a href="#controller"></a></h2>
- <div class="pre"><pre class="lineno">1<br>2<br></pre><code><span class="hl_t">typedef</span> <span class="hl_t">int</span> (<span class="hl_o">*</span><span class="hl_f">ui_ctrl</span>)(<span class="hl_v">ui_t</span> <span class="hl_o">*</span><span class="hl_v">ctx</span>, <span class="hl_t">int</span> <span class="hl_v">x</span>, <span class="hl_t">int</span> <span class="hl_v">y</span>, <span class="hl_t">int</span> <span class="hl_v">w</span>, <span class="hl_t">int</span> <span class="hl_v">h</span>,
- <span class="hl_v">ui_form_t</span> <span class="hl_o">*</span><span class="hl_v">form</span>, <span class="hl_v">ui_event_t</span> <span class="hl_o">*</span><span class="hl_v">evt</span>);</code></div>
- <p>This function receives the effective area <samp>x</samp>, <samp>y</samp>, <samp>w</samp>, <samp>h</samp> where the widget is located, the form element in <samp>form</samp>, and
- the current event in <samp>evt</samp> for <a href="#event_handling" onclick="c('event_handling')">event handling</a>. This hook is only called if the <samp>form</samp> isn't <samp>UI_HIDDEN</samp> nor <samp>UI_DISABLED</samp>,
- and the mouse is over the widget.</p>
- <h2 id="destructor">Destructor<a href="#destructor"></a></h2>
- <div class="pre"><pre class="lineno">1<br></pre><code><span class="hl_t">typedef</span> <span class="hl_t">int</span> (<span class="hl_o">*</span><span class="hl_f">ui_fini</span>)(<span class="hl_v">ui_t</span> <span class="hl_o">*</span><span class="hl_v">ctx</span>, <span class="hl_v">ui_form_t</span> <span class="hl_o">*</span><span class="hl_v">form</span>);</code></div>
- <p>This optional hook is needed if the widget allocates extra memory. It is expected to be called multiple times, so it must
- not double free those buffers.</p><br style="clear:both;"><label class="btn prev" accesskey="p" for="_lines" title="Lines">Previous</label><label class="btn next" accesskey="n" for="_example" title="Example">Next</label></div>
- <div class="page" rel="example"><div><ul class="breadcrumbs"><li><label class="home" for="_" title="Home"></label> »</li><li> Example</li></ul><hr></div>
- <h1 id="example">Example<a href="#example"></a></h1>
- <div class="pre"><pre class="lineno">1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br>31<br>32<br>33<br>34<br>35<br>36<br>37<br>38<br>39<br>40<br>41<br>42<br>43<br>44<br>45<br>46<br>47<br>48<br>49<br>50<br>51<br>52<br>53<br>54<br>55<br>56<br>57<br></pre><code><span class="hl_p">#define UI_IMPLEMENTATION</span>
- <span class="hl_p">#include <ui.h></span>
- <span class="hl_t">int</span> <span class="hl_f">main</span>(<span class="hl_t">int</span> <span class="hl_v">argc</span>, <span class="hl_t">char</span> <span class="hl_o">**</span><span class="hl_v">argv</span>)
- {
- <span class="hl_c">/* localized strings array */</span>
- <span class="hl_t">enum</span> { <span class="hl_v">WINDOW_TITLE</span>, <span class="hl_v">POPUP_TITLE</span>, <span class="hl_v">BUTTON_TITLE</span>,
- <span class="hl_v">EASY_TITLE</span>, <span class="hl_v">HARD_TITLE</span>, <span class="hl_v">VOLUME_TITLE</span> };
- <span class="hl_t">char</span> <span class="hl_o">*</span><span class="hl_v">lang</span>[] <span class="hl_o">=</span> { <span class="hl_s">"Basic demo"</span>, <span class="hl_s">"Show"</span>, <span class="hl_s">"Button"</span>,
- <span class="hl_s">"easy"</span>, <span class="hl_s">"hard"</span>, <span class="hl_s">"Volume:"</span> };
- <span class="hl_c">/* variables to store game states */</span>
- <span class="hl_t">int</span> <span class="hl_v">button</span> <span class="hl_o">=</span> <span class="hl_n">0</span>, <span class="hl_v">difficulty</span> <span class="hl_o">=</span> <span class="hl_n">0</span>, <span class="hl_v">volume</span> <span class="hl_o">=</span> <span class="hl_n">25</span>;
- <span class="hl_c">/* form referencing those variables, you use a HTML flow like layout */</span>
- <span class="hl_v">ui_t</span> <span class="hl_v">ctx</span>;
- <span class="hl_v">ui_form_t</span> <span class="hl_v">popup</span>[] <span class="hl_o">=</span> {
- { <span class="hl_o">.</span><span class="hl_v">type</span> <span class="hl_o">=</span> <span class="hl_v">UI_BUTTON</span>, <span class="hl_o">.</span><span class="hl_v">flags</span> <span class="hl_o">=</span> <span class="hl_v">UI_FORCEBR</span>,
- <span class="hl_o">.</span><span class="hl_v">ptr</span> <span class="hl_o">=</span> <span class="hl_o">&</span><span class="hl_v">button</span>, <span class="hl_o">.</span><span class="hl_v">value</span> <span class="hl_o">=</span> <span class="hl_n">1</span>,
- <span class="hl_o">.</span><span class="hl_v">label</span> <span class="hl_o">=</span> <span class="hl_v">BUTTON_TITLE</span> },
- { <span class="hl_o">.</span><span class="hl_v">type</span> <span class="hl_o">=</span> <span class="hl_v">UI_RADIO</span>, <span class="hl_o">.</span><span class="hl_v">flags</span> <span class="hl_o">=</span> <span class="hl_v">UI_NOBR</span>,
- <span class="hl_o">.</span><span class="hl_v">ptr</span> <span class="hl_o">=</span> <span class="hl_o">&</span><span class="hl_v">difficulty</span>, <span class="hl_o">.</span><span class="hl_v">value</span> <span class="hl_o">=</span> <span class="hl_n">0</span>,
- <span class="hl_o">.</span><span class="hl_v">y</span> <span class="hl_o">=</span> <span class="hl_n">5</span>, <span class="hl_o">.</span><span class="hl_v">label</span> <span class="hl_o">=</span> <span class="hl_v">EASY_TITLE</span> },
- { <span class="hl_o">.</span><span class="hl_v">type</span> <span class="hl_o">=</span> <span class="hl_v">UI_RADIO</span>, <span class="hl_o">.</span><span class="hl_v">flags</span> <span class="hl_o">=</span> <span class="hl_v">UI_FORCEBR</span>,
- <span class="hl_o">.</span><span class="hl_v">ptr</span> <span class="hl_o">=</span> <span class="hl_o">&</span><span class="hl_v">difficulty</span>, <span class="hl_o">.</span><span class="hl_v">value</span> <span class="hl_o">=</span> <span class="hl_n">1</span>,
- <span class="hl_o">.</span><span class="hl_v">x</span> <span class="hl_o">=</span> <span class="hl_n">20</span>, <span class="hl_o">.</span><span class="hl_v">label</span> <span class="hl_o">=</span> <span class="hl_v">HARD_TITLE</span> },
- { <span class="hl_o">.</span><span class="hl_v">type</span> <span class="hl_o">=</span> <span class="hl_v">UI_LABEL</span>, <span class="hl_o">.</span><span class="hl_v">flags</span> <span class="hl_o">=</span> <span class="hl_v">UI_NOBR</span>,
- <span class="hl_o">.</span><span class="hl_v">y</span> <span class="hl_o">=</span> <span class="hl_n">5</span>, <span class="hl_o">.</span><span class="hl_v">label</span> <span class="hl_o">=</span> <span class="hl_v">VOLUME_TITLE</span> },
- { <span class="hl_o">.</span><span class="hl_v">type</span> <span class="hl_o">=</span> <span class="hl_v">UI_SLIDER</span>, <span class="hl_o">.</span><span class="hl_v">ptr</span> <span class="hl_o">=</span> <span class="hl_o">&</span><span class="hl_v">volume</span>, <span class="hl_o">.</span><span class="hl_v">max</span> <span class="hl_o">=</span> <span class="hl_n">100</span> },
- { <span class="hl_o">.</span><span class="hl_v">type</span> <span class="hl_o">=</span> <span class="hl_v">UI_END</span> }
- };
- <span class="hl_v">ui_form_t</span> <span class="hl_v">form</span>[] <span class="hl_o">=</span> {
- { <span class="hl_o">.</span><span class="hl_v">type</span> <span class="hl_o">=</span> <span class="hl_v">UI_POPUP</span>, <span class="hl_o">.</span><span class="hl_v">align</span> <span class="hl_o">=</span> <span class="hl_v">UI_CENTER</span> <span class="hl_o">|</span> <span class="hl_v">UI_MIDDLE</span>,
- <span class="hl_o">.</span><span class="hl_v">ptr</span> <span class="hl_o">=</span> <span class="hl_o">&</span><span class="hl_v">popup</span>,
- <span class="hl_o">.</span><span class="hl_v">x</span> <span class="hl_o">=</span> <span class="hl_f">UI_PERCENT</span>(<span class="hl_n">50</span>), <span class="hl_o">.</span><span class="hl_v">y</span> <span class="hl_o">=</span> <span class="hl_f">UI_PERCENT</span>(<span class="hl_n">50</span>),
- <span class="hl_o">.</span><span class="hl_v">m</span> <span class="hl_o">=</span> <span class="hl_n">10</span>, <span class="hl_o">.</span><span class="hl_v">label</span> <span class="hl_o">=</span> <span class="hl_v">POPUP_TITLE</span> },
- { <span class="hl_o">.</span><span class="hl_v">type</span> <span class="hl_o">=</span> <span class="hl_v">UI_END</span> }
- };
- <span class="hl_c">/* initialize the UI context */</span>
- <span class="hl_f">ui_init</span>(<span class="hl_o">&</span><span class="hl_v">ctx</span>, <span class="hl_k">sizeof</span>(<span class="hl_v">lang</span>)<span class="hl_o">/</span><span class="hl_k">sizeof</span>(<span class="hl_v">lang</span>[<span class="hl_n">0</span>]), <span class="hl_v">lang</span>, <span class="hl_n">640</span>, <span class="hl_n">480</span>, <span class="hl_t">NULL</span>);
- <span class="hl_c">/* wait until user closes the window */</span>
- <span class="hl_k">while</span>(<span class="hl_f">ui_event</span>(<span class="hl_o">&</span><span class="hl_v">ctx</span>, <span class="hl_v">form</span>)) {
- <span class="hl_c">/* handle button, you can do this from another thread if you want */</span>
- <span class="hl_k">if</span>(<span class="hl_v">button</span>) {
- <span class="hl_f">printf</span>(<span class="hl_s">"button clicked\n"</span>);
- <span class="hl_v">button</span> <span class="hl_o">=</span> <span class="hl_n">0</span>;
- <span class="hl_f">ui_refresh</span>(<span class="hl_o">&</span><span class="hl_v">ctx</span>);
- }
- }
- <span class="hl_c">/* destroy window, free resources */</span>
- <span class="hl_f">ui_free</span>(<span class="hl_o">&</span><span class="hl_v">ctx</span>);
- <span class="hl_k">return</span> <span class="hl_n">0</span>;
- }</code></div>
- <p><img class="imgl" width="191" height="114" alt="example.png" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAL8AAAByCAYAAAACnABsAAAE70lEQVR42u2dsW6rMBRAnafsmdno2CkVQ9cwsfYPSNUv6fuRSvxGt3ZLB1SytFuzNSP5gr6lznMdA4ZAQu1zpEjBGELM8eWaBneSpumXAHCczWYjnp+fJ2rZVK4AcJmyLA/K/tAs4CvID94y1QuiKDqolOe5cb1aDvALuK+M/FLsPM/3L4QH0h4Al9OePM9FFEUiiqJ9hG+K9OrVokv61FQGcLLIr6Y6JoF1wU2pkU36BDDKtMdW2L4iNJ0CRpfzE7HBG/ltUh0ALyL/KZCdjU4HZ5VfH+zW3ZGxTZeq9mPzHmBIJmmafvHDNnCdsizFer3+O6q0B8DbnB8A+QGQHwD5AZAfAPkBkB8A+QGQHwD5AZAfAPkBjEzbVC6KwstGms/nmOKz/EVRiJubG+8aaLvditVqRQfwPfJLGXzi/f0dS8j5AZAfwM+0R+Xx8dFYniTJUfts2t6mDsCgkV8VcLlciuVyWdspbDtTEARH1QE4edrz+fm5f4+c4HTa0yaay6uEvmy6UmRZ1qlO1VXHtJ8kSX7UJY1C/s5IGWUKpBMEwcGVQS4nSSKCINjvQ92+TR0ps7ouy7IfYwQpvSyT+2QcQdrTGTXnz7Lsh+htUya5bCprqlO1zpSGmTokID85PyA/ADn/N6b/Z1q1ru2yaeB6fX3dqY5p3zZldccERP49Ly8vPwaWclkdcEox5Xp1WUdft1wuxeXlpXUd/bNMxwPQOfLrIupySt7e3mrryWW1nqmuvr6pTtUx1dWp+x6A/JWY5LSpV7edzT773t72ewBpDwDyAyA/gMs5/3a79e5JLkB+MZ/PxWq18rKReH6XyI8EQM4PgPwAyA+A/ADID4D8AMgPMC6mNMHv4+7ubv/+4eHB+c8dfeTf7XYHLxim3c4lngvC9x75d7td5eN/s9kMw2k3N+VXT+Bms9mXh2EoyrIUV1dX4uPjw+pSWhVh9DqmCNS0H7m+qWwM4tu0m+m7t203dbumlMbUvqQ936jim5abTpp8VZ20uvW2+3E1/+/abnq5TfsS+QccSHVZLyOXKoJrJ6pLHt6m81ftx1XxRyO/zQlsiuZqB/BJ/mPbzfVB7UnSnjAMa5dP1Yl8SnngzPLPZjMRx/FeePkSQog4jq0HbWrEaiuuvs1v6ABqu+l0aTdozyRN0y+bwWkTFxcXB2U2J7Dt3R71zoTpzo3tfsZyqe/SbnUdvapNTO1mcxfNtv3HTlmWYr1e/x1EfhfyYnAXk/ze/rYH8WHqm+y+3tkAj+VHdNDhJ82A/ADID4D8AMgPgPwAyA+A/ADID4D8AMgPMHJa/ban7xkQXJsECRyWv2/0KTNAiKenp4OyxWJBw5D2DE+XxyiHFL+uHEYY+fv47XzVI3dtHtPr83gkVRNNHUtRFI0dg/+JdngujpkoYTqU+Lqk6pw6Q3c400ROtsdjc4yvr69nO9nwnziOxTGP4DqR9thMVCWFZ4wBoxjwnqODAHSSX58W0MWHwJu+U1mW4vb2tvfPzbLM6jIPZ4z8LkwLeMyxh2EohpjqZbFY1N7V4XZn/3Set6duAGt7d8V2Cm2106n1bP/o9ptmbuA+/3A3C5i0CpD/G/7IBd6C/ID8AMgPgPwAyA+A/ADID4D8AMgPgPwAyA+A/ADID4D8AGNgutlsmBUAvGRiKLunWYC0BwD5AZAfwBn+AaqCPC8J0grEAAAAAElFTkSuQmCC"></p><br style="clear:both;"><label class="btn prev" accesskey="p" for="_custom" title="Custom">Previous</label><label class="btn next" accesskey="n" for="_fine_tuning" title="Fine Tuning">Next</label></div>
- <div class="page" rel="fine_tuning"><div><ul class="breadcrumbs"><li><label class="home" for="_" title="Home"></label> »</li><li> Fine Tuning</li></ul><hr></div>
- <h1 id="fine_tuning">Fine Tuning<a href="#fine_tuning"></a></h1>
- <h2 id="base">Base<a href="#base"></a></h2>
- <p>You can tweak SMGUI by providing some define before you include <b>ui.h</b>.</p>
- <h3 id="ui_implementation">UI_IMPLEMENTATION<a href="#ui_implementation"></a></h3>
- <div class="warn"><p><span>Warning</span></p><p> Only define this after you have included the modules.</p></div>
- <p>Set this if you want to include not just the definitions but the implementation too.</p>
- <h3 id="ui_noaa">UI_NOAA<a href="#ui_noaa"></a></h3>
- <p>Disable anti-aliased lines (eliminates math.h and libm dependency).</p>
- <h3 id="ui_maxevents">UI_MAXEVENTS<a href="#ui_maxevents"></a></h3>
- <p>Set the maximum number of pending events. If not defined otherwise, defaults to 16.</p>
- <h3 id="ui_maxpopups">UI_MAXPOPUPS<a href="#ui_maxpopups"></a></h3>
- <p>Set the maximum number of visible popups. If not defined otherwise, defaults to 16.</p>
- <h3 id="ui_backend_initialized">UI_BACKEND_INITIALIZED<a href="#ui_backend_initialized"></a></h3>
- <p>Set if you want to call <samp>glfwInit()</samp> / <samp>glfwTerminate()</samp>, <samp>SDL_Init()</samp> / <samp>SDL_Quit()</samp> etc. yourself. This is needed if you want
- SMGUI to handle multiple windows.</p>
- <h3 id="ui_backend_noflush">UI_BACKEND_NOFLUSH<a href="#ui_backend_noflush"></a></h3>
- <p>Set if you don't want <samp>ui_event()</samp> to flush the window, and you call <samp>glfwSwapBuffers()</samp> /
- <samp>SDL_RenderPresent()</samp> / etc. yourself. This is needed if you want to draw over the UI layer.</p>
- <h2 id="glfw3">GLFW3<a href="#glfw3"></a></h2>
- <p>Separately you can tweak the GLFW3 backend by providing some define before you include <b>ui_glfw.h</b>.</p>
- <p>By default, this backend is compiled with shaders for OpenGL3.3 core profile with both <samp>glad</samp> and <samp>glew</samp> extension loader
- support.</p>
- <h3 id="ui_glfw_noshader">UI_GLFW_NOSHADER<a href="#ui_glfw_noshader"></a></h3>
- <p>Use old-school OpenGL API. This works everywhere and requires no extension loader nor shaders. The downside is, that some video
- card drivers are buggy and break backward compatibility, so you won't be able to use your own shaders either with this option.</p>
- <h3 id="ui_glfw_gles2">UI_GLFW_GLES2<a href="#ui_glfw_gles2"></a></h3>
- <p>Use shaders, but only OpenGL ES 2.0 (mobile platform variant). For supporting legacy mobiles only, most modern devices have
- no issues using OpenGL 3.3 core.</p>
- <h3 id="ui_glfw_customhooks">UI_GLFW_CUSTOMHOOKS<a href="#ui_glfw_customhooks"></a></h3>
- <p>If you want to use your own GLFW3 hooks, then define this, and also call the backend's hooks from your hooks.
- For example:</p>
- <div class="pre"><pre class="lineno">1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br></pre><code><span class="hl_c">/* set your hook as usual */</span>
- <span class="hl_f">glfwSetMouseButtonCallback</span>(<span class="hl_f">ui_getwindow</span>(<span class="hl_v">ctx</span>), <span class="hl_v">my_glfw_mouse</span>);
- <span class="hl_c">/* your hook */</span>
- <span class="hl_t">void</span> <span class="hl_f">my_glfw_mouse</span>(<span class="hl_v">GLFWwindow</span> <span class="hl_o">*</span><span class="hl_v">window</span>, <span class="hl_t">int</span> <span class="hl_v">button</span>, <span class="hl_t">int</span> <span class="hl_v">action</span>, <span class="hl_t">int</span> <span class="hl_v">mods</span>)
- {
- <span class="hl_c">/* parse what you want */</span>
- <span class="hl_c">/* ... */</span>
- <span class="hl_c">/* at the end also call the ui_glfw's hook */</span>
- <span class="hl_f">ui_glfw_mouse</span>(<span class="hl_v">window</span>, <span class="hl_v">button</span>, <span class="hl_v">action</span>, <span class="hl_v">mods</span>);
- }</code></div><br style="clear:both;"><label class="btn prev" accesskey="p" for="_example" title="Example">Previous</label><label class="btn next" accesskey="n" for="_smgui_license" title="SMGUI License">Next</label></div>
- <div class="page" rel="smgui_license"><div><ul class="breadcrumbs"><li><label class="home" for="_" title="Home"></label> »</li><li> SMGUI License</li></ul><hr></div>
- <h1 id="smgui_license">SMGUI License<a href="#smgui_license"></a></h1>
- <p>Licensed under the terms of the permissive <b>MIT license</b>.</p>
- <div class="pre"><pre>
- Permission is hereby granted, free of charge, to any person
- obtaining a copy of this software and associated documentation
- files (the "Software"), to deal in the Software without
- restriction, including without limitation the rights to use, copy,
- modify, merge, publish, distribute, sublicense, and/or sell copies
- of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- </pre></div><br style="clear:both;"><label class="btn prev" accesskey="p" for="_fine_tuning" title="Fine Tuning">Previous</label></div>
- <footer><hr><p>© Copyright 2024 bzt (bztsrc@gitlab)<br><small>Generated by <a href="https://gitlab.com/bztsrc/gendoc">gendoc</a> v1.0.0</small></p></footer>
- </div>
- </div>
- <script>function m(){document.getElementById("menuchk").checked=false;}function c(s){var r=document.getElementById(s);if(r!=undefined){if(r.tagName=="INPUT")r.checked=true;else document.getElementById("_"+r.parentNode.getAttribute("rel")).checked=true;}m();}function s(s){var r=document.getElementById("_s"),p=document.getElementById("_m").getElementsByClassName("page"),n,i,j,a,b,c,d;if(s){s=s.toLowerCase();document.getElementById("_t").style.display="none";r.style.display="block";while(r.firstChild)r.removeChild(r.firstChild);n=document.createElement("p");n.appendChild(document.createTextNode("Search Results"));r.appendChild(n);for(i=1;i<p.length;i++){a=p[i].getAttribute("rel");b="";c=p[i].childNodes;d=p[i].getElementsByTagName("H1")[0].innerText;for(j=1;j<c.length && c[j].className!="btn prev";j++){if(c[j].id!=undefined&&c[j].id!=""){a=c[j].id;d=c[j].innerText;}else if(a!=b&&c[j].innerText!=undefined&&c[j].innerText.toLowerCase().indexOf(s)!=-1){b=a;n=document.createElement("a");n.appendChild(document.createTextNode(d));n.setAttribute("href","#"+a);n.setAttribute("onclick","c('"+a+"');");r.appendChild(n);}}}}else{document.getElementById("_t").style.display="block";r.style.display="none";}}document.addEventListener("DOMContentLoaded",function(e){var i,r,n;document.getElementById("_q").style.display="inline-block";if(document.location.href.indexOf("?")!=-1)document.location.href=document.location.href.replace("?","#");else{r=document.querySelectorAll("LABEL:not(.menu)");while(r.length){l=r[0].getAttribute("for").substr(1);n=document.createElement("a");n.appendChild(document.createTextNode(r[0].innerText));n.setAttribute("href","#"+l);n.setAttribute("onclick","c('"+(l!=""?l:"_")+"');");if(r[0].getAttribute("class")!=undefined)n.setAttribute("class",r[0].getAttribute("class"));if(r[0].getAttribute("title")!=undefined&&l!="")n.setAttribute("title",r[0].getAttribute("title"));if(r[0].getAttribute("accesskey")!=undefined)n.setAttribute("accesskey",r[0].getAttribute("accesskey"));r[0].parentNode.replaceChild(n,r[0]);r=document.querySelectorAll("LABEL:not(.menu)");}try{c(document.location.href.split("#")[1]);}catch(e){}}});</script>
- </body>
- </html>
|