2022-10-13 17:43:56 +00:00
{ //run in own scope for fast switch
2022-09-21 19:33:14 +00:00
const STORAGE = require ( "Storage" ) ;
2022-11-01 23:31:06 +00:00
const BAT _FULL = require ( "Storage" ) . readJSON ( "setting.json" ) . batFullVoltage || 0.3144 ;
2022-10-13 17:43:56 +00:00
let init = function ( ) {
global . screen = 1 ;
global . drawTimeout = undefined ;
global . lastDrawnScreen = 0 ;
global . firstDraw = true ;
global . slices = [ ] ;
global . maxScreens = 1 ;
global . scheduleDraw = false ;
2022-09-21 19:33:14 +00:00
Bangle . loadWidgets ( ) ;
2022-10-21 15:04:53 +00:00
WIDGETS . gpstrek . start ( false ) ;
2022-10-13 17:43:56 +00:00
if ( ! WIDGETS . gpstrek . getState ( ) . numberOfSlices ) WIDGETS . gpstrek . getState ( ) . numberOfSlices = 3 ;
} ;
let cleanup = function ( ) {
if ( global . drawTimeout ) clearTimeout ( global . drawTimeout ) ;
delete global . screen ;
delete global . drawTimeout ;
delete global . lastDrawnScreen ;
delete global . firstDraw ;
delete global . slices ;
delete global . maxScreens ;
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
init ( ) ;
scheduleDraw = true ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let parseNumber = function ( toParse ) {
2022-09-21 19:33:14 +00:00
if ( toParse . includes ( "." ) ) return parseFloat ( toParse ) ;
return parseFloat ( "" + toParse + ".0" ) ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let parseWaypoint = function ( filename , offset , result ) {
2022-09-21 19:33:14 +00:00
result . lat = parseNumber ( STORAGE . read ( filename , offset , 11 ) ) ;
result . lon = parseNumber ( STORAGE . read ( filename , offset += 11 , 12 ) ) ;
return offset + 12 ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let parseWaypointWithElevation = function ( filename , offset , result ) {
2022-09-21 19:33:14 +00:00
offset = parseWaypoint ( filename , offset , result ) ;
result . alt = parseNumber ( STORAGE . read ( filename , offset , 6 ) ) ;
return offset + 6 ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let parseWaypointWithName = function ( filename , offset , result ) {
2022-09-21 19:33:14 +00:00
offset = parseWaypoint ( filename , offset , result ) ;
return parseName ( filename , offset , result ) ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let parseName = function ( filename , offset , result ) {
2022-09-21 19:33:14 +00:00
let nameLength = STORAGE . read ( filename , offset , 2 ) - 0 ;
result . name = STORAGE . read ( filename , offset += 2 , nameLength ) ;
return offset + nameLength ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let parseWaypointWithElevationAndName = function ( filename , offset , result ) {
2022-09-21 19:33:14 +00:00
offset = parseWaypointWithElevation ( filename , offset , result ) ;
return parseName ( filename , offset , result ) ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let getEntry = function ( filename , offset , result ) {
2022-09-21 19:33:14 +00:00
result . fileOffset = offset ;
let type = STORAGE . read ( filename , offset ++ , 1 ) ;
if ( type == "" ) return - 1 ;
switch ( type ) {
case "A" :
offset = parseWaypoint ( filename , offset , result ) ;
break ;
case "B" :
offset = parseWaypointWithName ( filename , offset , result ) ;
break ;
case "C" :
offset = parseWaypointWithElevation ( filename , offset , result ) ;
break ;
case "D" :
offset = parseWaypointWithElevationAndName ( filename , offset , result ) ;
break ;
default :
print ( "Unknown entry type" , type ) ;
return - 1 ;
}
offset ++ ;
result . fileLength = offset - result . fileOffset ;
//print(result);
return offset ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
const labels = [ "N" , "NE" , "E" , "SE" , "S" , "SW" , "W" , "NW" ] ;
const loc = require ( "locale" ) ;
2022-10-13 17:43:56 +00:00
let matchFontSize = function ( graphics , text , height , width ) {
2022-09-21 19:33:14 +00:00
graphics . setFontVector ( height ) ;
let metrics ;
let size = 1 ;
while ( graphics . stringMetrics ( text ) . width > 0.90 * width ) {
size -= 0.05 ;
graphics . setFont ( "Vector" , Math . floor ( height * size ) ) ;
}
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let getDoubleLineSlice = function ( title1 , title2 , provider1 , provider2 , refreshTime ) {
2022-09-21 19:33:14 +00:00
let lastDrawn = Date . now ( ) - Math . random ( ) * refreshTime ;
2022-11-02 17:02:47 +00:00
let lastValue1 = 0 ;
let lastValue2 = 0 ;
2022-09-21 19:33:14 +00:00
return {
refresh : function ( ) {
2022-11-02 17:02:47 +00:00
let bigChange1 = ( Math . abs ( lastValue1 - provider1 ( ) ) > 1 ) ;
let bigChange2 = ( Math . abs ( lastValue2 - provider2 ( ) ) > 1 ) ;
let refresh = ( Bangle . isLocked ( ) ? ( refreshTime ? refreshTime * 5 : 10000 ) : ( refreshTime ? refreshTime * 2 : 1000 ) ) ;
let old = ( Date . now ( ) - lastDrawn ) > refresh ;
return ( bigChange1 || bigChange2 ) && old ;
2022-09-21 19:33:14 +00:00
} ,
draw : function ( graphics , x , y , height , width ) {
lastDrawn = Date . now ( ) ;
if ( typeof title1 == "function" ) title1 = title1 ( ) ;
if ( typeof title2 == "function" ) title2 = title2 ( ) ;
graphics . clearRect ( x , y , x + width , y + height ) ;
2022-11-02 17:02:47 +00:00
lastValue1 = provider1 ( ) ;
matchFontSize ( graphics , title1 + lastValue1 , Math . floor ( height * 0.5 ) , width ) ;
2022-09-21 19:33:14 +00:00
graphics . setFontAlign ( - 1 , - 1 ) ;
graphics . drawString ( title1 , x + 2 , y ) ;
graphics . setFontAlign ( 1 , - 1 ) ;
2022-11-02 17:02:47 +00:00
graphics . drawString ( lastValue1 , x + width , y ) ;
2022-09-21 19:33:14 +00:00
2022-11-02 17:02:47 +00:00
lastValue2 = provider2 ( ) ;
matchFontSize ( graphics , title2 + lastValue2 , Math . floor ( height * 0.5 ) , width ) ;
2022-09-21 19:33:14 +00:00
graphics . setFontAlign ( - 1 , - 1 ) ;
graphics . drawString ( title2 , x + 2 , y + ( height * 0.5 ) ) ;
graphics . setFontAlign ( 1 , - 1 ) ;
2022-11-02 17:02:47 +00:00
graphics . drawString ( lastValue2 , x + width , y + ( height * 0.5 ) ) ;
2022-09-21 19:33:14 +00:00
}
} ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2023-05-14 13:37:54 +00:00
let getMapSlice = function ( refreshTime ) {
let lastDrawn = Date . now ( ) - Math . random ( ) * refreshTime ;
return {
refresh : function ( ) {
let refresh = ( Bangle . isLocked ( ) ? ( refreshTime ? refreshTime * 5 : 10000 ) : ( refreshTime ? refreshTime * 2 : 1000 ) ) ;
let old = ( Date . now ( ) - lastDrawn ) > refresh ;
return true ;
} ,
draw : function ( graphics , x , y , height , width ) {
lastDrawn = Date . now ( ) ;
graphics . clearRect ( x , y , x + width , y + height ) ;
graphics . setClipRect ( x , y , x + width , y + height ) ;
let course = WIDGETS . gpstrek . getState ( ) . currentPos . course ;
if ( course === undefined ) course = WIDGETS . gpstrek . getState ( ) . avgComp ;
let route = WIDGETS . gpstrek . getState ( ) . route ;
let startingPoint = Bangle . project ( route . currentWaypoint ) ;
let current = Bangle . project ( WIDGETS . gpstrek . getState ( ) . currentPos ) ;
let poly = [ current . x , current . y ] ;
for ( let i = 0 ; i < 63 ; i ++ ) {
let nextPoint = getNext ( route , route . index + i ) ;
if ( ! nextPoint . lat ) break ;
let toDraw = Bangle . project ( nextPoint ) ;
poly . push ( toDraw . x ) ;
poly . push ( toDraw . y ) ;
}
poly = graphics . transformVertices ( poly , {
x : - current . x ,
y : - current . y ,
} ) ;
poly = graphics . transformVertices ( poly , {
rotate : require ( "graphics_utils" ) . degreesToRadians ( course ) ,
} ) ;
poly = graphics . transformVertices ( poly , {
scale : 0.05 ,
} ) ;
poly = graphics . transformVertices ( poly , {
x : x + width / 2 ,
y : y + height
} ) ;
print ( current , poly ) ;
graphics . fillCircle ( poly [ 0 ] , poly [ 1 ] , 5 ) ;
graphics . drawPoly ( poly , false ) ;
}
} ;
} ;
2022-10-13 17:43:56 +00:00
let getTargetSlice = function ( targetDataSource ) {
2022-09-21 19:33:14 +00:00
let nameIndex = 0 ;
let lastDrawn = Date . now ( ) - Math . random ( ) * 3000 ;
return {
refresh : function ( ) {
2022-11-02 17:02:47 +00:00
return Date . now ( ) - lastDrawn > ( Bangle . isLocked ( ) ? 3000 : 10000 ) ;
2022-09-21 19:33:14 +00:00
} ,
draw : function ( graphics , x , y , height , width ) {
lastDrawn = Date . now ( ) ;
graphics . clearRect ( x , y , x + width , y + height ) ;
if ( targetDataSource . icon ) {
graphics . drawImage ( targetDataSource . icon , x , y + ( height - 16 ) / 2 ) ;
x += 16 ;
width -= 16 ;
}
2023-05-12 08:19:23 +00:00
let start = targetDataSource . getStart ( ) ;
let target = targetDataSource . getTarget ( ) ;
2022-09-21 19:33:14 +00:00
2023-05-12 08:19:23 +00:00
if ( ! target || ! start ) return ;
let dist = distance ( start , target ) ;
2022-09-21 19:33:14 +00:00
if ( isNaN ( dist ) ) dist = Infinity ;
2023-05-12 08:19:23 +00:00
let bearingString = bearing ( start , target ) + "°" ;
if ( target . name ) {
2022-09-21 19:33:14 +00:00
graphics . setFont ( "Vector" , Math . floor ( height * 0.5 ) ) ;
2023-05-12 08:19:23 +00:00
let scrolledName = ( target . name || "" ) . substring ( nameIndex ) ;
2022-09-21 19:33:14 +00:00
if ( graphics . stringMetrics ( scrolledName ) . width > width ) {
nameIndex ++ ;
} else {
nameIndex = 0 ;
}
graphics . drawString ( scrolledName , x + 2 , y ) ;
let distanceString = loc . distance ( dist , 2 ) ;
matchFontSize ( graphics , distanceString + bearingString , height * 0.5 , width ) ;
graphics . drawString ( bearingString , x + 2 , y + ( height * 0.5 ) ) ;
graphics . setFontAlign ( 1 , - 1 ) ;
graphics . drawString ( distanceString , x + width , y + ( height * 0.5 ) ) ;
} else {
graphics . setFont ( "Vector" , Math . floor ( height * 1 ) ) ;
2023-05-12 08:19:23 +00:00
let bearingString = bearing ( start , target ) + "°" ;
2022-09-21 19:33:14 +00:00
let formattedDist = loc . distance ( dist , 2 ) ;
let distNum = ( formattedDist . match ( /[0-9\.]+/ ) || [ Infinity ] ) [ 0 ] ;
let size = 0.8 ;
let distNumMetrics ;
while ( graphics . stringMetrics ( bearingString ) . width + ( distNumMetrics = graphics . stringMetrics ( distNum ) ) . width > 0.90 * width ) {
size -= 0.05 ;
graphics . setFont ( "Vector" , Math . floor ( height * size ) ) ;
}
graphics . drawString ( bearingString , x + 2 , y + ( height - distNumMetrics . height ) / 2 ) ;
graphics . setFontAlign ( 1 , - 1 ) ;
graphics . drawString ( distNum , x + width , y + ( height - distNumMetrics . height ) / 2 ) ;
graphics . setFont ( "Vector" , Math . floor ( height * 0.25 ) ) ;
graphics . setFontAlign ( - 1 , 1 ) ;
if ( targetDataSource . getProgress ) {
graphics . drawString ( targetDataSource . getProgress ( ) , x + 2 , y + height ) ;
}
graphics . setFontAlign ( 1 , 1 ) ;
if ( ! isNaN ( distNum ) && distNum != Infinity )
graphics . drawString ( formattedDist . match ( /[a-zA-Z]+/ ) , x + width , y + height ) ;
}
}
} ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let drawCompass = function ( graphics , x , y , height , width , increment , start ) {
2022-09-21 19:33:14 +00:00
graphics . setFont12x20 ( ) ;
graphics . setFontAlign ( 0 , - 1 ) ;
graphics . setColor ( graphics . theme . fg ) ;
let frag = 0 - start % 15 ;
if ( frag > 0 ) frag = 0 ;
let xpos = 0 + frag * increment ;
for ( let i = start ; i <= 720 ; i += 15 ) {
2022-10-21 15:04:53 +00:00
var res = i + frag ;
2022-09-21 19:33:14 +00:00
if ( res % 90 == 0 ) {
graphics . drawString ( labels [ Math . floor ( res / 45 ) % 8 ] , xpos , y + 2 ) ;
graphics . fillRect ( xpos - 2 , Math . floor ( y + height * 0.6 ) , xpos + 2 , Math . floor ( y + height ) ) ;
} else if ( res % 45 == 0 ) {
graphics . drawString ( labels [ Math . floor ( res / 45 ) % 8 ] , xpos , y + 2 ) ;
graphics . fillRect ( xpos - 2 , Math . floor ( y + height * 0.75 ) , xpos + 2 , Math . floor ( y + height ) ) ;
} else if ( res % 15 == 0 ) {
graphics . fillRect ( xpos , Math . floor ( y + height * 0.9 ) , xpos + 1 , Math . floor ( y + height ) ) ;
}
xpos += increment * 15 ;
if ( xpos > width + 20 ) break ;
}
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let getCompassSlice = function ( compassDataSource ) {
2022-09-21 19:33:14 +00:00
let lastDrawn = Date . now ( ) - Math . random ( ) * 2000 ;
2022-11-02 17:02:47 +00:00
let lastDrawnValue = 0 ;
2022-09-21 19:33:14 +00:00
const buffers = 4 ;
let buf = [ ] ;
return {
2022-11-02 17:02:47 +00:00
refresh : function ( ) {
let bigChange = ( Math . abs ( lastDrawnValue - compassDataSource . getCourse ( ) ) > 2 ) ;
let old = ( Bangle . isLocked ( ) ? ( Date . now ( ) - lastDrawn > 2000 ) : true ) ;
return bigChange && old ;
} ,
2022-09-21 19:33:14 +00:00
draw : function ( graphics , x , y , height , width ) {
lastDrawn = Date . now ( ) ;
const max = 180 ;
const increment = width / max ;
graphics . clearRect ( x , y , x + width , y + height ) ;
2022-11-02 17:02:47 +00:00
lastDrawnValue = compassDataSource . getCourse ( ) ;
var start = lastDrawnValue - 90 ;
if ( isNaN ( lastDrawnValue ) ) start = - 90 ;
2022-09-21 19:33:14 +00:00
if ( start < 0 ) start += 360 ;
start = start % 360 ;
2022-10-13 17:43:56 +00:00
if ( WIDGETS . gpstrek . getState ( ) . acc && compassDataSource . getCourseType ( ) == "MAG" ) {
2022-09-21 19:33:14 +00:00
drawCompass ( graphics , 0 , y + width * 0.05 , height - width * 0.05 , width , increment , start ) ;
} else {
drawCompass ( graphics , 0 , y , height , width , increment , start ) ;
}
if ( compassDataSource . getPoints ) {
2022-12-04 20:13:10 +00:00
let points = compassDataSource . getPoints ( ) ; //storing this in a variable works around a minifier bug causing a problem in the next line: for(let a of a.getPoints())
for ( let p of points ) {
2022-11-05 20:45:51 +00:00
g . reset ( ) ;
2022-11-02 17:02:47 +00:00
var bpos = p . bearing - lastDrawnValue ;
2022-09-21 19:33:14 +00:00
if ( bpos > 180 ) bpos -= 360 ;
if ( bpos < - 180 ) bpos += 360 ;
bpos += 120 ;
let min = 0 ;
let max = 180 ;
if ( bpos <= min ) {
bpos = Math . floor ( width * 0.05 ) ;
} else if ( bpos >= max ) {
bpos = Math . ceil ( width * 0.95 ) ;
} else {
bpos = Math . round ( bpos * increment ) ;
}
2022-11-03 20:24:51 +00:00
if ( p . color ) {
graphics . setColor ( p . color ) ;
}
if ( p . icon ) {
graphics . drawImage ( p . icon , bpos , y + height - 12 , { rotate : 0 , scale : 2 } ) ;
} else {
graphics . fillCircle ( bpos , y + height - 12 , Math . floor ( width * 0.03 ) ) ;
}
2022-09-21 19:33:14 +00:00
}
}
if ( compassDataSource . getMarkers ) {
2022-12-04 20:13:10 +00:00
let markers = compassDataSource . getMarkers ( ) ; //storing this in a variable works around a minifier bug causing a problem in the next line: for(let a of a.getMarkers())
for ( let m of markers ) {
2022-11-05 20:45:51 +00:00
g . reset ( ) ;
2022-09-21 19:33:14 +00:00
g . setColor ( m . fillcolor ) ;
let mpos = m . xpos * width ;
if ( m . xpos < 0.05 ) mpos = Math . floor ( width * 0.05 ) ;
if ( m . xpos > 0.95 ) mpos = Math . ceil ( width * 0.95 ) ;
g . fillPoly ( triangle ( mpos , y + height - m . height , m . height , m . width ) ) ;
g . setColor ( m . linecolor ) ;
g . drawPoly ( triangle ( mpos , y + height - m . height , m . height , m . width ) , true ) ;
}
}
graphics . setColor ( g . theme . fg ) ;
graphics . fillRect ( x , y , Math . floor ( width * 0.05 ) , y + height ) ;
graphics . fillRect ( Math . ceil ( width * 0.95 ) , y , width , y + height ) ;
2022-10-13 17:43:56 +00:00
if ( WIDGETS . gpstrek . getState ( ) . acc && compassDataSource . getCourseType ( ) == "MAG" ) {
let xh = E . clip ( width * 0.5 - height / 2 + ( ( ( WIDGETS . gpstrek . getState ( ) . acc . x + 1 ) / 2 ) * height ) , width * 0.5 - height / 2 , width * 0.5 + height / 2 ) ;
let yh = E . clip ( y + ( ( ( WIDGETS . gpstrek . getState ( ) . acc . y + 1 ) / 2 ) * height ) , y , y + height ) ;
2022-09-21 19:33:14 +00:00
graphics . fillRect ( width * 0.5 - height / 2 , y , width * 0.5 + height / 2 , y + Math . floor ( width * 0.05 ) ) ;
graphics . setColor ( g . theme . bg ) ;
graphics . drawLine ( width * 0.5 - 5 , y , width * 0.5 - 5 , y + Math . floor ( width * 0.05 ) ) ;
graphics . drawLine ( width * 0.5 + 5 , y , width * 0.5 + 5 , y + Math . floor ( width * 0.05 ) ) ;
graphics . fillRect ( xh - 1 , y , xh + 1 , y + Math . floor ( width * 0.05 ) ) ;
let left = Math . floor ( width * 0.05 ) ;
let right = Math . ceil ( width * 0.95 ) ;
graphics . drawLine ( 0 , y + height / 2 - 5 , left , y + height / 2 - 5 ) ;
graphics . drawLine ( right , y + height / 2 - 5 , x + width , y + height / 2 - 5 ) ;
graphics . drawLine ( 0 , y + height / 2 + 5 , left , y + height / 2 + 5 ) ;
graphics . drawLine ( right , y + height / 2 + 5 , x + width , y + height / 2 + 5 ) ;
graphics . fillRect ( 0 , yh - 1 , left , yh + 1 ) ;
graphics . fillRect ( right , yh - 1 , x + width , yh + 1 ) ;
}
graphics . setColor ( g . theme . fg ) ;
graphics . drawRect ( Math . floor ( width * 0.05 ) , y , Math . ceil ( width * 0.95 ) , y + height ) ;
}
} ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let radians = function ( a ) {
2022-09-21 19:33:14 +00:00
return a * Math . PI / 180 ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let degrees = function ( a ) {
let d = a * 180 / Math . PI ;
2022-09-21 19:33:14 +00:00
return ( d + 360 ) % 360 ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let bearing = function ( a , b ) {
2022-09-21 19:33:14 +00:00
if ( ! a || ! b || ! a . lon || ! a . lat || ! b . lon || ! b . lat ) return Infinity ;
2022-10-13 17:43:56 +00:00
let delta = radians ( b . lon - a . lon ) ;
let alat = radians ( a . lat ) ;
let blat = radians ( b . lat ) ;
let y = Math . sin ( delta ) * Math . cos ( blat ) ;
let x = Math . cos ( alat ) * Math . sin ( blat ) -
2022-09-21 19:33:14 +00:00
Math . sin ( alat ) * Math . cos ( blat ) * Math . cos ( delta ) ;
return Math . round ( degrees ( Math . atan2 ( y , x ) ) ) ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let distance = function ( a , b ) {
2022-09-21 19:33:14 +00:00
if ( ! a || ! b || ! a . lon || ! a . lat || ! b . lon || ! b . lat ) return Infinity ;
2022-10-13 17:43:56 +00:00
let x = radians ( a . lon - b . lon ) * Math . cos ( radians ( ( a . lat + b . lat ) / 2 ) ) ;
let y = radians ( b . lat - a . lat ) ;
2022-09-21 19:33:14 +00:00
return Math . round ( Math . sqrt ( x * x + y * y ) * 6371000 ) ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-11-01 23:09:34 +00:00
let getAveragedCompass = function ( ) {
return Math . round ( WIDGETS . gpstrek . getState ( ) . avgComp ) ;
} ;
2022-10-13 17:43:56 +00:00
let triangle = function ( x , y , width , height ) {
2022-09-21 19:33:14 +00:00
return [
Math . round ( x ) , Math . round ( y ) ,
Math . round ( x + width * 0.5 ) , Math . round ( y + height ) ,
Math . round ( x - width * 0.5 ) , Math . round ( y + height )
] ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let onSwipe = function ( dir ) {
2022-10-19 19:04:46 +00:00
if ( dir < 0 ) {
nextScreen ( ) ;
} else if ( dir > 0 ) {
switchMenu ( ) ;
} else {
nextScreen ( ) ;
}
2022-10-13 17:43:56 +00:00
} ;
2022-10-19 19:04:46 +00:00
2022-10-13 17:43:56 +00:00
let setButtons = function ( ) {
2022-10-19 19:04:46 +00:00
let options = {
mode : "custom" ,
2022-10-21 15:04:53 +00:00
swipe : onSwipe ,
btn : nextScreen ,
touch : nextScreen
2022-10-19 19:04:46 +00:00
} ;
Bangle . setUI ( options ) ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let getApproxFileSize = function ( name ) {
2022-09-21 19:33:14 +00:00
let currentStart = STORAGE . getStats ( ) . totalBytes ;
let currentSize = 0 ;
for ( let i = currentStart ; i > 500 ; i /= 2 ) {
let currentDiff = i ;
//print("Searching", currentDiff);
while ( STORAGE . read ( name , currentSize + currentDiff , 1 ) == "" ) {
//print("Loop", currentDiff);
currentDiff = Math . ceil ( currentDiff / 2 ) ;
}
i = currentDiff * 2 ;
currentSize += currentDiff ;
}
return currentSize ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let parseRouteData = function ( filename , progressMonitor ) {
2022-09-21 19:33:14 +00:00
let routeInfo = { } ;
routeInfo . filename = filename ;
routeInfo . refs = [ ] ;
let c = { } ;
let scanOffset = 0 ;
routeInfo . length = 0 ;
routeInfo . count = 0 ;
routeInfo . mirror = false ;
let lastSeenWaypoint ;
let lastSeenAlt ;
let waypoint = { } ;
routeInfo . up = 0 ;
routeInfo . down = 0 ;
2023-05-12 08:13:01 +00:00
2022-09-21 19:33:14 +00:00
let size = getApproxFileSize ( filename ) ;
while ( ( scanOffset = getEntry ( filename , scanOffset , waypoint ) ) > 0 ) {
if ( routeInfo . count % 5 == 0 ) progressMonitor ( scanOffset , "Loading" , size ) ;
if ( lastSeenWaypoint ) {
routeInfo . length += distance ( lastSeenWaypoint , waypoint ) ;
let diff = waypoint . alt - lastSeenAlt ;
//print("Distance", routeInfo.length, "alt", lastSeenAlt, waypoint.alt, diff);
if ( waypoint . alt && lastSeenAlt && diff > 3 ) {
if ( lastSeenAlt < waypoint . alt ) {
//print("Up", diff);
routeInfo . up += diff ;
} else {
//print("Down", diff);
routeInfo . down += diff ;
}
}
}
routeInfo . count ++ ;
routeInfo . refs . push ( waypoint . fileOffset ) ;
lastSeenWaypoint = waypoint ;
if ( ! isNaN ( waypoint . alt ) ) lastSeenAlt = waypoint . alt ;
waypoint = { } ;
}
set ( routeInfo , 0 ) ;
return routeInfo ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2023-05-14 13:37:54 +00:00
let hasPrev = function ( route , index ) {
if ( ! index ) index = route . index ;
2022-09-21 19:33:14 +00:00
if ( route . mirror ) return route . index < ( route . count - 1 ) ;
return route . index > 0 ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2023-05-14 13:37:54 +00:00
let hasNext = function ( route , index ) {
if ( ! index ) index = route . index ;
2022-09-21 19:33:14 +00:00
if ( route . mirror ) return route . index > 0 ;
return route . index < ( route . count - 1 ) ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2023-05-14 13:37:54 +00:00
let getNext = function ( route , index ) {
if ( ! index ) index = route . index ;
if ( ! hasNext ( route , index ) ) return ;
if ( route . mirror ) -- index ;
if ( ! route . mirror ) ++ index ;
let result = { } ;
getEntry ( route . filename , route . refs [ index ] , result ) ;
return result ;
} ;
2022-10-13 17:43:56 +00:00
let next = function ( route ) {
2022-09-21 19:33:14 +00:00
if ( ! hasNext ( route ) ) return ;
if ( route . mirror ) set ( route , -- route . index ) ;
if ( ! route . mirror ) set ( route , ++ route . index ) ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let set = function ( route , index ) {
2022-09-21 19:33:14 +00:00
route . currentWaypoint = { } ;
route . index = index ;
getEntry ( route . filename , route . refs [ index ] , route . currentWaypoint ) ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let prev = function ( route ) {
2022-09-21 19:33:14 +00:00
if ( ! hasPrev ( route ) ) return ;
if ( route . mirror ) set ( route , ++ route . index ) ;
if ( ! route . mirror ) set ( route , -- route . index ) ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
let lastMirror ;
let cachedLast ;
2022-10-13 17:43:56 +00:00
let getLast = function ( route ) {
2022-09-21 19:33:14 +00:00
let wp = { } ;
if ( lastMirror != route . mirror ) {
if ( route . mirror ) getEntry ( route . filename , route . refs [ 0 ] , wp ) ;
if ( ! route . mirror ) getEntry ( route . filename , route . refs [ route . count - 1 ] , wp ) ;
lastMirror = route . mirror ;
cachedLast = wp ;
}
return cachedLast ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let removeMenu = function ( ) {
2022-09-21 19:33:14 +00:00
E . showMenu ( ) ;
switchNav ( ) ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let showProgress = function ( progress , title , max ) {
2022-09-21 19:33:14 +00:00
//print("Progress",progress,max)
let message = title ? title : "Loading" ;
if ( max ) {
message += " " + E . clip ( ( progress / max * 100 ) , 0 , 100 ) . toFixed ( 0 ) + "%" ;
} else {
let dots = progress % 4 ;
for ( let i = 0 ; i < dots ; i ++ ) message += "." ;
for ( let i = dots ; i < 4 ; i ++ ) message += " " ;
}
E . showMessage ( message ) ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let handleLoading = function ( c ) {
2022-09-21 19:33:14 +00:00
E . showMenu ( ) ;
2022-10-13 17:43:56 +00:00
WIDGETS . gpstrek . getState ( ) . route = parseRouteData ( c , showProgress ) ;
WIDGETS . gpstrek . getState ( ) . waypoint = null ;
WIDGETS . gpstrek . getState ( ) . route . mirror = false ;
2022-10-21 15:04:53 +00:00
removeMenu ( ) ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let showRouteSelector = function ( ) {
2022-10-21 15:04:53 +00:00
var menu = {
2022-09-21 19:33:14 +00:00
"" : {
back : showRouteMenu ,
}
} ;
2022-11-02 21:50:00 +00:00
STORAGE . list ( /\.trf$/ ) . forEach ( ( file ) => {
2023-05-12 08:13:01 +00:00
menu [ file ] = ( ) => { handleLoading ( file ) ; } ;
2022-11-02 21:50:00 +00:00
} ) ;
2022-09-21 19:33:14 +00:00
E . showMenu ( menu ) ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let showRouteMenu = function ( ) {
2022-10-21 15:04:53 +00:00
var menu = {
2022-09-21 19:33:14 +00:00
"" : {
"title" : "Route" ,
back : showMenu ,
} ,
"Select file" : showRouteSelector
} ;
2022-10-13 17:43:56 +00:00
if ( WIDGETS . gpstrek . getState ( ) . route ) {
2022-09-21 19:33:14 +00:00
menu . Mirror = {
2022-10-13 17:43:56 +00:00
value : WIDGETS . gpstrek . getState ( ) && WIDGETS . gpstrek . getState ( ) . route && ! ! WIDGETS . gpstrek . getState ( ) . route . mirror || false ,
2022-09-21 19:33:14 +00:00
onchange : v => {
2022-10-13 17:43:56 +00:00
WIDGETS . gpstrek . getState ( ) . route . mirror = v ;
2022-09-21 19:33:14 +00:00
}
} ;
menu [ 'Select closest waypoint' ] = function ( ) {
2022-10-13 17:43:56 +00:00
if ( WIDGETS . gpstrek . getState ( ) . currentPos && WIDGETS . gpstrek . getState ( ) . currentPos . lat ) {
setClosestWaypoint ( WIDGETS . gpstrek . getState ( ) . route , null , showProgress ) ; removeMenu ( ) ;
2022-09-21 19:33:14 +00:00
} else {
E . showAlert ( "No position" ) . then ( ( ) => { E . showMenu ( menu ) ; } ) ;
}
} ;
menu [ 'Select closest waypoint (not visited)' ] = function ( ) {
2022-10-13 17:43:56 +00:00
if ( WIDGETS . gpstrek . getState ( ) . currentPos && WIDGETS . gpstrek . getState ( ) . currentPos . lat ) {
setClosestWaypoint ( WIDGETS . gpstrek . getState ( ) . route , WIDGETS . gpstrek . getState ( ) . route . index , showProgress ) ; removeMenu ( ) ;
2022-09-21 19:33:14 +00:00
} else {
E . showAlert ( "No position" ) . then ( ( ) => { E . showMenu ( menu ) ; } ) ;
}
} ;
menu [ 'Select waypoint' ] = {
2022-10-13 17:43:56 +00:00
value : WIDGETS . gpstrek . getState ( ) . route . index ,
min : 1 , max : WIDGETS . gpstrek . getState ( ) . route . count , step : 1 ,
2022-10-21 15:04:53 +00:00
onchange : v => { set ( WIDGETS . gpstrek . getState ( ) . route , v - 1 ) ; }
2022-09-21 19:33:14 +00:00
} ;
menu [ 'Select waypoint as current position' ] = function ( ) {
2022-10-13 17:43:56 +00:00
WIDGETS . gpstrek . getState ( ) . currentPos . lat = WIDGETS . gpstrek . getState ( ) . route . currentWaypoint . lat ;
WIDGETS . gpstrek . getState ( ) . currentPos . lon = WIDGETS . gpstrek . getState ( ) . route . currentWaypoint . lon ;
WIDGETS . gpstrek . getState ( ) . currentPos . alt = WIDGETS . gpstrek . getState ( ) . route . currentWaypoint . alt ;
2022-09-21 19:33:14 +00:00
removeMenu ( ) ;
} ;
}
2022-10-13 17:43:56 +00:00
if ( WIDGETS . gpstrek . getState ( ) . route && hasPrev ( WIDGETS . gpstrek . getState ( ) . route ) )
2022-10-21 15:04:53 +00:00
menu [ 'Previous waypoint' ] = function ( ) { prev ( WIDGETS . gpstrek . getState ( ) . route ) ; removeMenu ( ) ; } ;
2022-10-13 17:43:56 +00:00
if ( WIDGETS . gpstrek . getState ( ) . route && hasNext ( WIDGETS . gpstrek . getState ( ) . route ) )
2022-10-21 15:04:53 +00:00
menu [ 'Next waypoint' ] = function ( ) { next ( WIDGETS . gpstrek . getState ( ) . route ) ; removeMenu ( ) ; } ;
2022-09-21 19:33:14 +00:00
E . showMenu ( menu ) ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let showWaypointSelector = function ( ) {
2022-09-21 19:33:14 +00:00
let waypoints = require ( "waypoints" ) . load ( ) ;
2022-10-21 15:04:53 +00:00
var menu = {
2022-09-21 19:33:14 +00:00
"" : {
back : showWaypointMenu ,
}
} ;
2022-11-02 21:23:37 +00:00
waypoints . forEach ( ( wp , c ) => {
2022-09-21 19:33:14 +00:00
menu [ waypoints [ c ] . name ] = function ( ) {
2022-10-21 15:04:53 +00:00
WIDGETS . gpstrek . getState ( ) . waypoint = waypoints [ c ] ;
WIDGETS . gpstrek . getState ( ) . waypointIndex = c ;
WIDGETS . gpstrek . getState ( ) . route = null ;
2022-09-21 19:33:14 +00:00
removeMenu ( ) ;
} ;
2022-11-02 21:23:37 +00:00
} ) ;
2022-09-21 19:33:14 +00:00
E . showMenu ( menu ) ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let showCalibrationMenu = function ( ) {
2022-09-21 19:33:14 +00:00
let menu = {
"" : {
"title" : "Calibration" ,
back : showMenu ,
} ,
"Barometer (GPS)" : ( ) => {
2022-10-13 17:43:56 +00:00
if ( ! WIDGETS . gpstrek . getState ( ) . currentPos || isNaN ( WIDGETS . gpstrek . getState ( ) . currentPos . alt ) ) {
2022-09-21 19:33:14 +00:00
E . showAlert ( "No GPS altitude" ) . then ( ( ) => { E . showMenu ( menu ) ; } ) ;
} else {
2022-10-13 17:43:56 +00:00
WIDGETS . gpstrek . getState ( ) . calibAltDiff = WIDGETS . gpstrek . getState ( ) . altitude - WIDGETS . gpstrek . getState ( ) . currentPos . alt ;
E . showAlert ( "Calibrated Altitude Difference: " + WIDGETS . gpstrek . getState ( ) . calibAltDiff . toFixed ( 0 ) ) . then ( ( ) => { removeMenu ( ) ; } ) ;
2022-09-21 19:33:14 +00:00
}
} ,
"Barometer (Manual)" : {
2022-10-13 17:43:56 +00:00
value : Math . round ( WIDGETS . gpstrek . getState ( ) . currentPos && ( WIDGETS . gpstrek . getState ( ) . currentPos . alt != undefined && ! isNaN ( WIDGETS . gpstrek . getState ( ) . currentPos . alt ) ) ? WIDGETS . gpstrek . getState ( ) . currentPos . alt : WIDGETS . gpstrek . getState ( ) . altitude ) ,
2022-09-21 19:33:14 +00:00
min : - 2000 , max : 10000 , step : 1 ,
2022-10-21 15:04:53 +00:00
onchange : v => { WIDGETS . gpstrek . getState ( ) . calibAltDiff = WIDGETS . gpstrek . getState ( ) . altitude - v ; }
2022-09-21 19:33:14 +00:00
} ,
"Reset Compass" : ( ) => { Bangle . resetCompass ( ) ; removeMenu ( ) ; } ,
} ;
E . showMenu ( menu ) ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let showWaypointMenu = function ( ) {
2022-09-21 19:33:14 +00:00
let menu = {
"" : {
"title" : "Waypoint" ,
back : showMenu ,
} ,
"Select waypoint" : showWaypointSelector ,
} ;
E . showMenu ( menu ) ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let showBackgroundMenu = function ( ) {
2022-10-13 18:36:47 +00:00
let menu = {
"" : {
"title" : "Background" ,
back : showMenu ,
} ,
2022-10-13 17:43:56 +00:00
"Start" : ( ) => { E . showPrompt ( "Start?" ) . then ( ( v ) => { if ( v ) { WIDGETS . gpstrek . start ( true ) ; removeMenu ( ) ; } else { showMenu ( ) ; } } ) . catch ( ( ) => { showMenu ( ) ; } ) ; } ,
"Stop" : ( ) => { E . showPrompt ( "Stop?" ) . then ( ( v ) => { if ( v ) { WIDGETS . gpstrek . stop ( true ) ; removeMenu ( ) ; } else { showMenu ( ) ; } } ) . catch ( ( ) => { showMenu ( ) ; } ) ; } ,
2022-10-13 18:36:47 +00:00
} ;
E . showMenu ( menu ) ;
2022-10-13 17:43:56 +00:00
} ;
2022-10-13 18:36:47 +00:00
2022-10-13 17:43:56 +00:00
let showMenu = function ( ) {
2022-10-21 15:04:53 +00:00
var mainmenu = {
2022-09-21 19:33:14 +00:00
"" : {
"title" : "Main" ,
back : removeMenu ,
} ,
"Route" : showRouteMenu ,
"Waypoint" : showWaypointMenu ,
2022-10-13 18:36:47 +00:00
"Background" : showBackgroundMenu ,
2022-09-21 19:33:14 +00:00
"Calibration" : showCalibrationMenu ,
2022-10-21 15:04:53 +00:00
"Reset" : ( ) => { E . showPrompt ( "Do Reset?" ) . then ( ( v ) => { if ( v ) { WIDGETS . gpstrek . resetState ( ) ; removeMenu ( ) ; } else { E . showMenu ( mainmenu ) ; } } ) . catch ( ( ) => { E . showMenu ( mainmenu ) ; } ) ; } ,
2022-10-30 17:31:31 +00:00
"Info rows" : {
2022-10-13 17:43:56 +00:00
value : WIDGETS . gpstrek . getState ( ) . numberOfSlices ,
2022-09-21 19:33:14 +00:00
min : 1 , max : 6 , step : 1 ,
2022-10-21 15:04:53 +00:00
onchange : v => { WIDGETS . gpstrek . getState ( ) . numberOfSlices = v ; }
2022-09-21 19:33:14 +00:00
} ,
} ;
E . showMenu ( mainmenu ) ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let switchMenu = function ( ) {
2022-10-21 15:04:53 +00:00
stopDrawing ( ) ;
2022-10-13 17:43:56 +00:00
showMenu ( ) ;
} ;
2022-09-21 19:33:14 +00:00
2022-10-21 15:04:53 +00:00
let stopDrawing = function ( ) {
if ( drawTimeout ) clearTimeout ( drawTimeout ) ;
scheduleDraw = false ;
} ;
2022-10-13 17:43:56 +00:00
let drawInTimeout = function ( ) {
if ( global . drawTimeout ) clearTimeout ( drawTimeout ) ;
drawTimeout = setTimeout ( ( ) => {
drawTimeout = undefined ;
2022-09-21 19:33:14 +00:00
draw ( ) ;
2023-05-12 08:19:23 +00:00
} , 500 ) ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let switchNav = function ( ) {
2022-09-21 19:33:14 +00:00
if ( ! screen ) screen = 1 ;
setButtons ( ) ;
scheduleDraw = true ;
2022-10-21 15:04:53 +00:00
firstDraw = true ;
2022-09-21 19:33:14 +00:00
drawInTimeout ( ) ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let nextScreen = function ( ) {
2022-09-21 19:33:14 +00:00
screen ++ ;
if ( screen > maxScreens ) {
screen = 1 ;
}
2022-10-13 17:43:56 +00:00
drawInTimeout ( ) ;
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let setClosestWaypoint = function ( route , startindex , progress ) {
if ( startindex >= WIDGETS . gpstrek . getState ( ) . route . count ) startindex = WIDGETS . gpstrek . getState ( ) . route . count - 1 ;
if ( ! WIDGETS . gpstrek . getState ( ) . currentPos . lat ) {
2022-09-21 19:33:14 +00:00
set ( route , startindex ) ;
return ;
}
let minDist = 100000000000000 ;
let minIndex = 0 ;
for ( let i = startindex ? startindex : 0 ; i < route . count - 1 ; i ++ ) {
if ( progress && ( i % 5 == 0 ) ) progress ( i - ( startindex ? startindex : 0 ) , "Searching" , route . count ) ;
let wp = { } ;
getEntry ( route . filename , route . refs [ i ] , wp ) ;
2022-10-13 17:43:56 +00:00
let curDist = distance ( WIDGETS . gpstrek . getState ( ) . currentPos , wp ) ;
2022-09-21 19:33:14 +00:00
if ( curDist < minDist ) {
minDist = curDist ;
minIndex = i ;
} else {
if ( startindex ) break ;
}
}
set ( route , minIndex ) ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
2022-11-03 20:24:51 +00:00
const finishIcon = atob ( "CggB//meZmeZ+Z5n/w==" ) ;
2022-09-21 19:33:14 +00:00
const compassSliceData = {
getCourseType : function ( ) {
2022-10-13 17:43:56 +00:00
return ( WIDGETS . gpstrek . getState ( ) . currentPos && WIDGETS . gpstrek . getState ( ) . currentPos . course ) ? "GPS" : "MAG" ;
2022-09-21 19:33:14 +00:00
} ,
getCourse : function ( ) {
2022-10-13 17:43:56 +00:00
if ( compassSliceData . getCourseType ( ) == "GPS" ) return WIDGETS . gpstrek . getState ( ) . currentPos . course ;
2022-11-01 23:09:34 +00:00
return getAveragedCompass ( ) ;
2022-09-21 19:33:14 +00:00
} ,
getPoints : function ( ) {
let points = [ ] ;
2022-10-13 17:43:56 +00:00
if ( WIDGETS . gpstrek . getState ( ) . currentPos && WIDGETS . gpstrek . getState ( ) . currentPos . lon && WIDGETS . gpstrek . getState ( ) . route ) {
points . push ( { bearing : bearing ( WIDGETS . gpstrek . getState ( ) . currentPos , getLast ( WIDGETS . gpstrek . getState ( ) . route ) ) , icon : finishIcon } ) ;
2022-09-21 19:33:14 +00:00
}
2022-10-13 17:43:56 +00:00
if ( WIDGETS . gpstrek . getState ( ) . currentPos && WIDGETS . gpstrek . getState ( ) . currentPos . lon && WIDGETS . gpstrek . getState ( ) . waypoint ) {
points . push ( { bearing : bearing ( WIDGETS . gpstrek . getState ( ) . currentPos , WIDGETS . gpstrek . getState ( ) . waypoint ) , icon : finishIcon } ) ;
2022-11-03 20:09:59 +00:00
}
2023-05-12 08:13:01 +00:00
if ( WIDGETS . gpstrek . getState ( ) . currentPos && WIDGETS . gpstrek . getState ( ) . currentPos . lon && WIDGETS . gpstrek . getState ( ) . route && WIDGETS . gpstrek . getState ( ) . route . currentWaypoint ) {
points . push ( { bearing : bearing ( WIDGETS . gpstrek . getState ( ) . currentPos , WIDGETS . gpstrek . getState ( ) . route . currentWaypoint ) , color : "#0f0" } ) ;
}
2022-09-21 19:33:14 +00:00
return points ;
} ,
getMarkers : function ( ) {
return [ { xpos : 0.5 , width : 10 , height : 10 , linecolor : g . theme . fg , fillcolor : "#f00" } ] ;
}
} ;
2023-05-14 13:37:54 +00:00
const mapSliceData = {
getRoute : function ( ) {
return WIDGETS . gpstrek . getState ( ) . route ;
}
} ;
2022-09-21 19:33:14 +00:00
const waypointData = {
icon : atob ( "EBCBAAAAAAAAAAAAcIB+zg/uAe4AwACAAAAAAAAAAAAAAAAA" ) ,
getProgress : function ( ) {
2022-10-13 17:43:56 +00:00
return ( WIDGETS . gpstrek . getState ( ) . route . index + 1 ) + "/" + WIDGETS . gpstrek . getState ( ) . route . count ;
2022-09-21 19:33:14 +00:00
} ,
getTarget : function ( ) {
2023-05-12 08:13:01 +00:00
2022-10-13 17:43:56 +00:00
return WIDGETS . gpstrek . getState ( ) . route . currentWaypoint ;
2022-09-21 19:33:14 +00:00
} ,
getStart : function ( ) {
2022-10-13 17:43:56 +00:00
return WIDGETS . gpstrek . getState ( ) . currentPos ;
2022-09-21 19:33:14 +00:00
}
} ;
const finishData = {
icon : atob ( "EBABAAA/4DmgJmAmYDmgOaAmYD/gMAAwADAAMAAwAAAAAAA=" ) ,
getTarget : function ( ) {
2022-10-13 17:43:56 +00:00
if ( WIDGETS . gpstrek . getState ( ) . route ) return getLast ( WIDGETS . gpstrek . getState ( ) . route ) ;
if ( WIDGETS . gpstrek . getState ( ) . waypoint ) return WIDGETS . gpstrek . getState ( ) . waypoint ;
2022-09-21 19:33:14 +00:00
} ,
getStart : function ( ) {
2022-10-13 17:43:56 +00:00
return WIDGETS . gpstrek . getState ( ) . currentPos ;
2022-09-21 19:33:14 +00:00
}
} ;
2022-10-13 17:43:56 +00:00
let getSliceHeight = function ( number ) {
return Math . floor ( Bangle . appRect . h / WIDGETS . gpstrek . getState ( ) . numberOfSlices ) ;
} ;
2022-09-21 19:33:14 +00:00
let compassSlice = getCompassSlice ( compassSliceData ) ;
2023-05-14 13:37:54 +00:00
let mapSlice = getMapSlice ( mapSliceData ) ;
2022-09-21 19:33:14 +00:00
let waypointSlice = getTargetSlice ( waypointData ) ;
let finishSlice = getTargetSlice ( finishData ) ;
let eleSlice = getDoubleLineSlice ( "Up" , "Down" , ( ) => {
2022-10-13 17:43:56 +00:00
return loc . distance ( WIDGETS . gpstrek . getState ( ) . up , 3 ) + "/" + ( WIDGETS . gpstrek . getState ( ) . route ? loc . distance ( WIDGETS . gpstrek . getState ( ) . route . up , 3 ) : "---" ) ;
2022-09-21 19:33:14 +00:00
} , ( ) => {
2022-10-13 17:43:56 +00:00
return loc . distance ( WIDGETS . gpstrek . getState ( ) . down , 3 ) + "/" + ( WIDGETS . gpstrek . getState ( ) . route ? loc . distance ( WIDGETS . gpstrek . getState ( ) . route . down , 3 ) : "---" ) ;
2022-09-21 19:33:14 +00:00
} ) ;
let statusSlice = getDoubleLineSlice ( "Speed" , "Alt" , ( ) => {
let speed = 0 ;
2022-10-13 17:43:56 +00:00
if ( WIDGETS . gpstrek . getState ( ) . currentPos && WIDGETS . gpstrek . getState ( ) . currentPos . speed ) speed = WIDGETS . gpstrek . getState ( ) . currentPos . speed ;
2022-09-21 19:33:14 +00:00
return loc . speed ( speed , 2 ) ;
} , ( ) => {
let alt = Infinity ;
2022-10-13 17:43:56 +00:00
if ( ! isNaN ( WIDGETS . gpstrek . getState ( ) . altitude ) ) {
alt = isNaN ( WIDGETS . gpstrek . getState ( ) . calibAltDiff ) ? WIDGETS . gpstrek . getState ( ) . altitude : ( WIDGETS . gpstrek . getState ( ) . altitude - WIDGETS . gpstrek . getState ( ) . calibAltDiff ) ;
2022-09-21 19:33:14 +00:00
}
2022-10-13 17:43:56 +00:00
if ( WIDGETS . gpstrek . getState ( ) . currentPos && WIDGETS . gpstrek . getState ( ) . currentPos . alt ) alt = WIDGETS . gpstrek . getState ( ) . currentPos . alt ;
if ( isNaN ( alt ) ) return "---" ;
2022-09-21 19:33:14 +00:00
return loc . distance ( alt , 3 ) ;
} ) ;
let status2Slice = getDoubleLineSlice ( "Compass" , "GPS" , ( ) => {
2022-11-01 23:09:34 +00:00
return getAveragedCompass ( ) + "°" ;
2022-09-21 19:33:14 +00:00
} , ( ) => {
let course = "---°" ;
2022-10-13 17:43:56 +00:00
if ( WIDGETS . gpstrek . getState ( ) . currentPos && WIDGETS . gpstrek . getState ( ) . currentPos . course ) course = WIDGETS . gpstrek . getState ( ) . currentPos . course + "°" ;
2022-09-21 19:33:14 +00:00
return course ;
} , 200 ) ;
let healthSlice = getDoubleLineSlice ( "Heart" , "Steps" , ( ) => {
2022-10-13 17:43:56 +00:00
return WIDGETS . gpstrek . getState ( ) . bpm || "---" ;
2022-09-21 19:33:14 +00:00
} , ( ) => {
2022-10-21 15:04:53 +00:00
return ! isNaN ( WIDGETS . gpstrek . getState ( ) . steps ) ? WIDGETS . gpstrek . getState ( ) . steps : "---" ;
2022-09-21 19:33:14 +00:00
} ) ;
let system2Slice = getDoubleLineSlice ( "Bat" , "" , ( ) => {
2022-11-01 23:31:06 +00:00
return ( Bangle . isCharging ( ) ? "+" : "" ) + E . getBattery ( ) . toFixed ( 0 ) + "% " + ( analogRead ( D3 ) * 4.2 / BAT _FULL ) . toFixed ( 2 ) + "V" ;
2022-09-21 19:33:14 +00:00
} , ( ) => {
return "" ;
} ) ;
let systemSlice = getDoubleLineSlice ( "RAM" , "Storage" , ( ) => {
let ram = process . memory ( false ) ;
return ( ( ram . blocksize * ram . free ) / 1024 ) . toFixed ( 0 ) + "kB" ;
} , ( ) => {
return ( STORAGE . getFree ( ) / 1024 ) . toFixed ( 0 ) + "kB" ;
} ) ;
2022-10-13 17:43:56 +00:00
let updateSlices = function ( ) {
2022-09-21 19:33:14 +00:00
slices = [ ] ;
slices . push ( compassSlice ) ;
2023-05-14 13:37:54 +00:00
if ( WIDGETS . gpstrek . getState ( ) . route ) slices . push ( mapSlice ) ;
2022-10-13 17:43:56 +00:00
if ( WIDGETS . gpstrek . getState ( ) . currentPos && WIDGETS . gpstrek . getState ( ) . currentPos . lat && WIDGETS . gpstrek . getState ( ) . route && WIDGETS . gpstrek . getState ( ) . route . currentWaypoint && WIDGETS . gpstrek . getState ( ) . route . index < WIDGETS . gpstrek . getState ( ) . route . count - 1 ) {
2022-09-21 19:33:14 +00:00
slices . push ( waypointSlice ) ;
}
2022-10-13 17:43:56 +00:00
if ( WIDGETS . gpstrek . getState ( ) . currentPos && WIDGETS . gpstrek . getState ( ) . currentPos . lat && ( WIDGETS . gpstrek . getState ( ) . route || WIDGETS . gpstrek . getState ( ) . waypoint ) ) {
2022-09-21 19:33:14 +00:00
slices . push ( finishSlice ) ;
}
2022-10-13 17:43:56 +00:00
if ( ( WIDGETS . gpstrek . getState ( ) . route && WIDGETS . gpstrek . getState ( ) . route . down !== undefined ) || WIDGETS . gpstrek . getState ( ) . down != undefined ) {
2022-09-21 19:33:14 +00:00
slices . push ( eleSlice ) ;
}
slices . push ( statusSlice ) ;
slices . push ( status2Slice ) ;
slices . push ( healthSlice ) ;
slices . push ( systemSlice ) ;
slices . push ( system2Slice ) ;
2022-10-13 17:43:56 +00:00
maxScreens = Math . ceil ( slices . length / WIDGETS . gpstrek . getState ( ) . numberOfSlices ) ;
} ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let clear = function ( ) {
g . clearRect ( Bangle . appRect ) ;
} ;
2022-09-21 19:33:14 +00:00
2023-05-12 08:19:23 +00:00
let minimumDistance = Number . MAX _VALUE ;
let lastSearch = 0 ;
let updateInProgress = false ;
let updateRouting = function ( ) {
if ( updateInProgress ) return ;
updateInProgress = true ;
if ( WIDGETS . gpstrek . getState ( ) . route && WIDGETS . gpstrek . getState ( ) . currentPos . lat ) {
let currentDistanceToTarget = distance ( WIDGETS . gpstrek . getState ( ) . currentPos , WIDGETS . gpstrek . getState ( ) . route . currentWaypoint ) ;
if ( currentDistanceToTarget < minimumDistance ) {
minimumDistance = currentDistanceToTarget ;
}
let nextAvailable = hasNext ( WIDGETS . gpstrek . getState ( ) . route ) ;
if ( currentDistanceToTarget < 30 && nextAvailable ) {
next ( WIDGETS . gpstrek . getState ( ) . route ) ;
minimumDistance = Number . MAX _VALUE ;
} else if ( lastSearch + 15000 < Date . now ( ) && minimumDistance < currentDistanceToTarget - 30 ) {
stopDrawing ( ) ;
Bangle . buzz ( 1000 ) ;
setClosestWaypoint ( WIDGETS . gpstrek . getState ( ) . route , WIDGETS . gpstrek . getState ( ) . route . index , showProgress ) ;
minimumDistance = Number . MAX _VALUE ;
lastSearch = Date . now ( ) ;
switchNav ( ) ;
}
}
updateInProgress = false ;
} ;
2022-10-13 17:43:56 +00:00
let draw = function ( ) {
if ( ! global . screen ) return ;
let ypos = Bangle . appRect . y ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let firstSlice = ( screen - 1 ) * WIDGETS . gpstrek . getState ( ) . numberOfSlices ;
2022-09-21 19:33:14 +00:00
updateSlices ( ) ;
let force = lastDrawnScreen != screen || firstDraw ;
if ( force ) {
clear ( ) ;
2022-11-05 22:45:40 +00:00
}
2022-10-13 17:43:56 +00:00
if ( firstDraw ) Bangle . drawWidgets ( ) ;
2022-09-21 19:33:14 +00:00
lastDrawnScreen = screen ;
2023-05-12 08:19:23 +00:00
updateRouting ( ) ;
2022-09-21 19:33:14 +00:00
2022-10-13 17:43:56 +00:00
let sliceHeight = getSliceHeight ( ) ;
for ( let slice of slices . slice ( firstSlice , firstSlice + WIDGETS . gpstrek . getState ( ) . numberOfSlices ) ) {
2022-09-21 19:33:14 +00:00
g . reset ( ) ;
if ( ! slice . refresh || slice . refresh ( ) || force ) slice . draw ( g , 0 , ypos , sliceHeight , g . getWidth ( ) ) ;
ypos += sliceHeight + 1 ;
g . drawLine ( 0 , ypos - 1 , g . getWidth ( ) , ypos - 1 ) ;
}
2023-05-12 08:13:01 +00:00
2023-05-12 08:19:23 +00:00
updateRouting ( ) ;
2022-11-05 22:45:40 +00:00
if ( scheduleDraw ) {
drawInTimeout ( ) ;
}
2022-09-21 19:33:14 +00:00
firstDraw = false ;
2022-10-13 17:43:56 +00:00
} ;
2022-09-21 19:33:14 +00:00
switchNav ( ) ;
2022-10-13 17:43:56 +00:00
clear ( ) ;
}
2023-05-12 08:19:23 +00:00