@@ -20,6 +20,7 @@ Copyright (C) 2019 Damien Nicolet
2020angular . module ( 'nwas' , [ 'ngSanitize' , 'pascalprecht.translate' ] ) . controller ( 'main' , function ( $scope , $http , apps , $translate ) {
2121
2222 $scope . locale = $translate . use ( ) ;
23+ $scope . wallpaper = null ;
2324 $scope . apps = apps ;
2425 $scope . selectedApps = [ ] ;
2526 $scope . customFiles = [ ] ;
@@ -35,6 +36,63 @@ angular.module('nwas', ['ngSanitize', 'pascalprecht.translate']).controller('mai
3536 }
3637 } ;
3738
39+ $scope . setWallpaper = function setWallpaper ( el ) {
40+ let file = el [ 0 ] . files [ 0 ] ;
41+ el . value = null ;
42+ let reader = new FileReader ( ) ;
43+
44+ reader . addEventListener ( "load" , function ( ) {
45+ let img = document . createElement ( 'img' ) ;
46+ img . onload = function ( ) {
47+ $scope . $apply ( function ( ) {
48+ let cropperDiv = document . getElementById ( "cropperDiv" ) ;
49+ cropperDiv . innerText = "" ;
50+ cropperDiv . appendChild ( img ) ;
51+ $ ( '#imageModal' ) . modal ( 'show' ) ;
52+ img . style = "max-width: 100%;" ;
53+
54+ $scope . wallpaper = {
55+ name : file . name ,
56+ cropper : new Cropper ( img , {
57+ aspectRatio : 320 / 222 ,
58+ viewMode : 1
59+ } )
60+ } ;
61+ } ) ;
62+ } ;
63+ img . src = reader . result ;
64+ } , false ) ;
65+
66+ if ( file ) {
67+ reader . readAsDataURL ( file ) ;
68+ }
69+ } ;
70+
71+ $scope . saveCroppedWallpaper = function saveCroppedWallpaper ( ) {
72+ // Resize image
73+ var canvas = document . createElement ( 'canvas' ) ,
74+ ctx = canvas . getContext ( '2d' ) ;
75+ canvas . width = 320 ;
76+ canvas . height = 222 ;
77+
78+ ctx . drawImage ( $scope . wallpaper . cropper . getCroppedCanvas ( ) , 0 , 0 , 320 , 222 ) ;
79+
80+ $scope . wallpaper = {
81+ name : $scope . wallpaper . name ,
82+ imagesrc : canvas . toDataURL ( "image/png" )
83+ } ;
84+ document . getElementById ( "wallpaper-name" ) . innerText = $scope . wallpaper . name ;
85+ $ ( '#imageModal' ) . modal ( 'hide' ) ;
86+ }
87+
88+ $scope . removeWallpaper = function removeWallpaper ( ) {
89+ $scope . wallpaper = null ;
90+ document . getElementById ( "wallpaper-file-input" ) . value = null ;
91+ $translate ( "WALLPAPER_FILE" ) . then ( function ( translatedValue ) {
92+ document . getElementById ( "wallpaper-name" ) . innerText = translatedValue ;
93+ } ) ;
94+ } ;
95+
3896 $scope . removeApplication = function removeApplication ( app ) {
3997 let index = $scope . selectedApps . indexOf ( app ) ;
4098 if ( index >= 0 ) {
@@ -127,8 +185,56 @@ angular.module('nwas', ['ngSanitize', 'pascalprecht.translate']).controller('mai
127185 return compressed;
128186 }
129187*/
130- let buildArchive = async function buildArchive ( applications , files ) {
131- if ( applications . length == 0 && files . length == 0 ) {
188+ let fromPNGToOBM = function fromPNGToOBM ( dataURL ) {
189+ //OBM (Omega Bit Map) is the wallpaper format of Omega
190+ let img = new Image ( ) ;
191+ img . src = dataURL ;
192+
193+ let canvas = document . createElement ( 'canvas' ) ;
194+
195+ canvas . width = img . width ;
196+ canvas . height = img . height ;
197+
198+ let img_header32 = new Uint32Array ( 3 ) ;
199+ img_header32 [ 0 ] = 466512775 ; //We use a "random" magic number
200+ img_header32 [ 1 ] = canvas . width ;
201+ img_header32 [ 2 ] = canvas . height ;
202+
203+ let context = canvas . getContext ( '2d' ) ;
204+ context . drawImage ( img , 0 , 0 ) ;
205+ let imgd = context . getImageData ( 0 , 0 , img . width , img . height ) ;
206+
207+ let img_rgba32 = new Uint32Array ( imgd . data . buffer ) ;
208+ let img_rgba8888 = new Uint8Array ( imgd . data . buffer ) ;
209+ let img_rgb565 = new Uint16Array ( img_rgba32 . length ) ;
210+ for ( let i = 0 ; i < img_rgba32 . length ; i ++ ) {
211+ let r = img_rgba8888 [ i * 4 + 0 ] / 255 ;
212+ let g = img_rgba8888 [ i * 4 + 1 ] / 255 ;
213+ let b = img_rgba8888 [ i * 4 + 2 ] / 255 ;
214+ let a = img_rgba8888 [ i * 4 + 3 ] / 255 ;
215+
216+ let br = r * a + 1 * ( 1 - a ) ;
217+ let bg = g * a + 1 * ( 1 - a ) ;
218+ let bb = b * a + 1 * ( 1 - a ) ;
219+
220+ let ir = Math . round ( br * 0xFF ) ;
221+ let ig = Math . round ( bg * 0xFF ) ;
222+ let ib = Math . round ( bb * 0xFF ) ;
223+
224+ img_rgb565 [ i ] = ( ir >> 3 ) << 11 | ( ig >> 2 ) << 5 | ( ib >> 3 ) ;
225+ }
226+
227+
228+ let img_header8 = new Uint8Array ( img_header32 . buffer , img_header32 . byteOffset , img_header32 . byteLength ) ;
229+ let img_data = new Uint8Array ( img_rgb565 . buffer , img_rgb565 . byteOffset , img_rgb565 . byteLength ) ;
230+
231+ let final_data = Uint8Array . from ( [ ...img_header8 , ...img_data ] ) ;
232+
233+ return final_data ;
234+ }
235+
236+ let buildArchive = async function buildArchive ( applications , wallpaper , files ) {
237+ if ( applications . length == 0 && files . length == 0 && wallpaper == null ) {
132238 return new Promise ( function ( resolve , reject ) {
133239 resolve ( new Uint8Array ( 0x200 ) ) ;
134240 } ) ;
@@ -160,6 +266,16 @@ angular.module('nwas', ['ngSanitize', 'pascalprecht.translate']).controller('mai
160266 }
161267
162268 }
269+ if ( wallpaper != null ) {
270+ console . log ( "Inling wallpaper" ) ;
271+ $scope . $apply ( function ( ) {
272+ $scope . lastAction = $translate . instant ( "ADDING" ) + " " + wallpaper . name ;
273+ } ) ;
274+ files . push ( {
275+ name : "wallpaper.obm" ,
276+ binary : fromPNGToOBM ( wallpaper . imagesrc )
277+ } ) ;
278+ }
163279
164280 for ( let i = 0 ; i < files . length ; i ++ ) {
165281 let file = files [ i ] ;
@@ -237,7 +353,7 @@ angular.module('nwas', ['ngSanitize', 'pascalprecht.translate']).controller('mai
237353 $scope . $apply ( function ( ) {
238354 $scope . uploading = true ;
239355 } ) ;
240- let archive = await buildArchive ( $scope . selectedApps , $scope . customFiles ) ;
356+ let archive = await buildArchive ( $scope . selectedApps , $scope . wallpaper , $scope . customFiles ) ;
241357 console . log ( "Archive" , archive ) ;
242358 await uploadFile ( selectedDevice , "@External Flash /0x90200000/32*064Kg,64*064Kg" , archive , false ) ;
243359 $scope . $apply ( function ( ) {
@@ -329,6 +445,16 @@ angular.module('nwas', ['ngSanitize', 'pascalprecht.translate']).controller('mai
329445 } )
330446 }
331447 }
448+
449+ } ) . directive ( "ngWallpaperSelect" , function ( ) {
450+ return {
451+ link : function ( $scope , el ) {
452+ el . bind ( "change" , function ( e ) {
453+ $scope . setWallpaper ( el ) ;
454+ } )
455+ }
456+ }
457+
332458} ) . config ( function ( $translateProvider ) {
333459 $translateProvider
334460 . translations ( 'en' , {
@@ -342,6 +468,9 @@ angular.module('nwas', ['ngSanitize', 'pascalprecht.translate']).controller('mai
342468 REMOVE : 'Remove' ,
343469 CUSTOM_FILE : 'Custom file' ,
344470 INSTALL : 'Install' ,
471+ WALLPAPER : "Wallpaper" ,
472+ WALLPAPER_FILE : 'PNG file of size 320x222' ,
473+ WALLPAPER_FILE_SIZE_ERROR : 'Error : the file is not the right size.' ,
345474 AVAILABLE_APPLICATIONS : 'Available applications' ,
346475 ADD : 'Add' ,
347476 ACKNOWLEDGMENTS : 'Acknowledgments' ,
@@ -355,6 +484,9 @@ angular.module('nwas', ['ngSanitize', 'pascalprecht.translate']).controller('mai
355484 DFU_WROTE : "Done" ,
356485 OR : "or" ,
357486 CHECK_ICONS : "Enable experimental icons support." ,
487+ CROP_IMAGE_TITLE : "Crop wallpaper" ,
488+ CROP_IMAGE_SAVE : "Save" ,
489+ CROP_IMAGE_CANCEL : "Cancel" ,
358490 } )
359491 . translations ( 'fr' , {
360492 TITLE : 'Dépôt d\'application N110 non officiel' ,
@@ -367,6 +499,9 @@ angular.module('nwas', ['ngSanitize', 'pascalprecht.translate']).controller('mai
367499 REMOVE : 'Supprimer' ,
368500 CUSTOM_FILE : 'Fichier local' ,
369501 INSTALL : 'Installer' ,
502+ WALLPAPER : 'Fond d\'écran' ,
503+ WALLPAPER_FILE : 'Fichier PNG de taille 320x222' ,
504+ WALLPAPER_FILE_SIZE_ERROR : 'Erreur : le fichier ne fait pas la bonne taile.' ,
370505 AVAILABLE_APPLICATIONS : 'Applications disponibles' ,
371506 ADD : 'Ajouter' ,
372507 ACKNOWLEDGMENTS : 'Remerciements' ,
@@ -380,6 +515,9 @@ angular.module('nwas', ['ngSanitize', 'pascalprecht.translate']).controller('mai
380515 DFU_WROTE : "Terminé" ,
381516 OR : "ou" ,
382517 CHECK_ICONS : "Activer le support des icons (Expérimental)" ,
518+ CROP_IMAGE_TITLE : "Recadrer le fond d'écran" ,
519+ CROP_IMAGE_SAVE : "Sauvegarder" ,
520+ CROP_IMAGE_CANCEL : "Annuler" ,
383521 } )
384522 . registerAvailableLanguageKeys ( [ 'en' , 'fr' ] , {
385523 'en_*' : 'en' ,
0 commit comments