@@ -4,14 +4,23 @@ const storage = require('Storage');
44const widget_utils = require ( 'widget_utils' ) ;
55const global_settings = storage . readJSON ( "setting.json" , true ) || { } ;
66const LOCATION_FILE = "mylocation.json" ;
7- const h = g . getHeight ( ) ;
8- const w = g . getWidth ( ) ;
97let location ;
108let cachedSunTimes = null ;
119let lastSunCalcDate = null ;
12- var prevVals = { } ;
10+ var valsArrs = { } ;
1311let drawTimeout ;
1412
13+ const h = g . getHeight ( ) ;
14+ const w = g . getWidth ( ) ;
15+ const fontSize = 13 ;
16+ const lineHeight = 16 ;
17+ const buttonHeight = 12 ;
18+ const buttonX = 78 ;
19+ const buttonY = 3 ;
20+ const headerHeight = 16 ;
21+ const usableHeight = h - headerHeight ;
22+ const maxLines = Math . floor ( usableHeight / lineHeight ) ;
23+
1524var settings = {
1625 hr_12 : global_settings [ "12hour" ] !== undefined ? global_settings [ "12hour" ] : false ,
1726 dark_mode : g . theme . dark
@@ -26,22 +35,6 @@ let clrs = {
2635 brackets : g . theme . fg ,
2736} ;
2837
29-
30- let jsonText ;
31- let lines = [ ] ;
32- let fontSize = 13 ;
33- const lineHeight = 16 ;
34-
35- const buttonHeight = 12 ;
36- const buttonX = 78 ;
37- const buttonY = 3 ;
38-
39- let valuePositions = [ ] ;
40- const headerHeight = 16 ;
41- const usableHeight = h - headerHeight ;
42- const maxLines = Math . floor ( usableHeight / lineHeight ) ;
43- var numWidth = 0 ;
44-
4538// requires the myLocation app
4639let loadLocation = function ( ) {
4740 location = require ( "Storage" ) . readJSON ( LOCATION_FILE , 1 ) || { } ;
@@ -110,45 +103,49 @@ let getVal = function(now, loc) {
110103 return vals ;
111104} ;
112105
113- let loadJson = function ( ) {
106+
107+ let getKeyValRegex = function ( line ) {
108+ return line . trim ( ) . match ( / ^ " ( [ ^ " ] + ) " : \s * ( .+ ) $ / ) ;
109+ } ;
110+
111+ let getIndentRegex = function ( line ) {
112+ const indentMatch = line . match ( / ^ ( \s * ) / ) ;
113+ return indentMatch ? indentMatch [ 1 ] : "" ;
114+ } ;
115+
116+ let getJsonLine = function ( ) {
114117 const now = new Date ( ) ;
115118 const vals = getVal ( now , location ) ;
116119 //vals.steps = null; // For testing; uncomment to see the steps not appear
117120 //location.location = null; // For testing, if null, the time becomes an struct to take up sun's struct
118- let raw ;
119-
120- if ( location . location !== null ) {
121- raw = {
122- time : vals . time ,
123- dt : vals . date ,
124- sun : {
125- rise : vals . rise ,
126- set : vals . set ,
127- } ,
128- "batt_%" : vals . batt_pct ,
129- } ;
130- } else {
131- raw = {
132- time : {
133- hr : getHr ( now . getHours ( ) ) [ 0 ] ,
134- min : now . getMinutes ( ) ,
121+ const hasLoc = location . location !== null ;
122+ let raw = {
123+ time : hasLoc
124+ ? vals . time
125+ : {
126+ hr : getHr ( now . getHours ( ) ) [ 0 ] ,
127+ min : now . getMinutes ( ) ,
135128 } ,
136- dt : vals . date ,
137- "batt_%" : vals . batt_pct ,
129+ dt : vals . date ,
130+ "batt_%" : vals . batt_pct ,
131+ } ;
132+ if ( vals . steps != null ) {
133+ raw . steps = vals . steps ;
134+ }
135+ if ( hasLoc ) {
136+ raw . sun = {
137+ rise : vals . rise ,
138+ set : vals . set ,
138139 } ;
139140 }
140-
141- if ( vals . steps != null ) raw . steps = vals . steps ;
142-
143- jsonText = JSON . stringify ( raw , null , 2 ) ;
144- lines = jsonText . split ( "\n" ) ;
141+ let jsonText = JSON . stringify ( raw , null , 2 ) ;
142+ return jsonText . split ( "\n" ) ;
145143} ;
146144
147145let draw = function ( ) {
148146 g . clear ( ) ;
149147 g . setFontAlign ( - 1 , - 1 ) ;
150148 g . setFont ( "Vector" , 10 ) ;
151- valuePositions = [ ] ;
152149
153150 g . setColor ( clrs . tab ) ;
154151
@@ -159,77 +156,95 @@ let draw = function() {
159156 g . setFont ( "Vector" , buttonHeight ) ;
160157 g . drawString ( "X" , buttonX , buttonY ) ;
161158 g . setFont ( "Vector" , fontSize ) ;
162-
159+
160+ var lines = getJsonLine ( ) ;
161+ var numWidth = 0 ;
162+
163+ // Draw numbers first to find out their max width
163164 for ( let i = 0 ; i < maxLines ; i ++ ) {
164165 const y = headerHeight + i * lineHeight ;
165166 const lineNumberStr = ( i + 1 ) . toString ( ) . padStart ( 2 , " " ) + " " ;
166167 g . drawString ( lineNumberStr , 0 , y ) ;
167168 numWidth = Math . max ( numWidth , g . stringWidth ( lineNumberStr ) ) ;
168169 }
169-
170- redrawValues ( ) ;
171- } ;
172-
173- let redraw = function ( ) {
174170 for ( let i = 0 ; i < maxLines ; i ++ ) {
175- const lineIndex = i ;
176- const line = lines [ lineIndex ] ;
177- if ( ! line ) continue ;
178171 const y = headerHeight + i * lineHeight ;
172+ const line = lines [ i ] ;
173+ if ( ! line ) continue ;
179174
180- const indentMatch = line . match ( / ^ ( \s * ) / ) ;
181- const indent = indentMatch ? indentMatch [ 1 ] : "" ;
182-
183- const kvMatch = line . trim ( ) . match ( / ^ " ( [ ^ " ] + ) " : \s * ( .+ ) $ / ) ;
175+ let kvMatch = getKeyValRegex ( line ) ;
184176 if ( kvMatch ) {
185177 const key = kvMatch [ 1 ] ;
186178 let value = kvMatch [ 2 ] ;
187179
188- if ( prevVals . key == value ) continue ;
189- prevVals . key = value ;
190-
191180 // Key
192181 g . setColor ( clrs . keys ) ;
193- g . drawString ( indent + `"${ key } "` , numWidth , y ) ;
194- const keyWidth = g . stringWidth ( indent + `"${ key } "` ) ;
195- const valueX = numWidth + keyWidth ;
196- const valueText = ": " + value ;
182+ const indent = getIndentRegex ( line ) ;
183+ const keyText = indent + `"${ key } "` ;
184+ g . drawString ( keyText , numWidth , y ) ;
185+ const keyWidth = g . stringWidth ( keyText ) ;
186+ let x = numWidth + keyWidth ;
197187
188+ g . setColor ( clrs . brackets ) ;
189+ const colonText = ": " ;
190+ g . drawString ( colonText , x , y ) ;
191+ x += g . stringWidth ( colonText ) ;
192+
198193 // Value color
194+ const endComma = value . endsWith ( ',' ) ;
195+ valsArrs [ key ] = { text :value , x :x , y :y , endComma :endComma } ;
196+ if ( endComma ) value = value . slice ( 0 , - 1 ) ;
199197 if ( value . startsWith ( '"' ) ) {
200- g . setColor ( clrs . strings ) ;
198+ valsArrs [ key ] . color = clrs . strings ;
201199 } else if ( value . startsWith ( '{' ) || value . startsWith ( '}' ) ) {
202- g . setColor ( clrs . brackets ) ;
200+ valsArrs [ key ] . color = clrs . brackets ;
203201 } else {
204- g . setColor ( clrs . ints ) ;
202+ valsArrs [ key ] . color = clrs . ints ;
205203 }
206- g . drawString ( valueText , valueX , y ) ;
207-
208- valuePositions . push ( {
209- key,
210- x : valueX ,
211- y,
212- text : value
213- } ) ;
214- } else {
204+ g . setColor ( valsArrs [ key ] . color ) ;
205+ g . drawString ( value , x , y ) ;
206+ if ( endComma ) {
207+ g . setColor ( clrs . brackets ) ;
208+ g . drawString ( ',' , x + g . stringWidth ( value ) , y ) ;
209+ }
210+ }
211+ else {
215212 g . setColor ( clrs . brackets ) ;
216213 g . drawString ( line , numWidth , y ) ;
217214 }
218215 }
219216} ;
220217
221- let clearVals = function ( ) {
222- g . setFont ( "Vector" , fontSize ) ;
218+ // Redraws only values that changed
219+ let redraw = function ( ) {
223220 g . setFontAlign ( - 1 , - 1 ) ;
224- valuePositions . forEach ( pos => {
221+ g . setFont ( "Vector" , fontSize ) ;
222+ var lines = getJsonLine ( ) ;
223+
224+ for ( let i = 0 ; i < lines . length ; i ++ ) {
225+ let kvMatch = getKeyValRegex ( lines [ i ] ) ;
226+ if ( ! kvMatch ) continue ;
227+ const key = kvMatch [ 1 ] ;
228+ let value = kvMatch [ 2 ] ;
229+ if ( ! ( key in valsArrs ) ) continue ;
230+ let valsArr = valsArrs [ key ] ;
231+ if ( value === valsArr . text ) continue ; // No need to update
232+ valsArrs [ key ] . text = value ;
233+
234+ // Clear prev values
225235 g . setColor ( clrs . bg ) ;
226- g . fillRect ( pos . x , pos . y , w , pos . y + lineHeight ) ;
227- } ) ;
236+ g . fillRect ( valsArr . x , valsArr . y , w , valsArr . y + lineHeight ) ;
237+
238+ g . setColor ( valsArr . color ) ;
239+ g . drawString ( value , valsArr . x , valsArr . y ) ;
240+ if ( valsArr . endComma ) {
241+ g . setColor ( clrs . brackets ) ;
242+ g . drawString ( ',' , valsArr . Banglex + g . stringWidth ( value ) , valsArr . y ) ;
243+ }
244+ }
228245} ;
229246
230247let redrawValues = function ( ) {
231- loadJson ( ) ;
232- clearVals ( ) ;
233248 redraw ( ) ;
234249 if ( drawTimeout ) clearTimeout ( drawTimeout ) ;
235250 drawTimeout = setTimeout ( function ( ) {
@@ -256,4 +271,5 @@ loadLocation();
256271Bangle . loadWidgets ( ) ;
257272widget_utils . hide ( ) ;
258273draw ( ) ;
274+ redrawValues ( ) ; // To set the timeout
259275}
0 commit comments