Skip to content

Instantly share code, notes, and snippets.

@rozek
Last active January 14, 2020 19:50
Show Gist options
  • Save rozek/cb55c9cf62d4505653a986f39e807eb5 to your computer and use it in GitHub Desktop.
Save rozek/cb55c9cf62d4505653a986f39e807eb5 to your computer and use it in GitHub Desktop.
Bangle.js: a simple ButtonWatcher example
//------------------------------------------------------------------------------
//-- ButtonWatcher --
//------------------------------------------------------------------------------
(function () {
let _AutoRepeatDelay = 800; // start auto repeat after 800ms
let _AutoRepeatInterval = 200; // send "ButtonPressed" every 200ms
const ButtonList = [BTN1, BTN2, BTN3, BTN4, BTN5];
const TakerList = [[], [], [], [], []];
const TimerIdList = [null, null, null, null, null];
const IntervalIdList = [null, null, null, null, null];
/**** setWatchFor ****/
function setWatchFor (Button, Taker) {
let ButtonId = ButtonList.indexOf(Button);
if (ButtonId < 0) { throw new TypeError('button expected') }
if ((Taker == null) || (typeof Taker !== 'object')) {
throw new TypeError('"Taker" should be an object');
}
let TakerIndex = TakerList[ButtonId].indexOf(Taker);
if (TakerIndex < 0) { TakerList[ButtonId].push(Taker) }
return this;
}
/**** clearWatchFor ****/
function clearWatchFor (Button, Taker) {
let ButtonId = ButtonList.indexOf(Button);
if (ButtonId < 0) { throw new TypeError('button expected') }
if ((Taker == null) || (typeof Taker !== 'object')) {
throw new TypeError('"Taker" should be an object');
}
let TakerIndex = TakerList[ButtonId].indexOf(Taker);
if (TakerIndex >= 0) { TakerList[ButtonId].splice(TakerIndex,1) }
return this;
}
/**** clearWatchesFor ****/
function clearWatchesFor (Taker) {
if ((Taker == null) || (typeof Taker !== 'object')) {
throw new TypeError('"Taker" should be an object');
}
for (let ButtonId = 0; ButtonId < 5; ButtonId++) {
let TakerIndex = TakerList[ButtonId].indexOf(Taker);
if (TakerIndex >= 0) { TakerList[ButtonId].splice(TakerIndex,1) }
}
return this;
}
/**** clearWatches ****/
function clearWatches () {
for (let ButtonId = 0; ButtonId < 5; ButtonId++) {
TakerList[ButtonId] = [];
}
return this;
}
/**** handleTimeout ****/
function handleTimeout (ButtonId) {
clearTimeout(TimerIdList[ButtonId]);
TimerIdList[ButtonId] = null;
if (_AutoRepeatInterval != null) {
IntervalIdList[ButtonId] = setInterval(handleInterval,_AutoRepeatInterval,ButtonId);
}
informTakers(ButtonId,'onButtonPress');
}
/**** handleInterval ****/
function handleInterval (ButtonId) {
informTakers(ButtonId,'onButtonPress');
}
/**** informTakers ****/
function informTakers (ButtonId, MethodName) {
let Takers = TakerList[ButtonId];
for (let i = 0, l = Takers.length; i < l; i++) {
let Method = Takers[i][MethodName];
if (typeof Method === 'function') {
try {
Method.call(Takers[i],ButtonId+1);
} catch (Signal) { /* nop */ }
}
}
}
/**** ButtonWatcher object ****/
ButtonWatcher = {
get AutoRepeatDelay () { return _AutoRepeatDelay },
set AutoRepeatDelay (Value) {
switch (true) {
case (Value == null):
_AutoRepeatDelay = undefined;
break;
case (typeof Value === 'number') || (Value instanceof Number):
_AutoRepeatDelay = (Value <= 0 ? undefined : Value);
break;
default:
throw new TypeError('number expected');
}
},
get AutoRepeatInterval () { return _AutoRepeatInterval },
set AutoRepeatInterval (Value) {
switch (true) {
case (Value == null):
_AutoRepeatInterval = undefined;
break;
case (typeof Value === 'number') || (Value instanceof Number):
_AutoRepeatInterval = (Value <= 0 ? undefined : Value);
break;
default:
throw new TypeError('number expected');
}
},
setWatchFor:setWatchFor, clearWatchFor:clearWatchFor,
clearWatchesFor:clearWatchesFor, clearWatches:clearWatches
};
/**** let ButtonWatcher actually watch all buttons ****/
function handleButton (Button, Details) {
let ButtonId = ButtonList.indexOf(Button);
if (Details.state == true) {
if (_AutoRepeatDelay != null) {
TimerIdList[ButtonId] = setTimeout(handleTimeout,_AutoRepeatDelay,ButtonId);
informTakers(ButtonId,'onButtonDown');
}
} else {
if (TimerIdList[ButtonId] != null) {
clearTimeout(TimerIdList[ButtonId]);
TimerIdList[ButtonId] = null;
}
if (IntervalIdList[ButtonId] != null) {
clearInterval(IntervalIdList[ButtonId]);
IntervalIdList[ButtonId] = null;
}
informTakers(ButtonId,'onButtonUp');
}
}
let Options = { edge:'both', debounce:50, repeat:true };
setWatch(handleButton.bind(ButtonWatcher,BTN1), BTN1, Options);
setWatch(handleButton.bind(ButtonWatcher,BTN2), BTN2, Options);
setWatch(handleButton.bind(ButtonWatcher,BTN3), BTN3, Options);
setWatch(handleButton.bind(ButtonWatcher,BTN4), BTN4, Options);
setWatch(handleButton.bind(ButtonWatcher,BTN5), BTN5, Options);
})();
Bangle.setLCDMode('120x120');
g.clear();
g.setFont("6x8");
const Width = g.getWidth();
const Height = g.getHeight();
/**** show screen ****/
g.drawString('Buttons/Touch Areas', 5,5);
g.drawString('BTN1:', 10,25);
g.drawString('BTN2:', 10,40);
g.drawString('BTN3:', 10,55);
g.drawString('BTN4:', 10,70);
g.drawString('BTN5:', 10,85);
g.drawString('press Btn/tap Scrn', 5,105);
/**** Button Monitor ****/
let ButtonMonitor = {
onButtonDown: function onButtonDown (ButtonId) {
ButtonId -= 1;
g.clearRect(45,25+ButtonId*15, Width,40+ButtonId*15);
g.drawString('down', 45,25+ButtonId*15);
g.flip();
},
onButtonPress: function onButtonPress (ButtonId) {
ButtonId -= 1;
g.clearRect(45,25+ButtonId*15, Width,40+ButtonId*15);
g.drawString('pressed', 45,25+ButtonId*15);
g.flip();
},
onButtonUp: function onButtonUp (ButtonId) {
ButtonId -= 1;
g.clearRect(45,25+ButtonId*15, Width,40+ButtonId*15);
g.drawString('up', 45,25+ButtonId*15);
g.flip();
}
};
/**** watch all buttons ****/
ButtonWatcher.setWatchFor(BTN1,ButtonMonitor);
ButtonWatcher.setWatchFor(BTN2,ButtonMonitor);
ButtonWatcher.setWatchFor(BTN3,ButtonMonitor);
ButtonWatcher.setWatchFor(BTN4,ButtonMonitor);
ButtonWatcher.setWatchFor(BTN5,ButtonMonitor);
g.flip();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment