├── How_To_Use_I_AM_UI_OLD.md ├── README.md ├── I_AM_UI.js └── i-am-ui-new.js /How_To_Use_I_AM_UI_OLD.md: -------------------------------------------------------------------------------- 1 | # I_AM_UI 2 | a ui engine for p5.js 3 | 4 | to get started: 5 | 6 | -go to p5.com and open the editor 7 | -import I_AM_UI 8 | -import a font and rename it UIfont.ttf it must be a true type font 9 | 10 | -- your code should look like this: 11 | 12 | function setup() { 13 | cnv = createCanvas(400, 400); 14 | cnv.touchMoved(touch_Moved); 15 | 16 | I_AM_UI_Create_UI_engine() 17 | } 18 | 19 | function mousePressed() { 20 | I_AM_UI_Update_MP_Engine() 21 | } 22 | 23 | function touchStarted() { 24 | I_AM_UI_Update_MP_Engine() 25 | } 26 | 27 | 28 | function touch_Moved() { 29 | I_AM_UI_Update_MD_Engine(); 30 | } 31 | 32 | function mouseDragged() { 33 | I_AM_UI_Update_MD_Engine(); 34 | } 35 | 36 | function draw() 37 | { 38 | background(220); 39 | } 40 | 41 | - types of object 42 | 43 | -- I_AM_UI_Button(x,y,width,height,text,text_size,text_offset_x,text_offset_y,m,index,corner_size); its a button 44 | 45 | -- I_AM_UI_hyperect(x,y,width,height,corner_size); rectangle with more verticies 46 | 47 | -- I_AM_UI_bool(x,y,width,height,index,text_if_true,text_if_false,corner_size); its a toggle 48 | 49 | -- I_AM_UI_colorThing(x,y,index); its a rgb color selector 50 | 51 | -- I_AM_UI_display(x,y,width,height,text,text_size,text_offset_x,text_offset_y,corner_size); text display 52 | 53 | -- I_AM_UI_windowsBase(x,y,width,height,text,corner_size,line_offset); hyperect with text and line 54 | 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # fez-ui 2 | 3 | ## regarding the name change 4 | i changed the name because it was too similar to [dear-imgui](https://github.com/ocornut/imgui)\ 5 | also "i-am-ui" wasn't very creative\ 6 | the names of the files will stay the same to keep compatibility 7 | 8 | ## about 9 | a ui library for p5.js 10 | 11 | please note that the new version is vastly different from the old version.\ 12 | all acessibily such as tts or tactile response is not included. 13 | 14 | library can be used with jsdelivr: 15 | ```html 16 | 17 | ``` 18 | 19 | #### [live example](https://editor.p5js.org/the.spiderminecart/full/PeLTnsMH5) 20 | 21 | ## a list of features: 22 | ### util 23 | hitbox\ 24 | iiil\ 25 | gridlock 26 | 27 | ### ui 28 | [button](https://github.com/zturtledog/fez-ui/wiki/ui#button)\ 29 | [vslider](https://github.com/zturtledog/fez-ui/wiki/ui#vslider)\ 30 | [slider](https://github.com/zturtledog/fez-ui/wiki/ui#slider)\ 31 | [slider2d](https://github.com/zturtledog/fez-ui/wiki/ui#slider2d)\ 32 | [onelinetext](https://github.com/zturtledog/fez-ui/wiki/ui#onelinetext)\ 33 | [checkbox](https://github.com/zturtledog/fez-ui/wiki/ui#checkbox)\ 34 | [draggable](https://github.com/zturtledog/fez-ui/wiki/ui#draggable) 35 | 36 | ### gui 37 | hyperect\ 38 | centeredtext 39 | 40 | ### kpi 41 | kpi is an updated input system that makes it easier to handle key input\ 42 | keydown\ 43 | keytapd 44 | 45 | ## coming someday (maybe) 46 | *(feature creep be like)*\ 47 | colorpicker\ 48 | graphics portals -- a hole in the scene to another graphics instance (a wrapper of p5.Graphics)\ 49 | survansii support -- a type of string formating\ 50 | graphs -- like with equations and things.\ 51 | theme systems -- a way of managing color themes 52 | 53 | ## getting started 54 | 55 | import i-am-ui-new.js into your project\ 56 | it is important to put `uiupd()` at the end of your draw function 57 | 58 | like this: 59 | ```js 60 | function draw() { 61 | background(220); 62 | 63 | //your code here! 64 | 65 | uiupd(); 66 | } 67 | ``` 68 | 69 | ## example project 70 | 71 | [![image](https://user-images.githubusercontent.com/71353802/186051464-0802a68e-1986-48d5-8b6c-cace418368bd.png)](https://editor.p5js.org/the.spiderminecart/full/PeLTnsMH5) 72 | 73 | #### see wiki for the docs 74 | note that it is a perpetual work in progress.\ 75 | also apologies for any spelling errors. 76 | -------------------------------------------------------------------------------- /I_AM_UI.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | THIS IS IMPORTANT FOR THOSE WHO SEEK TO USE THIS LIBRARY: 4 | 5 | this version is depricated and should not be used, instead use i-am-ui-new.js located in the same repo. 6 | 7 | */ 8 | 9 | let bool_index = []; 10 | let clicked = []; 11 | let boolean_index = []; 12 | let dragging = []; 13 | let color_dragging = []; 14 | let color_SH = []; 15 | let colorPosY = []; 16 | let colorPosX = []; 17 | let colorX = []; 18 | let colorY = []; 19 | let colorZ = []; 20 | 21 | let Cli_AMMO = 0; 22 | 23 | function I_AM_UI_Create_UI_engine(ammount) 24 | { 25 | for (let i = 0; i x && mouseX < x + w && mouseY > y && mouseY < y + h) 68 | { 69 | clicked[i] = false; 70 | print("Event.ButionDown: "+m); 71 | print(" "); 72 | 73 | return(true); 74 | }else{ 75 | clicked[i] = false; 76 | } 77 | 78 | I_AM_UI_hyperect(x,y,w,h,c); 79 | textSize(s); 80 | fill(27); 81 | text(t,x+ox,y+h-oy); 82 | fill(250); 83 | } 84 | 85 | function I_AM_UI_hyperect(x,y,w,h,c) 86 | { 87 | beginShape(); 88 | vertex(x+c, y); 89 | vertex(x+w-c, y); 90 | vertex(x+w, y+c); 91 | vertex(x+w, y+h-c); 92 | vertex(x+w-c, y+h); 93 | vertex(x+c, y+h); 94 | vertex(x, y+h-c); 95 | vertex(x, y+c); 96 | endShape(CLOSE); 97 | } 98 | 99 | function I_AM_UI_AddBar(x,y,t,w) 100 | { 101 | I_AM_UI_hyperect(x,y,w,20,5); 102 | if (I_AM_UI_Button(x,y,20,20,"+",25,2.5,2)) 103 | { 104 | return(true); 105 | } 106 | textSize(12); 107 | fill(27); 108 | text(t,x+25,y+15); 109 | fill(250); 110 | } 111 | 112 | function I_AM_UI_windowsBase(x,y,w,h,t,c,b) 113 | { 114 | I_AM_UI_hyperect(x,y,w,h,c); 115 | 116 | line(x,y+b,x+w,y+b); 117 | 118 | textSize(20); 119 | textFont(modulus); 120 | fill(27); 121 | text(t,x+12,y+b/2); 122 | fill(250); 123 | } 124 | 125 | function I_AM_UI_bool(x,y,w,h,i,t1,t2,c) 126 | { 127 | if(boolean_index[i] == true && mouseX > x && mouseX < x + w && mouseY > y && mouseY < y + h) 128 | { 129 | if(bool_index[i] == true) 130 | { 131 | bool_index[i] = false; 132 | }else 133 | { 134 | bool_index[i] = true; 135 | } 136 | boolean_index[i] = false; 137 | 138 | print("Event.Boolean.AtIndex["+i+"] was set to: "+ bool_index[i]); 139 | }else 140 | { 141 | boolean_index[i] = false; 142 | } 143 | 144 | I_AM_UI_hyperect(x,y,w,h,c); 145 | 146 | textSize(15); 147 | stroke(0); 148 | 149 | if (bool_index[i] == true) 150 | { 151 | text(t1,x+5,y+h-5); 152 | }else 153 | { 154 | text(t2,x+5,y+h-5); 155 | } 156 | 157 | return(bool_index[i]); 158 | } 159 | 160 | function I_AM_UI_colorThing(x,y,i) 161 | { 162 | if (color_dragging[i] == true) 163 | { 164 | if (mouseX > x+10 && mouseX < x + 120 && mouseY > y+10 && mouseY < y + 120) 165 | { 166 | colorX[i] = map(mouseX-x,0,120,0,255); 167 | colorY[i] = map(mouseY-y,0,120,0,255); 168 | 169 | colorPosX[i] = mouseX; 170 | colorPosY[i] = mouseY; 171 | } 172 | if (mouseX > x+130 && mouseX < x + 150 && mouseY > y && mouseY < y + 113) 173 | { 174 | colorZ[i] = map(mouseY-y,0,113,0,255); 175 | } 176 | 177 | color_dragging[i] = false; 178 | 179 | }else 180 | { 181 | color_dragging[i] = false; 182 | } 183 | 184 | I_AM_UI_hyperect(x,y,160,130,5); 185 | I_AM_UI_hyperect(x+10,y+10,110,110,5); 186 | I_AM_UI_hyperect(x+130,y+10,20,110,5); 187 | I_AM_UI_hyperect(x+130,y+10,20,map(colorZ[i],0,255,0,110),5); 188 | 189 | fill(colorX[i],colorY[i],colorZ[i]); 190 | ellipse(colorPosX[i],colorPosY[i],10,10); 191 | fill(255); 192 | 193 | let col = color(colorX[i],colorY[i],colorZ[i]); 194 | 195 | return(col); 196 | } 197 | 198 | function I_AM_UI_display(x,y,w,h,t,s,ox,oy,c) 199 | { 200 | I_AM_UI_hyperect(x,y,w,h,c); 201 | textSize(s); 202 | fill(27); 203 | text(t,x+ox,y+h-oy); 204 | fill(250); 205 | } 206 | -------------------------------------------------------------------------------- /i-am-ui-new.js: -------------------------------------------------------------------------------- 1 | // localizations 2 | let keys = "`1234567890-=\tqwertyuiop[]\\asdfghjkl;'zxcvbnm,./ ~!@#$%^&*()_+QWERTYUIOP{}|ASDFGHJKL:\"ZXCVBNM<>?" 3 | 4 | //permance 5 | 6 | let pdown 7 | let umouse 8 | 9 | //kpi 10 | let keylist = {}; 11 | document.addEventListener("keydown", (event) => { 12 | let posi = { 13 | key: event.key, 14 | code: event.code, 15 | which: event.keyCode, 16 | location:event.location, 17 | 18 | ctrl: event.ctrlKey, 19 | shift: event.shiftKey, 20 | alt: event.altKey, 21 | meta: event.metaKey, 22 | 23 | unique: true 24 | }; 25 | 26 | event.preventDefault() 27 | 28 | if (!keylist[event.key]) 29 | keylist[event.key] = posi; 30 | 31 | return false 32 | }); 33 | document.addEventListener("keyup", (e) => { 34 | keylist[event.key] = false; 35 | }); 36 | function keydown(code) { 37 | return !!keylist[code] 38 | } 39 | function keytapd(code) { 40 | return !!(keylist[code] && keylist[code].unique) 41 | } 42 | function ukpi() { 43 | for (let prp in keylist) { 44 | if (keylist[prp]) 45 | keylist[prp].unique = false 46 | } 47 | } 48 | 49 | //util 50 | 51 | function hitbox(x, y, w, h, px, py) { 52 | return px > x && px < x + w && py > y && py < y + h; 53 | } 54 | 55 | function iiil(t,l) { 56 | for (let i of l) { 57 | if (t == i) 58 | return true 59 | } 60 | return false 61 | } 62 | 63 | function iiis(t,l) { 64 | return !!l.split("").find(e=>e==t) 65 | } 66 | 67 | function gridlock(g,m) { 68 | return round(g/m)*m 69 | } 70 | 71 | function clamp(v,m,x) { 72 | return v>x?x:(v{ 250 | setTimeout(()=>{ 251 | if (mouseIsPressed && tmr>=w) { 252 | loop() 253 | pdown = !true 254 | }else{ 255 | rndr() 256 | o() 257 | tmr++ 258 | } 259 | },0) 260 | };o() 261 | } 262 | 263 | //classes 264 | 265 | //@note key repermanace bug (p[a]p[s]r[a]) 266 | //@note i think i fixed it but not sure 267 | class onelinetext { 268 | constructor(init,x,y,s) { 269 | this.text = init 270 | this.x = x 271 | this.y = y 272 | this.s = s||20 273 | this.cursor = 1 274 | this.spkeydic = {} 275 | } 276 | 277 | //setters 278 | 279 | position(x,y) { 280 | this.x = x 281 | this.y = y 282 | } 283 | 284 | size(s) { 285 | this.s = s 286 | } 287 | 288 | //events 289 | 290 | enter(f) { 291 | this.entr = f 292 | } 293 | 294 | charpressed(f) { 295 | this.cpress = f 296 | } 297 | 298 | sckey(k,f) { 299 | this.spkeydic[k] = f 300 | } 301 | 302 | //important 303 | 304 | salad() { 305 | this.text = "salad" 306 | this.cursor = 0 307 | } //this is the most important function 308 | 309 | update() { 310 | textSize(this.s) 311 | 312 | this.w = textWidth(this.text); 313 | 314 | //inbound cursor 315 | 316 | if (this.cursor < 0) { 317 | this.cursor = 0; 318 | } 319 | if (this.cursor > this.text.length) { 320 | this.cursor = this.text.length; 321 | } 322 | 323 | //cursor string data 324 | 325 | let data = [this.text.substring(0,this.cursor),this.text.substring(this.cursor)] 326 | 327 | if (this.select) { 328 | // move cursor right 329 | if (keyIsDown(39)) { 330 | if (!this.cursorkeyleft || this.cursorkeyleftime > 30) 331 | this.cursor++; 332 | this.cursorkeyleft = true 333 | this.cursorkeyleftime++ 334 | } 335 | else{ 336 | this.cursorkeyleft = false 337 | this.cursorkeyleftime = 0 338 | } 339 | 340 | //move cursor left 341 | if (keyIsDown(37)) { 342 | if (!this.cursorkeyright || this.cursorkeyrightime > 30) 343 | this.cursor--; 344 | this.cursorkeyright = true 345 | this.cursorkeyrightime++ 346 | } 347 | else{ 348 | this.cursorkeyright = false 349 | this.cursorkeyrightime = 0 350 | } 351 | 352 | //enter 353 | if (keyIsDown(13)) { 354 | if (this.entr) this.entr(this,this.text) 355 | } 356 | 357 | //delete previous char 358 | if (keyIsDown(8)) { 359 | if (!this.cursorkeydel || this.cursorkeydeltime > 50) { 360 | this.cursor--; 361 | this.text = data[0].substring(0,this.cursor)+data[1] 362 | } 363 | this.cursorkeydel = true 364 | this.cursorkeydeltime++ 365 | } 366 | else{ 367 | this.cursorkeydel = false 368 | this.cursorkeydeltime = 0 369 | } 370 | 371 | //actial typing with timer 372 | //@note this is where the problem happens 373 | if (keyIsPressed) { 374 | // console.log(char(keyCode)) 375 | if (iiil(key,keys)) 376 | if (!this.cursorkey || key != this.pcursorkey || this.cursorkeytime > 50) { 377 | if (keyIsDown(keyCode)) { 378 | this.cursor++ 379 | this.text = data[0]+key+data[1] 380 | 381 | if (this.cpress) this.cpress(this,this.text,key) 382 | if (this.spkeydic[key]) this.spkeydic[key](this) 383 | } 384 | } 385 | this.cursorkey = true 386 | this.pcursorkey = key 387 | this.cursorkeytime++ 388 | }else{ 389 | this.cursorkey = false 390 | this.cursorkeytime = 0 391 | } 392 | } 393 | 394 | //select and position the cursor 395 | 396 | if (hitbox(this.x,this.y-this.s-2.5,(this.w < 10 ? 10 : this.w),this.s+5,mouseX,mouseY)) { 397 | cursor(TEXT) 398 | if (mouseIsPressed) { 399 | let record = ""; 400 | for(let i = 0;i < this.text.length; i++) { 401 | record += this.text.charAt(i) 402 | if (hitbox(this.x,this.y-this.s-2.5,textWidth(record),this.s+5,mouseX,mouseY)) { 403 | this.cursor = i+1 404 | break; 405 | } 406 | } 407 | 408 | this.select = true 409 | } 410 | } 411 | else{ 412 | cursor(ARROW) 413 | if (mouseIsPressed) { 414 | this.select = false 415 | } 416 | } 417 | } 418 | 419 | draw() { 420 | let data = [this.text.substring(0,this.cursor),this.text.substring(this.cursor)] 421 | 422 | textSize(this.s) 423 | 424 | //draw 425 | 426 | noStroke() 427 | textSize(this.s) 428 | text(data[0],this.x,this.y) 429 | text(data[1],this.x+textWidth(data[0])+1,this.y) 430 | strokeWeight(2) 431 | stroke(0) 432 | if (this.select) 433 | line(this.x+textWidth(data[0])+1,this.y,this.x+textWidth(data[0])+1,this.y-this.s+5) 434 | line(this.x,this.y+2,this.x+(this.w < 10 ? 10 : this.w),this.y+2) 435 | } 436 | } 437 | 438 | --------------------------------------------------------------------------------