|
| 1 | +{ |
| 2 | + /* |
| 3 | + let setDevMode = ()=>{ |
| 4 | + Bangle.setLCDTimeout(0); // Easier to read the screen while developing. |
| 5 | + Bangle.setLocked(false); |
| 6 | + Bangle.setLCDBrightness(0.6); |
| 7 | + Bangle.setLCDPower(true); |
| 8 | + }; |
| 9 | + setDevMode(); |
| 10 | + */ |
| 11 | + |
| 12 | + //// Drawing operations |
| 13 | + |
| 14 | + Bangle.loadWidgets(); // So appRect takes widgets into account. |
| 15 | + let R = Bangle.appRect; |
| 16 | + |
| 17 | + let backDropColor = [1,0,0]; |
| 18 | + |
| 19 | + let draw = (rect)=>{ |
| 20 | + g.reset(); |
| 21 | + if (rect) g.setClipRect(rect.x1, rect.y1, rect.x2, rect.y2); |
| 22 | + g.setColor(backDropColor[0],backDropColor[1],backDropColor[2]).fillRect(0,0,176,176); |
| 23 | + g.setColor(1,1,1).drawLine(xA, R.y, xA, yA).drawLine(xB, R.y, xB, yA); |
| 24 | + g.reset(); |
| 25 | + Bangle.drawWidgets(); |
| 26 | + }; |
| 27 | + |
| 28 | + let blink = ()=>{setTimeout(()=>{ |
| 29 | + g.reset().setColor(backDropColor[1],backDropColor[0],backDropColor[2]).fillRect(R.x2/2-15,R.y2-29,R.x2/2-5,R.y2-19); |
| 30 | + setTimeout(()=>{g.reset().setColor(backDropColor[0],backDropColor[1],backDropColor[2]).fillRect(R.x2/2-15,R.y2-29,R.x2/2-5,R.y2-19);},100); |
| 31 | + },0); |
| 32 | + }; |
| 33 | + |
| 34 | + //// Functional logic |
| 35 | + |
| 36 | + // Get audio levels from Android device |
| 37 | + let audioLevels = {u:30, c:15}; // Init with values to avoid "Uncaught Error: Cannot read property 'u' of undefined" if values were not gathered from Gadgetbridge. |
| 38 | + let audioHandler = (e)=>{audioLevels = e;print(audioLevels);}; |
| 39 | + Bangle.on('audio', audioHandler); |
| 40 | + Bangle.musicControl("vg"); // vg = Volume Get level |
| 41 | + |
| 42 | + // Handle music messages |
| 43 | + // Bangle.emit("message", type, msg); |
| 44 | + let trackPosition = 0; |
| 45 | + let trackDur = 30; |
| 46 | + let trackState = "pause"; |
| 47 | + let messageHandler = (type, msg)=>{ |
| 48 | + print("\n","type:"+type, "t:"+msg.t, "src:"+msg.src, "mode:"+msg.state, "pos:"+msg.position, "dur:"+msg.dur); |
| 49 | + if (type==='music' && msg.src=="musicstate") { |
| 50 | + trackState = msg.state; |
| 51 | + trackPosition = msg.position + (trackState==="play"?1:0); // +1 when playing to account for latency. |
| 52 | + trackDur = msg.dur; |
| 53 | + if (progressBar) { |
| 54 | + progressBar.f.stopAutoUpdate(); |
| 55 | + initProgressBar(); |
| 56 | + } |
| 57 | + blink(); // Indicate when a `musicstate` message arrived. |
| 58 | + } |
| 59 | + }; |
| 60 | + Bangle.on('message', messageHandler); |
| 61 | + |
| 62 | + // cbVolumeSlider is used with volumeSlider |
| 63 | + let cbVolumeSlider = (mode,fb)=>{ |
| 64 | + if (mode =="incr") Bangle.musicControl(fb>0?"volumedown":"volumeup"); |
| 65 | + if (mode =="remove") { |
| 66 | + audioLevels.c = fb; |
| 67 | + ebLast = 0; |
| 68 | + draw(volumeSlider.c.r); |
| 69 | + //progressBar.f.draw(progressBar.v.level); |
| 70 | + print(process.memory().usage); |
| 71 | + print("#drag handlers: " + Bangle["#ondrag"].length); |
| 72 | + } |
| 73 | + }; |
| 74 | + |
| 75 | + // cbColorSlider is used with progressBar |
| 76 | + let cbColorSlider = (mode,fb)=>{ |
| 77 | + if (mode =="incr") { |
| 78 | + let l = colorSlider.v.level; |
| 79 | + print("color mode: " + l); |
| 80 | + if (l===0) backDropColor = [1,0,0]; |
| 81 | + if (l===1) backDropColor = [0.75,0.25,0]; |
| 82 | + if (l===2) backDropColor = [0.5,0.5,0]; |
| 83 | + if (l===3) backDropColor = [0.25,0.75,0]; |
| 84 | + if (l===4) backDropColor = [0,1,0]; |
| 85 | + if (l===5) backDropColor = [0,0.75,0.25]; |
| 86 | + if (l===6) backDropColor = [0,0.5,0.5]; |
| 87 | + if (l===7) backDropColor = [0,0.25,0.75]; |
| 88 | + if (l===8) backDropColor = [0,0,1]; |
| 89 | + g.setColor(backDropColor[0],backDropColor[1],backDropColor[2]).fillRect(xA+1,R.y,xB-1,yA); |
| 90 | + } |
| 91 | + if (mode =="remove") { |
| 92 | + init(); |
| 93 | + } |
| 94 | + }; |
| 95 | + |
| 96 | + // cbBrightnessSlider is used with progressBar |
| 97 | + let cbBrightnessSlider = (mode,fb)=>{ |
| 98 | + if (mode =="map") Bangle.setLCDBrightness(fb/100); |
| 99 | + if (mode =="remove") print("remove handling triggered") |
| 100 | + }; |
| 101 | + |
| 102 | + // cbProgressbar is used with progressBar |
| 103 | + let cbProgressbar = (mode,fb)=>{ |
| 104 | + print("progressbar callback"); |
| 105 | + //let currentLevel = fb; |
| 106 | + //print(process.memory().usage); |
| 107 | + //print("#drag handlers: " + Bangle["#ondrag"].length) |
| 108 | + }; |
| 109 | + |
| 110 | + // For use when dividing the parts of the screen for different sliders. |
| 111 | + let xA = R.x+4*R.w/8; |
| 112 | + let xB = R.x+11*R.w/16; |
| 113 | + let yA = R.x2-Math.round(R.w/20)-5; |
| 114 | + |
| 115 | + // volumeSlider controls volume level on the android device. |
| 116 | + let volumeSlider=require("Slider").create( |
| 117 | + cbVolumeSlider, |
| 118 | + {mode:"incr", steps:audioLevels.u, initLevel:audioLevels.c, horizontal:false, rounded:false, height:R.h-21, timeout:0.5, propagateDrag:true, xStart:R.x+4, dragRect:{x:R.x, y:0, x2:xA-1, y2: R.y2}} |
| 119 | + ); |
| 120 | + |
| 121 | + // colorSlider controls the background color of this app. It uses custom graphics defined in its callback function. |
| 122 | + let colorSlider = require("Slider").create( |
| 123 | + cbColorSlider, |
| 124 | + {mode:"incr", steps:8, drawableSlider:false, xStart: R.x2-2*R.w/4, height:R.h-21, initLevel:0, propagateDrag:true, timeout:0, dragRect:{x:xA, y:0, x2:xB-1, y2: R.y2}} |
| 125 | + ); |
| 126 | + |
| 127 | + // brightnessSlider controls the brightness of the Bangle.js |
| 128 | + let brightnessSlider = require("Slider").create( |
| 129 | + cbBrightnessSlider, |
| 130 | + {mode:"map", steps:100, height:R.h-21, timeout:0, initLevel:100*0.0, propagateDrag:true, dragRect:{x:xB, y:0, x2:R.x2, y2: R.y2}, rounded:true} |
| 131 | + ); |
| 132 | + |
| 133 | + // progressBar follows the media track playing on the android device. |
| 134 | + let progressBar; |
| 135 | + let initProgressBar = ()=>{ |
| 136 | + progressBar = require("Slider").create( |
| 137 | + cbProgressbar, |
| 138 | + {dragableSlider:false, steps:trackDur, initLevel:trackPosition, horizontal:true, rounded:false, timeout:0, immediateDraw:false, propagateDrag:true, width:Math.round(R.w/20), xStart:R.x2-R.w/20-4, oversizeR:10, oversizeL:10, autoProgress:true, yStart: R.x+4, height: R.w-8} |
| 139 | + ); |
| 140 | + progressBar.f.draw(progressBar.v.level); |
| 141 | + if (trackState==="play") progressBar.f.startAutoUpdate(); |
| 142 | + }; |
| 143 | + |
| 144 | + let init = ()=> { |
| 145 | + draw(); |
| 146 | + if (progressBar) { |
| 147 | + progressBar.f.draw(progressBar.v.level); |
| 148 | + } else {initProgressBar();} |
| 149 | + brightnessSlider.f.draw(brightnessSlider.v.level); |
| 150 | + }; |
| 151 | + |
| 152 | +// let isAnySliderDragActive = ()=>{ |
| 153 | +// return (volumeSlider.v.dragActive || brightnessSlider.v.dragActive || colorSlider.v.dragActive || progressBar.v.dragActive); |
| 154 | +// }; |
| 155 | + |
| 156 | + let ebLast = 0; // Used for fix/Hack needed because there is a timeout before the slider is called upon. |
| 157 | + Bangle.on('drag', (e)=>{ |
| 158 | + if (ebLast==0) { |
| 159 | + // if (!isAnySliderDragActive()) { |
| 160 | + if (e.y<yA) { |
| 161 | + if (e.x<xA && !volumeSlider.v.dragActive) { |
| 162 | + Bangle.musicControl("vg"); // vg = Volume Get level |
| 163 | + setTimeout(()=>{ // Timeout so gadgetbridge has time to send back volume levels. |
| 164 | + volumeSlider.c.steps=audioLevels.u; |
| 165 | + volumeSlider.v.level=audioLevels.c; |
| 166 | + },200); |
| 167 | + Bangle.prependListener('drag', volumeSlider.f.dragSlider); |
| 168 | + } |
| 169 | + if (e.x>=xA && e.x<xB && !colorSlider.v.dragActive) { |
| 170 | + Bangle.prependListener('drag', colorSlider.f.dragSlider); |
| 171 | + } |
| 172 | + if (e.x>=xB && !brightnessSlider.v.dragActive) { |
| 173 | + Bangle.prependListener('drag', brightnessSlider.f.dragSlider); |
| 174 | + } |
| 175 | + } |
| 176 | + if (e.y>=yA) { |
| 177 | + progressBar.f.dragSlider&&Bangle.prependListener('drag',progressBar.f.dragSlider); |
| 178 | + } |
| 179 | + // } |
| 180 | + } |
| 181 | + ebLast = e.b; |
| 182 | + }); |
| 183 | + |
| 184 | + init(); |
| 185 | + |
| 186 | + //print("#drag handlers: " + Bangle["#ondrag"].length) |
| 187 | +} |
0 commit comments