Update code owners and remove obsolete code (#446)
This commit is contained in:
		
							parent
							
								
									920b3c3dee
								
							
						
					
					
						commit
						c880f90eb5
					
				
							
								
								
									
										142
									
								
								.github/CODEOWNERS
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										142
									
								
								.github/CODEOWNERS
									
									
									
									
										vendored
									
									
								
							| @ -1,116 +1,60 @@ | |||||||
| # who owns all the code by default | # Who owns all the code by default | ||||||
| 
 |  | ||||||
| * @skotopes | * @skotopes | ||||||
| 
 | 
 | ||||||
| # unknow applications | # Applications | ||||||
| 
 |  | ||||||
| applications/** @skotopes | applications/** @skotopes | ||||||
| 
 | applications/accessor/** @DrZlo13 | ||||||
| # assets and asset generator | applications/app-loader/** @gornekich | ||||||
| 
 |  | ||||||
| assets/** @skotopes |  | ||||||
| 
 |  | ||||||
| # bootloader |  | ||||||
| 
 |  | ||||||
| bootloader/** @skotopes |  | ||||||
| firmware/targets/f4/api-hal/api-hal-boot.c @skotopes |  | ||||||
| 
 |  | ||||||
| # debug tools |  | ||||||
| 
 |  | ||||||
| debug/** @skotopes |  | ||||||
| 
 |  | ||||||
| # Core, HAL and applocation loader |  | ||||||
| 
 |  | ||||||
| applications/app-loader/** @DrZlo13 |  | ||||||
| core/** @DrZlo13 |  | ||||||
| firmware/targets/api-hal-include/** @DrZlo13 |  | ||||||
| 
 |  | ||||||
| firmware/targets/f4/api-hal/api-hal-clock.c @skotopes |  | ||||||
| firmware/targets/f4/api-hal/api-hal-clock.h @skotopes |  | ||||||
| firmware/targets/f4/api-hal/api-hal-delay.c @DrZlo13 |  | ||||||
| firmware/targets/f4/api-hal/api-hal-flash.c @skotopes |  | ||||||
| firmware/targets/f4/api-hal/api-hal-flash.h @skotopes |  | ||||||
| firmware/targets/f4/api-hal/api-hal-gpio.c @DrZlo13 |  | ||||||
| firmware/targets/f4/api-hal/api-hal-gpio.h @DrZlo13 |  | ||||||
| firmware/targets/f4/api-hal/api-hal-pwm.c @DrZlo13 |  | ||||||
| firmware/targets/f4/api-hal/api-hal-pwm.h @DrZlo13 |  | ||||||
| firmware/targets/f4/api-hal/api-hal-resources.c @DrZlo13 |  | ||||||
| firmware/targets/f4/api-hal/api-hal-resources.h @DrZlo13 |  | ||||||
| firmware/targets/f4/api-hal/api-hal-spi-config.c @DrZlo13 |  | ||||||
| firmware/targets/f4/api-hal/api-hal-spi-config.h @DrZlo13 |  | ||||||
| firmware/targets/f4/api-hal/api-hal-spi.c @DrZlo13 |  | ||||||
| firmware/targets/f4/api-hal/api-hal-spi-config.h @DrZlo13 |  | ||||||
| firmware/targets/f4/api-hal/api-hal-tim.c @DrZlo13 |  | ||||||
| firmware/targets/f4/api-hal/api-hal-tim.h @DrZlo13 |  | ||||||
| firmware/targets/f4/api-hal/api-hal-timebase-timer.h @skotopes |  | ||||||
| firmware/targets/f4/api-hal/api-hal-timebase.c @skotopes |  | ||||||
| firmware/targets/f4/api-hal/api-hal-timebase.h @skotopes |  | ||||||
| firmware/targets/f4/api-hal/api-hal-uuid.c @skotopes |  | ||||||
| firmware/targets/f4/api-hal/api-hal-vcp.c @skotopes |  | ||||||
| firmware/targets/f4/api-hal/api-hal.c @DrZlo13 |  | ||||||
| firmware/targets/f4/api-hal/api-interrupts.c @DrZlo13 |  | ||||||
| 
 |  | ||||||
| firmware/targets/f4/Src/i2c.c @skotopes |  | ||||||
| firmware/targets/f5/Src/i2c.c @skotopes |  | ||||||
| 
 |  | ||||||
| # BLE |  | ||||||
| 
 |  | ||||||
| firmware/targets/f4/ble-glue/** @skotopes |  | ||||||
| applications/bt/** @skotopes | applications/bt/** @skotopes | ||||||
| firmware/targets/f4/api-hal/api-hal-bt.c @skotopes | applications/cli/** @skotopes | ||||||
| 
 | applications/dolphin/** @skotopes @itsyourbedtime | ||||||
| # Dolphin | applications/gpio-tester/** @skotopes | ||||||
| 
 |  | ||||||
| applications/dolphin/** @skotopes |  | ||||||
| 
 |  | ||||||
| # GUI Stuff |  | ||||||
| 
 |  | ||||||
| applications/gui/** @skotopes | applications/gui/** @skotopes | ||||||
| applications/input/** @skotopes | applications/gui-test/** @DrZlo13 | ||||||
| 
 |  | ||||||
| # iButton |  | ||||||
| 
 |  | ||||||
| applications/ibutton/** @DrZlo13 | applications/ibutton/** @DrZlo13 | ||||||
| lib/cyfral/** @DrZlo13 | applications/input/** @skotopes | ||||||
| lib/onewire/** @DrZlo13 | applications/irda/** @DrZlo13 @albkharisov | ||||||
| 
 |  | ||||||
| # IR |  | ||||||
| 
 |  | ||||||
| applications/irda/** @DrZlo13 |  | ||||||
| 
 |  | ||||||
| # LF-Rfid |  | ||||||
| 
 |  | ||||||
| applications/lf-rfid/** @DrZlo13  | applications/lf-rfid/** @DrZlo13  | ||||||
| 
 |  | ||||||
| # Menu |  | ||||||
| 
 |  | ||||||
| applications/menu/** @skotopes | applications/menu/** @skotopes | ||||||
| 
 | applications/music-player/** @DrZlo13 | ||||||
| # NFC | applications/nfc/** @skotopes @gornekich | ||||||
| 
 | applications/power/** @skotopes | ||||||
| applications/nfc/** @skotopes |  | ||||||
| lib/ST25RFAL002/** @skotopes |  | ||||||
| 
 |  | ||||||
| # SD Card and filesystem |  | ||||||
| 
 |  | ||||||
| applications/sd-card-test/** @DrZlo13 | applications/sd-card-test/** @DrZlo13 | ||||||
| applications/sd-filesystem/** @DrZlo13 | applications/sd-filesystem/** @DrZlo13 | ||||||
| lib/common-api/filesystem-api.h @DrZlo13 | applications/subghz/** @skotopes | ||||||
| lib/fatfs/** @DrZlo13 | applications/template/** @skotopes | ||||||
| firmware/targets/f4/Src/fatfs/** @DrZlo13 | applications/tests/** @skotopes @DrZlo13 | ||||||
| 
 | 
 | ||||||
| # Power control app | # Assets and asset generator | ||||||
|  | assets/** @skotopes | ||||||
| 
 | 
 | ||||||
| applications/power/** @skotopes | # Bootloader | ||||||
| lib/drivers/bq* @skotopes | bootloader/** @skotopes | ||||||
| firmware/targets/f4/api-hal/api-hal-power.c @skotopes |  | ||||||
| 
 | 
 | ||||||
| # Some applications | # Core, HAL and applocation loader | ||||||
|  | core/** @DrZlo13 | ||||||
| 
 | 
 | ||||||
| applications/music-player/** @DrZlo13 | # Debug tools | ||||||
| applications/floopper-bloopper/** @skotopes | debug/** @skotopes | ||||||
| applications/gui-test/** @DrZlo13 |  | ||||||
| 
 | 
 | ||||||
|  | # Firmware | ||||||
|  | firmware/** @skotopes | ||||||
|  | 
 | ||||||
|  | # Lib | ||||||
| lib/app-template/** @DrZlo13 | lib/app-template/** @DrZlo13 | ||||||
| lib/qrcode/** @DrZlo13 |  | ||||||
| lib/callback-connector/** @DrZlo13 | lib/callback-connector/** @DrZlo13 | ||||||
|  | lib/common-api/** @DrZlo13 | ||||||
|  | lib/cyfral/** @DrZlo13 | ||||||
|  | lib/drivers/** @skotopes @gornekich | ||||||
|  | lib/fatfs/** @DrZlo13 | ||||||
|  | lib/fnv1a-hash/** @DrZlo13 | ||||||
|  | lib/mlib/** @skotopes | ||||||
|  | lib/onewire/** @DrZlo13 | ||||||
|  | lib/qrcode/** @DrZlo13 | ||||||
|  | lib/ST25RFAL002/** @skotopes @gornekich | ||||||
|  | lib/STM32CubeWB/** @skotopes | ||||||
|  | lib/u8g2/** @skotopes | ||||||
|  | lib/version/** @skotopes | ||||||
|  | 
 | ||||||
|  | # Make | ||||||
|  | make/** @skotopes | ||||||
|  | |||||||
| @ -1,104 +0,0 @@ | |||||||
| #include <furi.h> |  | ||||||
| 
 |  | ||||||
| typedef enum { |  | ||||||
|     EventTypeTick, |  | ||||||
|     EventTypeKey, |  | ||||||
|     // add your events type |  | ||||||
| } EventType; |  | ||||||
| 
 |  | ||||||
| typedef struct { |  | ||||||
|     union { |  | ||||||
|         InputEvent input; |  | ||||||
|         // add your events payload |  | ||||||
|     } value; |  | ||||||
|     EventType type; |  | ||||||
| } Event; |  | ||||||
| 
 |  | ||||||
| typedef struct { |  | ||||||
|     // describe state here |  | ||||||
| } State; |  | ||||||
| 
 |  | ||||||
| static void render_callback(Canvas* canvas, void* ctx) { |  | ||||||
|     State* state = (State*)acquire_mutex((ValueMutex*)ctx, 25); |  | ||||||
| 
 |  | ||||||
|     canvas_clear(canvas); |  | ||||||
| 
 |  | ||||||
|     // draw your app |  | ||||||
| 
 |  | ||||||
|     release_mutex((ValueMutex*)ctx, state); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void input_callback(InputEvent* input_event, void* ctx) { |  | ||||||
|     osMessageQueueId_t event_queue = (QueueHandle_t)ctx; |  | ||||||
| 
 |  | ||||||
|     Event event; |  | ||||||
|     event.type = EventTypeKey; |  | ||||||
|     event.value.input = *input_event; |  | ||||||
|     osMessageQueuePut(event_queue, &event, 0, 0); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| int32_t template_app(void* p) { |  | ||||||
|     osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(Event), NULL); |  | ||||||
| 
 |  | ||||||
|     State _state; |  | ||||||
|     /* init state here */ |  | ||||||
|     ValueMutex state_mutex; |  | ||||||
|     if(!init_mutex(&state_mutex, &_state, sizeof(State))) { |  | ||||||
|         printf("cannot create mutex\r\n"); |  | ||||||
|         return 255; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     ViewPort* view_port = view_port_alloc(); |  | ||||||
| 
 |  | ||||||
|     view_port_draw_callback_set(view_port, render_callback, &state_mutex); |  | ||||||
|     view_port_input_callback_set(view_port, input_callback, event_queue); |  | ||||||
| 
 |  | ||||||
|     // Open GUI and register view_port |  | ||||||
|     Gui* gui = furi_record_open("gui"); |  | ||||||
|     if(gui == NULL) { |  | ||||||
|         printf("gui is not available\r\n"); |  | ||||||
|         return 255; |  | ||||||
|     } |  | ||||||
|     gui_add_view_port(gui, view_port, /* specify UI layer */); |  | ||||||
| 
 |  | ||||||
|     Event event; |  | ||||||
|     while(1) { |  | ||||||
|         osStatus_t event_status = osMessageQueueGet( |  | ||||||
|             event_queue, &event, NULL, |  | ||||||
|             /* specify timeout */ |  | ||||||
|         ); |  | ||||||
|         State* state = (State*)acquire_mutex_block(&state_mutex); |  | ||||||
| 
 |  | ||||||
|         if(event_status == osOK) { |  | ||||||
|             if(event.type == EventTypeKey) { |  | ||||||
|                 // press events |  | ||||||
|                 if(event.value.input.type == InputTypeShort && event.value.input.key == InputKeyBack) { |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 if(event.value.input.type == InputTypeShort && event.value.input.key == InputKeyUp) { |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 if(event.value.input.type == InputTypeShort && event.value.input.key == InputKeyDown) { |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 if(event.value.input.type == InputTypeShort && event.value.input.key == InputKeyLeft) { |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 if(event.value.input.type == InputTypeShort && event.value.input.key == InputKeyRight) { |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 if(event.value.input.key == InputKeyOk) { |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } else { |  | ||||||
|             // event timeout |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // common code, for example, force update UI |  | ||||||
|         // view_port_update(view_port); |  | ||||||
| 
 |  | ||||||
|         release_mutex(&state_mutex, state); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return 0; |  | ||||||
| } |  | ||||||
							
								
								
									
										0
									
								
								flp/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										0
									
								
								flp/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
								
								
									
										14
									
								
								flp/Pipfile
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								flp/Pipfile
									
									
									
									
									
								
							| @ -1,14 +0,0 @@ | |||||||
| [[source]] |  | ||||||
| name = "pypi" |  | ||||||
| url = "https://pypi.org/simple" |  | ||||||
| verify_ssl = true |  | ||||||
| 
 |  | ||||||
| [dev-packages] |  | ||||||
| black = "20.8b1" |  | ||||||
| 
 |  | ||||||
| [packages] |  | ||||||
| pyserial = "3.4" |  | ||||||
| click = "7.1.2" |  | ||||||
| 
 |  | ||||||
| [requires] |  | ||||||
| python_version = "3.8" |  | ||||||
							
								
								
									
										142
									
								
								flp/Pipfile.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										142
									
								
								flp/Pipfile.lock
									
									
									
										generated
									
									
									
								
							| @ -1,142 +0,0 @@ | |||||||
| { |  | ||||||
|     "_meta": { |  | ||||||
|         "hash": { |  | ||||||
|             "sha256": "62bedeef792c73b899be0e307396e579f1af2d0c1d49dbccc252cc14e11e50d4" |  | ||||||
|         }, |  | ||||||
|         "pipfile-spec": 6, |  | ||||||
|         "requires": { |  | ||||||
|             "python_version": "3.8" |  | ||||||
|         }, |  | ||||||
|         "sources": [ |  | ||||||
|             { |  | ||||||
|                 "name": "pypi", |  | ||||||
|                 "url": "https://pypi.org/simple", |  | ||||||
|                 "verify_ssl": true |  | ||||||
|             } |  | ||||||
|         ] |  | ||||||
|     }, |  | ||||||
|     "default": { |  | ||||||
|         "click": { |  | ||||||
|             "hashes": [ |  | ||||||
|                 "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", |  | ||||||
|                 "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" |  | ||||||
|             ], |  | ||||||
|             "index": "pypi", |  | ||||||
|             "version": "==7.1.2" |  | ||||||
|         }, |  | ||||||
|         "pyserial": { |  | ||||||
|             "hashes": [ |  | ||||||
|                 "sha256:6e2d401fdee0eab996cf734e67773a0143b932772ca8b42451440cfed942c627", |  | ||||||
|                 "sha256:e0770fadba80c31013896c7e6ef703f72e7834965954a78e71a3049488d4d7d8" |  | ||||||
|             ], |  | ||||||
|             "index": "pypi", |  | ||||||
|             "version": "==3.4" |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|     "develop": { |  | ||||||
|         "appdirs": { |  | ||||||
|             "hashes": [ |  | ||||||
|                 "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41", |  | ||||||
|                 "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128" |  | ||||||
|             ], |  | ||||||
|             "version": "==1.4.4" |  | ||||||
|         }, |  | ||||||
|         "black": { |  | ||||||
|             "hashes": [ |  | ||||||
|                 "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea", |  | ||||||
|                 "sha256:70b62ef1527c950db59062cda342ea224d772abdf6adc58b86a45421bab20a6b" |  | ||||||
|             ], |  | ||||||
|             "index": "pypi", |  | ||||||
|             "version": "==20.8b1" |  | ||||||
|         }, |  | ||||||
|         "click": { |  | ||||||
|             "hashes": [ |  | ||||||
|                 "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", |  | ||||||
|                 "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" |  | ||||||
|             ], |  | ||||||
|             "index": "pypi", |  | ||||||
|             "version": "==7.1.2" |  | ||||||
|         }, |  | ||||||
|         "mypy-extensions": { |  | ||||||
|             "hashes": [ |  | ||||||
|                 "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d", |  | ||||||
|                 "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8" |  | ||||||
|             ], |  | ||||||
|             "version": "==0.4.3" |  | ||||||
|         }, |  | ||||||
|         "pathspec": { |  | ||||||
|             "hashes": [ |  | ||||||
|                 "sha256:7d91249d21749788d07a2d0f94147accd8f845507400749ea19c1ec9054a12b0", |  | ||||||
|                 "sha256:da45173eb3a6f2a5a487efba21f050af2b41948be6ab52b6a1e3ff22bb8b7061" |  | ||||||
|             ], |  | ||||||
|             "version": "==0.8.0" |  | ||||||
|         }, |  | ||||||
|         "regex": { |  | ||||||
|             "hashes": [ |  | ||||||
|                 "sha256:0dc64ee3f33cd7899f79a8d788abfbec168410be356ed9bd30bbd3f0a23a7204", |  | ||||||
|                 "sha256:1269fef3167bb52631ad4fa7dd27bf635d5a0790b8e6222065d42e91bede4162", |  | ||||||
|                 "sha256:14a53646369157baa0499513f96091eb70382eb50b2c82393d17d7ec81b7b85f", |  | ||||||
|                 "sha256:3a3af27a8d23143c49a3420efe5b3f8cf1a48c6fc8bc6856b03f638abc1833bb", |  | ||||||
|                 "sha256:46bac5ca10fb748d6c55843a931855e2727a7a22584f302dd9bb1506e69f83f6", |  | ||||||
|                 "sha256:4c037fd14c5f4e308b8370b447b469ca10e69427966527edcab07f52d88388f7", |  | ||||||
|                 "sha256:51178c738d559a2d1071ce0b0f56e57eb315bcf8f7d4cf127674b533e3101f88", |  | ||||||
|                 "sha256:5ea81ea3dbd6767873c611687141ec7b06ed8bab43f68fad5b7be184a920dc99", |  | ||||||
|                 "sha256:6961548bba529cac7c07af2fd4d527c5b91bb8fe18995fed6044ac22b3d14644", |  | ||||||
|                 "sha256:75aaa27aa521a182824d89e5ab0a1d16ca207318a6b65042b046053cfc8ed07a", |  | ||||||
|                 "sha256:7a2dd66d2d4df34fa82c9dc85657c5e019b87932019947faece7983f2089a840", |  | ||||||
|                 "sha256:8a51f2c6d1f884e98846a0a9021ff6861bdb98457879f412fdc2b42d14494067", |  | ||||||
|                 "sha256:9c568495e35599625f7b999774e29e8d6b01a6fb684d77dee1f56d41b11b40cd", |  | ||||||
|                 "sha256:9eddaafb3c48e0900690c1727fba226c4804b8e6127ea409689c3bb492d06de4", |  | ||||||
|                 "sha256:bbb332d45b32df41200380fff14712cb6093b61bd142272a10b16778c418e98e", |  | ||||||
|                 "sha256:bc3d98f621898b4a9bc7fecc00513eec8f40b5b83913d74ccb445f037d58cd89", |  | ||||||
|                 "sha256:c11d6033115dc4887c456565303f540c44197f4fc1a2bfb192224a301534888e", |  | ||||||
|                 "sha256:c50a724d136ec10d920661f1442e4a8b010a4fe5aebd65e0c2241ea41dbe93dc", |  | ||||||
|                 "sha256:d0a5095d52b90ff38592bbdc2644f17c6d495762edf47d876049cfd2968fbccf", |  | ||||||
|                 "sha256:d6cff2276e502b86a25fd10c2a96973fdb45c7a977dca2138d661417f3728341", |  | ||||||
|                 "sha256:e46d13f38cfcbb79bfdb2964b0fe12561fe633caf964a77a5f8d4e45fe5d2ef7" |  | ||||||
|             ], |  | ||||||
|             "version": "==2020.7.14" |  | ||||||
|         }, |  | ||||||
|         "toml": { |  | ||||||
|             "hashes": [ |  | ||||||
|                 "sha256:926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f", |  | ||||||
|                 "sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88" |  | ||||||
|             ], |  | ||||||
|             "version": "==0.10.1" |  | ||||||
|         }, |  | ||||||
|         "typed-ast": { |  | ||||||
|             "hashes": [ |  | ||||||
|                 "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355", |  | ||||||
|                 "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919", |  | ||||||
|                 "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa", |  | ||||||
|                 "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652", |  | ||||||
|                 "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75", |  | ||||||
|                 "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01", |  | ||||||
|                 "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d", |  | ||||||
|                 "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1", |  | ||||||
|                 "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907", |  | ||||||
|                 "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c", |  | ||||||
|                 "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3", |  | ||||||
|                 "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b", |  | ||||||
|                 "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614", |  | ||||||
|                 "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb", |  | ||||||
|                 "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b", |  | ||||||
|                 "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41", |  | ||||||
|                 "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6", |  | ||||||
|                 "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34", |  | ||||||
|                 "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe", |  | ||||||
|                 "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4", |  | ||||||
|                 "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7" |  | ||||||
|             ], |  | ||||||
|             "version": "==1.4.1" |  | ||||||
|         }, |  | ||||||
|         "typing-extensions": { |  | ||||||
|             "hashes": [ |  | ||||||
|                 "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918", |  | ||||||
|                 "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c", |  | ||||||
|                 "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f" |  | ||||||
|             ], |  | ||||||
|             "version": "==3.7.4.3" |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,2 +0,0 @@ | |||||||
| from flipper import file |  | ||||||
| from flipper.file import File |  | ||||||
| @ -1,122 +0,0 @@ | |||||||
| from enum import Enum |  | ||||||
| 
 |  | ||||||
| import serial |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class RemoteIOError(IOError): |  | ||||||
|     pass |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class UnsupportedOperation(RemoteIOError): |  | ||||||
|     # TODO: Tell more on error |  | ||||||
|     pass |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class ReadWriteError(RemoteIOError): |  | ||||||
|     pass |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class FileMode(Enum): |  | ||||||
|     READ = "r" |  | ||||||
|     WRITE = "w" |  | ||||||
|     # APPEND = "a" - Not Impl |  | ||||||
|     # READ_WRITE = "w+" |  | ||||||
|     # READ_APPEND = "a+" |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class File: |  | ||||||
|     opened: bool = False |  | ||||||
|     filename: str |  | ||||||
|     conn: serial.Serial |  | ||||||
|     mode = FileMode.READ |  | ||||||
| 
 |  | ||||||
|     def _open(self): |  | ||||||
|         # Opening file on Flipper's end |  | ||||||
|         self.conn.write(f"f_open {self.filename} {self.mode}\n".encode()) |  | ||||||
| 
 |  | ||||||
|         # Checking, if everything is OK. |  | ||||||
|         self.conn.write(b"f_valid\n") |  | ||||||
|         return bool(int(self.conn.read_until().decode())) |  | ||||||
| 
 |  | ||||||
|     def __init__(self, conn: serial.Serial, filename: str, mode=FileMode.READ): |  | ||||||
|         self.conn = conn |  | ||||||
|         self.mode = mode |  | ||||||
|         self.filename = filename |  | ||||||
| 
 |  | ||||||
|         if not self._open(): |  | ||||||
|             raise RemoteIOError |  | ||||||
|         self.opened = True |  | ||||||
| 
 |  | ||||||
|     def lseek(self, size: int): |  | ||||||
|         self.conn.write(f"f_lseek {size}\n".encode()) |  | ||||||
| 
 |  | ||||||
|     def tell(self): |  | ||||||
|         self.conn.write(b"f_tell\n") |  | ||||||
|         return int(self.conn.read_until().decode()) |  | ||||||
| 
 |  | ||||||
|     def size(self): |  | ||||||
|         self.conn.write(b"f_size\n") |  | ||||||
|         return int(self.conn.read_until().decode()) |  | ||||||
| 
 |  | ||||||
|     def write(self, data: bytes): |  | ||||||
|         if self.mode != FileMode.WRITE: |  | ||||||
|             raise UnsupportedOperation |  | ||||||
|         self.conn.write(f"f_write {len(data)}\n".encode()) |  | ||||||
|         self.conn.write(data) |  | ||||||
|         self.conn.write(b"\n") |  | ||||||
| 
 |  | ||||||
|         if self.conn.read_until().decode().strip() != "OK": |  | ||||||
|             raise ReadWriteError |  | ||||||
| 
 |  | ||||||
|     def read(self, size: int) -> bytes: |  | ||||||
|         self.conn.write(f"f_read {size}\n".encode()) |  | ||||||
|         return self.conn.read(size) |  | ||||||
| 
 |  | ||||||
|     def _close(self): |  | ||||||
|         self.conn.write(b"f_close\n") |  | ||||||
| 
 |  | ||||||
|     def close(self): |  | ||||||
|         self._close() |  | ||||||
|         # TODO: Add termination of remote file process. |  | ||||||
|         del self |  | ||||||
| 
 |  | ||||||
|     def read_all(self, block_size=128) -> bytes: |  | ||||||
|         """ |  | ||||||
|         Function to simplify reading of file over serial. |  | ||||||
| 
 |  | ||||||
|         :return: content of file represented in `bytes` |  | ||||||
|         """ |  | ||||||
|         size = self.size() |  | ||||||
|         a = bytearray() |  | ||||||
|         seek = 0 |  | ||||||
|         # Reading in blocks of block_size |  | ||||||
|         while seek < block_size * (size // block_size - 1): |  | ||||||
|             seek += block_size |  | ||||||
|             self.lseek(seek) |  | ||||||
|             a.extend(self.read(block_size)) |  | ||||||
| 
 |  | ||||||
|         seek += block_size |  | ||||||
|         self.lseek(seek) |  | ||||||
|         a.extend(self.read(size - seek))  # Appending mod |  | ||||||
| 
 |  | ||||||
|         self.lseek(0)  # Resetting seek to default-position |  | ||||||
| 
 |  | ||||||
|         return bytes(a) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def push(ser: serial.Serial, local_path, remote_path): |  | ||||||
|     with open(local_path, "rb") as local_f:  # Reading local file |  | ||||||
|         a = local_f.read() |  | ||||||
| 
 |  | ||||||
|     remote_f = File(ser, remote_path, FileMode.WRITE) |  | ||||||
|     remote_f.write(a) |  | ||||||
|     remote_f.close() |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def pull(ser: serial.Serial, remote_path, local_path): |  | ||||||
|     remote_f = File(ser, remote_path, FileMode.READ) |  | ||||||
| 
 |  | ||||||
|     with open(local_path, "wb") as f: |  | ||||||
|         f.write(remote_f.read_all()) |  | ||||||
| 
 |  | ||||||
|     remote_f.close() |  | ||||||
							
								
								
									
										39
									
								
								flp/flp.py
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								flp/flp.py
									
									
									
									
									
								
							| @ -1,39 +0,0 @@ | |||||||
| import flipper |  | ||||||
| import serial |  | ||||||
| import click |  | ||||||
| 
 |  | ||||||
| DEFAULT_TTY = "/dev/ttyUSB0" |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| @click.group() |  | ||||||
| def cli(): |  | ||||||
|     pass |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| @cli.group() |  | ||||||
| def fs(): |  | ||||||
|     pass |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| @fs.command() |  | ||||||
| @click.argument("file_in", type=click.Path(exists=True)) |  | ||||||
| @click.argument("file_out") |  | ||||||
| @click.option("--port", default=DEFAULT_TTY) |  | ||||||
| def push(file_in, file_out, port): |  | ||||||
|     with serial.Serial(port, 115200, timeout=10) as p: |  | ||||||
|         flipper.file.push(p, file_in, file_out) |  | ||||||
|     print("OK.") |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| @fs.command() |  | ||||||
| @click.argument("file_in") |  | ||||||
| @click.argument("file_out", type=click.Path()) |  | ||||||
| @click.option("--port", default=DEFAULT_TTY) |  | ||||||
| def pull(file_in, file_out, port): |  | ||||||
|     with serial.Serial(port, 115200, timeout=10) as p: |  | ||||||
|         flipper.file.pull(p, file_in, file_out) |  | ||||||
|     print("OK.") |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| if __name__ == "__main__": |  | ||||||
|     cli() |  | ||||||
							
								
								
									
										589
									
								
								lib/ui/ui.cpp
									
									
									
									
									
								
							
							
						
						
									
										589
									
								
								lib/ui/ui.cpp
									
									
									
									
									
								
							| @ -1,589 +0,0 @@ | |||||||
| #include <stdio.h> |  | ||||||
| 
 |  | ||||||
| extern "C" { |  | ||||||
|     #include "main.h" |  | ||||||
|     #include "cmsis_os.h" |  | ||||||
|     #include "u8g2_support.h" |  | ||||||
|     #include "u8g2/u8g2.h" |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #include "ui.h" |  | ||||||
| #include "events.h" |  | ||||||
| 
 |  | ||||||
| // function draw basic layout -- single bmp
 |  | ||||||
| void draw_bitmap(const char* bitmap, u8g2_t* u8g2, ScreenArea area) { |  | ||||||
|     if(bitmap == NULL) { |  | ||||||
|         printf("[basic layout] no content\n"); |  | ||||||
|         u8g2_SetFont(u8g2, u8g2_font_6x10_mf); |  | ||||||
|         u8g2_SetDrawColor(u8g2, 1); |  | ||||||
|         u8g2_SetFontMode(u8g2, 1); |  | ||||||
|         u8g2_DrawStr(u8g2, 2, 12, "no content"); |  | ||||||
|     } else { |  | ||||||
|         u8g2_SetDrawColor(u8g2, 1); |  | ||||||
|         u8g2_DrawXBM(u8g2, 0, 0, area.x + area.width, area.y + area.height, (unsigned char*)bitmap); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void draw_text(const char* text, u8g2_t* u8g2, ScreenArea area) { |  | ||||||
|     // TODO proper cleanup statusbar
 |  | ||||||
|     u8g2_SetDrawColor(u8g2, 0); |  | ||||||
|     u8g2_DrawBox(u8g2, 0, 0, area.x + area.width, area.y + area.height); |  | ||||||
| 
 |  | ||||||
|     Block text_block = Block { |  | ||||||
|         width: area.width, |  | ||||||
|         height: area.height, |  | ||||||
|         margin_left: 0, |  | ||||||
|         margin_top: 0, |  | ||||||
|         padding_left: 3, |  | ||||||
|         padding_top: 7, |  | ||||||
|         background: 0, |  | ||||||
|         color: 1, |  | ||||||
|         font: (uint8_t*)u8g2_font_6x10_mf, |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     draw_block(u8g2, text, text_block, area.x, area.y); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // draw layout and switch between ui item by button and timer
 |  | ||||||
| void LayoutComponent::handle(Event* event, Store* store, u8g2_t* u8g2, ScreenArea area) { |  | ||||||
|     switch(event->type) { |  | ||||||
|         // get button event
 |  | ||||||
|         case EventTypeButton: |  | ||||||
|             if(event->value.button.state) { |  | ||||||
|                 for(size_t i = 0; i < this->actions_size; i++) { |  | ||||||
|                     FlipperComponent* next = NULL; |  | ||||||
| 
 |  | ||||||
|                     switch(this->actions[i].action) { |  | ||||||
|                         case LayoutActionUp: |  | ||||||
|                             if(event->value.button.id == ButtonsUp) { |  | ||||||
|                                 next = this->actions[i].item; |  | ||||||
|                             } |  | ||||||
|                         break; |  | ||||||
|                         case LayoutActionDown: |  | ||||||
|                             if(event->value.button.id == ButtonsDown) { |  | ||||||
|                                 next = this->actions[i].item; |  | ||||||
|                             } |  | ||||||
|                         break; |  | ||||||
|                         case LayoutActionLeft: |  | ||||||
|                             if(event->value.button.id == ButtonsLeft) { |  | ||||||
|                                 next = this->actions[i].item; |  | ||||||
|                             } |  | ||||||
|                         break; |  | ||||||
|                         case LayoutActionRight: |  | ||||||
|                             if(event->value.button.id == ButtonsRight) { |  | ||||||
|                                 next = this->actions[i].item; |  | ||||||
|                             } |  | ||||||
|                         break; |  | ||||||
|                         case LayoutActionOk: |  | ||||||
|                             if(event->value.button.id == ButtonsOk) { |  | ||||||
|                                 next = this->actions[i].item; |  | ||||||
|                             } |  | ||||||
|                         break; |  | ||||||
|                         case LayoutActionBack: |  | ||||||
|                             if(event->value.button.id == ButtonsBack) { |  | ||||||
|                                 next = this->actions[i].item; |  | ||||||
|                             } |  | ||||||
|                         break; |  | ||||||
| 
 |  | ||||||
|                         // stub action
 |  | ||||||
|                         case LayoutActionUsbDisconnect: |  | ||||||
|                             if(event->value.button.id == ButtonsLeft) { |  | ||||||
|                                 next = this->actions[i].item; |  | ||||||
|                             } |  | ||||||
|                         break; |  | ||||||
| 
 |  | ||||||
|                         case LayoutActionUsbConnect: |  | ||||||
|                             if(event->value.button.id == ButtonsRight) { |  | ||||||
|                                 next = this->actions[i].item; |  | ||||||
|                             } |  | ||||||
|                         break; |  | ||||||
| 
 |  | ||||||
|                         default: break; |  | ||||||
|                     } |  | ||||||
| 
 |  | ||||||
|                     if(next) { |  | ||||||
|                         printf("[layout view] go to next item\n"); |  | ||||||
|                         Event send_event; |  | ||||||
|                         send_event.type = EventTypeUiNext; |  | ||||||
|                         next->handle( |  | ||||||
|                             &send_event, |  | ||||||
|                             store, |  | ||||||
|                             u8g2, |  | ||||||
|                             area |  | ||||||
|                         ); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         break; |  | ||||||
| 
 |  | ||||||
|         case EventTypeUsb: { |  | ||||||
|             printf("get usb event\n"); |  | ||||||
|              |  | ||||||
|             FlipperComponent* next = NULL; |  | ||||||
| 
 |  | ||||||
|             if(event->value.usb == UsbEventConnect) { |  | ||||||
|                 for(size_t i = 0; i < this->actions_size; i++) { |  | ||||||
|                     if(this->actions[i].action == LayoutActionUsbConnect) { |  | ||||||
|                         next = this->actions[i].item; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if(event->value.usb == UsbEventDisconnect) { |  | ||||||
|                 for(size_t i = 0; i < this->actions_size; i++) { |  | ||||||
|                     if(this->actions[i].action == LayoutActionUsbDisconnect) { |  | ||||||
|                         next = this->actions[i].item; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if(next) { |  | ||||||
|                 printf("[layout view] go to next item\n"); |  | ||||||
|                 Event send_event; |  | ||||||
|                 send_event.type = EventTypeUiNext; |  | ||||||
|                 next->handle( |  | ||||||
|                     &send_event, |  | ||||||
|                     store, |  | ||||||
|                     u8g2, |  | ||||||
|                     area |  | ||||||
|                 ); |  | ||||||
|             } |  | ||||||
|         } break; |  | ||||||
| 
 |  | ||||||
|         // start component from prev
 |  | ||||||
|         case EventTypeUiNext: |  | ||||||
|             printf("[layout view] start component %lX\n", (uint32_t)this); |  | ||||||
| 
 |  | ||||||
|             if(this->timeout > 0) { |  | ||||||
|                 // TODO start timer
 |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             // set current item to self
 |  | ||||||
|             store->current_component = this; |  | ||||||
| 
 |  | ||||||
|             this->wait_time = 0; |  | ||||||
| 
 |  | ||||||
|             // render layout
 |  | ||||||
|             this->dirty = true; |  | ||||||
|         break; |  | ||||||
| 
 |  | ||||||
|         case EventTypeTick: |  | ||||||
|             this->wait_time += event->value.tick_delta; |  | ||||||
| 
 |  | ||||||
|             if(this->wait_time > this->timeout) { |  | ||||||
|                 for(size_t i = 0; i < this->actions_size; i++) { |  | ||||||
|                     if(this->actions[i].action == LayoutActionTimeout || |  | ||||||
|                         this->actions[i].action == LayoutActionEndOfCycle |  | ||||||
|                     ) { |  | ||||||
|                         if(this->actions[i].item != NULL) { |  | ||||||
|                             printf("[layout view] go to next item\n"); |  | ||||||
|                             Event send_event; |  | ||||||
|                             send_event.type = EventTypeUiNext; |  | ||||||
|                             this->actions[i].item->handle( |  | ||||||
|                                 &send_event, |  | ||||||
|                                 store, |  | ||||||
|                                 u8g2, |  | ||||||
|                                 area |  | ||||||
|                             ); |  | ||||||
| 
 |  | ||||||
|                             return; |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if(this->dirty) { |  | ||||||
|                 this->draw_fn(this->data, u8g2, area); |  | ||||||
| 
 |  | ||||||
|                 store->dirty_screen = true; |  | ||||||
| 
 |  | ||||||
|                 this->dirty = false; |  | ||||||
|             } |  | ||||||
|         break; |  | ||||||
| 
 |  | ||||||
|         default: break; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void BlinkerComponent::handle(Event* event, Store* store, u8g2_t* u8g2, ScreenArea area) { |  | ||||||
|     switch(event->type) { |  | ||||||
|         // get button event
 |  | ||||||
|         case EventTypeButton: |  | ||||||
|             if(event->value.button.state && event->value.button.id == ButtonsBack) { |  | ||||||
|                 if(this->prev && this->prev != this) { |  | ||||||
|                     printf("[blinker view] go back\n"); |  | ||||||
| 
 |  | ||||||
|                     Event send_event; |  | ||||||
|                     send_event.type = EventTypeUiNext; |  | ||||||
|                     this->prev->handle( |  | ||||||
|                         &send_event, |  | ||||||
|                         store, |  | ||||||
|                         u8g2, |  | ||||||
|                         area |  | ||||||
|                     ); |  | ||||||
| 
 |  | ||||||
|                     this->prev = NULL; |  | ||||||
| 
 |  | ||||||
|                     store->led = ColorBlack; |  | ||||||
|                     this->wait_time = 0; |  | ||||||
|                     this->is_on = true; |  | ||||||
|                     this->active = false; |  | ||||||
|                 } else { |  | ||||||
|                     printf("[blinker view] no back/loop\n"); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if(event->value.button.state && event->value.button.id != ButtonsBack) { |  | ||||||
|                 this->active = false; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if(!event->value.button.state && event->value.button.id != ButtonsBack) { |  | ||||||
|                 this->active = true; |  | ||||||
|             } |  | ||||||
|         break; |  | ||||||
| 
 |  | ||||||
|         // start component from prev
 |  | ||||||
|         case EventTypeUiNext: |  | ||||||
|             printf("[blinker view] start component %lX\n", (uint32_t)this); |  | ||||||
| 
 |  | ||||||
|             if(this->prev == NULL) { |  | ||||||
|                 this->prev = store->current_component; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             // set current item to self
 |  | ||||||
|             store->current_component = this; |  | ||||||
| 
 |  | ||||||
|             this->dirty = true; |  | ||||||
|             this->wait_time = 0; |  | ||||||
|             this->is_on = true; |  | ||||||
|             this->active = false; |  | ||||||
|         break; |  | ||||||
| 
 |  | ||||||
|         case EventTypeTick: |  | ||||||
|             if(this->active) { |  | ||||||
|                 this->wait_time += event->value.tick_delta; |  | ||||||
| 
 |  | ||||||
|                 if(this->is_on) { |  | ||||||
|                     if(this->wait_time > this->config.on_time) { |  | ||||||
|                         this->wait_time = 0; |  | ||||||
|                         this->is_on = false; |  | ||||||
|                     } |  | ||||||
|                 } else { |  | ||||||
|                     if(this->wait_time > this->config.off_time) { |  | ||||||
|                         this->wait_time = 0; |  | ||||||
|                         this->is_on = true; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 store->led = this->is_on ? this->config.on_color : this->config.off_color; |  | ||||||
|             } else { |  | ||||||
|                 store->led = ColorBlack; |  | ||||||
|                 this->wait_time = 0; |  | ||||||
|                 this->is_on = true; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if(this->dirty) { |  | ||||||
|                 this->draw_fn(this->data, u8g2, area); |  | ||||||
| 
 |  | ||||||
|                 store->dirty_screen = true; |  | ||||||
| 
 |  | ||||||
|                 this->dirty = false; |  | ||||||
|             } |  | ||||||
|         break; |  | ||||||
| 
 |  | ||||||
|         default: break; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| void BlinkerComponentOnBtn::handle(Event* event, Store* store, u8g2_t* u8g2, ScreenArea area) { |  | ||||||
|     switch(event->type) { |  | ||||||
|         // get button event
 |  | ||||||
|         case EventTypeButton: |  | ||||||
|             if(event->value.button.state && event->value.button.id == ButtonsBack) { |  | ||||||
|                 if(this->prev && this->prev != this) { |  | ||||||
|                     printf("[blinker view] go back\n"); |  | ||||||
| 
 |  | ||||||
|                     Event send_event; |  | ||||||
|                     send_event.type = EventTypeUiNext; |  | ||||||
|                     this->prev->handle( |  | ||||||
|                         &send_event, |  | ||||||
|                         store, |  | ||||||
|                         u8g2, |  | ||||||
|                         area |  | ||||||
|                     ); |  | ||||||
| 
 |  | ||||||
|                     this->prev = NULL; |  | ||||||
| 
 |  | ||||||
|                     store->led = ColorBlack; |  | ||||||
|                     this->wait_time = 0; |  | ||||||
|                     this->is_on = true; |  | ||||||
|                     this->active = false; |  | ||||||
|                 } else { |  | ||||||
|                     printf("[blinker view] no back/loop\n"); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if(event->value.button.state && event->value.button.id != ButtonsBack) { |  | ||||||
|                 this->active = true; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if(!event->value.button.state && event->value.button.id != ButtonsBack) { |  | ||||||
|                 this->active = false; |  | ||||||
|             } |  | ||||||
|         break; |  | ||||||
| 
 |  | ||||||
|         // start component from prev
 |  | ||||||
|         case EventTypeUiNext: |  | ||||||
|             printf("[blinker view] start component %lX\n", (uint32_t)this); |  | ||||||
| 
 |  | ||||||
|             if(this->prev == NULL) { |  | ||||||
|                 this->prev = store->current_component; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             // set current item to self
 |  | ||||||
|             store->current_component = this; |  | ||||||
| 
 |  | ||||||
|             this->dirty = true; |  | ||||||
|             this->wait_time = 0; |  | ||||||
|             this->is_on = true; |  | ||||||
|             this->active = false; |  | ||||||
|         break; |  | ||||||
| 
 |  | ||||||
|         case EventTypeTick: |  | ||||||
|             if(this->active) { |  | ||||||
|                 this->wait_time += event->value.tick_delta; |  | ||||||
| 
 |  | ||||||
|                 if(this->is_on) { |  | ||||||
|                     if(this->wait_time > this->config.on_time) { |  | ||||||
|                         this->wait_time = 0; |  | ||||||
|                         this->is_on = false; |  | ||||||
|                     } |  | ||||||
|                 } else { |  | ||||||
|                     if(this->wait_time > this->config.off_time) { |  | ||||||
|                         this->wait_time = 0; |  | ||||||
|                         this->is_on = true; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 store->led = this->is_on ? this->config.on_color : this->config.off_color; |  | ||||||
|             } else { |  | ||||||
|                 store->led = ColorBlack; |  | ||||||
|                 this->wait_time = 0; |  | ||||||
|                 this->is_on = true; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if(this->dirty) { |  | ||||||
|                 this->draw_fn(this->data, u8g2, area); |  | ||||||
| 
 |  | ||||||
|                 store->dirty_screen = true; |  | ||||||
| 
 |  | ||||||
|                 this->dirty = false; |  | ||||||
|             } |  | ||||||
|         break; |  | ||||||
| 
 |  | ||||||
|         default: break; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #define MENU_DRAW_LINES 4 |  | ||||||
| 
 |  | ||||||
| Point draw_block(u8g2_t* u8g2, const char* text, Block layout, uint8_t x, uint8_t y) { |  | ||||||
|     u8g2_SetDrawColor(u8g2, layout.background); |  | ||||||
|     u8g2_DrawBox(u8g2, |  | ||||||
|         x + layout.margin_left, |  | ||||||
|         y + layout.margin_top, |  | ||||||
|         layout.width, layout.height |  | ||||||
|     ); |  | ||||||
| 
 |  | ||||||
|     u8g2_SetDrawColor(u8g2, layout.color); |  | ||||||
|     u8g2_SetFont(u8g2, layout.font); |  | ||||||
|     if(text != NULL) { |  | ||||||
|         u8g2_DrawStr(u8g2, |  | ||||||
|             x + layout.margin_left + layout.padding_left, |  | ||||||
|             y + layout.margin_top + layout.padding_top, |  | ||||||
|             text |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return { |  | ||||||
|         x: x + layout.margin_left + layout.width, |  | ||||||
|         y: y + layout.margin_top + layout.height |  | ||||||
|     }; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void draw_menu(MenuCtx* ctx, u8g2_t* u8g2, ScreenArea area) { |  | ||||||
|     // u8g2_ClearBuffer(u8g2);
 |  | ||||||
|     // clear area
 |  | ||||||
|     u8g2_SetDrawColor(u8g2, 0); |  | ||||||
|     u8g2_DrawBox(u8g2, area.x, area.y, area.width, area.height); |  | ||||||
| 
 |  | ||||||
|     u8g2_SetFontMode(u8g2, 1); |  | ||||||
| 
 |  | ||||||
|     uint8_t list_start = ctx->current - ctx->cursor; |  | ||||||
|     uint8_t list_size = ctx->size > MENU_DRAW_LINES ? MENU_DRAW_LINES : ctx->size; |  | ||||||
| 
 |  | ||||||
|     // draw header
 |  | ||||||
|     /*
 |  | ||||||
|     Point next = draw_block(u8g2, (const char*)data->name, Block { |  | ||||||
|         width: 128, |  | ||||||
|         height: 14, |  | ||||||
|         margin_left: 0, |  | ||||||
|         margin_top: 0, |  | ||||||
|         padding_left: 4, |  | ||||||
|         padding_top: 13, |  | ||||||
|         background: 1, |  | ||||||
|         color: 0, |  | ||||||
|         font: (uint8_t*)u8g2_font_helvB14_tf, |  | ||||||
|     }, area.x, area.y); |  | ||||||
|     */ |  | ||||||
| 
 |  | ||||||
|     Point next = {area.x, area.y}; |  | ||||||
| 
 |  | ||||||
|     for(size_t i = 0; i < list_size; i++) { |  | ||||||
|         next = draw_block(u8g2, (const char*)ctx->list[list_start + i].name, Block { |  | ||||||
|             width: 128, |  | ||||||
|             height: 15, |  | ||||||
|             margin_left: 0, |  | ||||||
|             margin_top: i == 0 ? 2 : 0, |  | ||||||
|             padding_left: 2, |  | ||||||
|             padding_top: 12, |  | ||||||
|             background: i == ctx->cursor ? 1 : 0, |  | ||||||
|             color: i == ctx->cursor ? 0 : 1, |  | ||||||
|             font: (uint8_t*)u8g2_font_7x14_tf, |  | ||||||
|         }, area.x, next.y); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     // u8g2_font_7x14_tf
 |  | ||||||
|     // u8g2_font_profont12_tf smallerbut cute
 |  | ||||||
|     // u8g2_font_samim_12_t_all орочий
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void MenuCtx::handle(MenuEvent event) { |  | ||||||
|     uint8_t menu_size = this->size > MENU_DRAW_LINES ? MENU_DRAW_LINES : this->size; |  | ||||||
| 
 |  | ||||||
|     switch(event) { |  | ||||||
|         case MenuEventDown: { |  | ||||||
|             if(this->current < (this->size - 1)) { |  | ||||||
|                 this->current++; |  | ||||||
| 
 |  | ||||||
|                 if(this->cursor < menu_size - 2 || this->current == this->size - 1) { |  | ||||||
|                     this->cursor++; |  | ||||||
|                 } |  | ||||||
|             } else { |  | ||||||
|                 this->current = 0; |  | ||||||
|                 this->cursor = 0; |  | ||||||
|             } |  | ||||||
|         } break; |  | ||||||
| 
 |  | ||||||
|         case MenuEventUp: { |  | ||||||
|             if(this->current > 0) { |  | ||||||
|                 this->current--; |  | ||||||
| 
 |  | ||||||
|                 if(this->cursor > 1 || this->current == 0) { |  | ||||||
|                     this->cursor--; |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|             } else { |  | ||||||
|                 this->current = this->size - 1; |  | ||||||
|                 this->cursor = menu_size - 1; |  | ||||||
|             } |  | ||||||
|         } break; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void MenuCtx::reset() { |  | ||||||
|     this->current = 0; |  | ||||||
|     this->cursor = 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // draw numenu and handle navigation
 |  | ||||||
| void MenuComponent::handle(Event* event, Store* store, u8g2_t* u8g2, ScreenArea area) { |  | ||||||
|     switch(event->type) { |  | ||||||
|         // get button event
 |  | ||||||
|         case EventTypeButton: { |  | ||||||
|             if(event->value.button.id == ButtonsOk && event->value.button.state) { |  | ||||||
|                 if(this->ctx.current < this->ctx.size) { |  | ||||||
|                     FlipperComponent* next_item = (FlipperComponent*)this->ctx.list[this->ctx.current].item; |  | ||||||
| 
 |  | ||||||
|                     if(next_item) { |  | ||||||
|                         store->is_fullscreen = false; |  | ||||||
| 
 |  | ||||||
|                         printf("[layout view] go to %d item\n", this->ctx.current); |  | ||||||
|                         Event send_event; |  | ||||||
|                         send_event.type = EventTypeUiNext; |  | ||||||
| 
 |  | ||||||
|                         next_item->handle( |  | ||||||
|                             &send_event, |  | ||||||
|                             store, |  | ||||||
|                             u8g2, |  | ||||||
|                             area |  | ||||||
|                         ); |  | ||||||
|                     } else { |  | ||||||
|                         printf("[menu view] no item at %d\n", this->ctx.current); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if(event->value.button.id == ButtonsDown && event->value.button.state) { |  | ||||||
|                 this->ctx.handle(MenuEventDown); |  | ||||||
|                 this->dirty = true; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if(event->value.button.id == ButtonsUp && event->value.button.state) { |  | ||||||
|                 this->ctx.handle(MenuEventUp); |  | ||||||
|                 this->dirty = true; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             // go back item
 |  | ||||||
|             if(event->value.button.id == ButtonsBack && event->value.button.state) { |  | ||||||
|                 if(this->prev && this->prev != this) { |  | ||||||
|                     store->is_fullscreen = false; |  | ||||||
| 
 |  | ||||||
|                     printf("[menu view] go back\n"); |  | ||||||
| 
 |  | ||||||
|                     this->ctx.reset(); |  | ||||||
| 
 |  | ||||||
|                     Event send_event; |  | ||||||
|                     send_event.type = EventTypeUiNext; |  | ||||||
|                     this->prev->handle( |  | ||||||
|                         &send_event, |  | ||||||
|                         store, |  | ||||||
|                         u8g2, |  | ||||||
|                         area |  | ||||||
|                     ); |  | ||||||
| 
 |  | ||||||
|                     this->prev = NULL; |  | ||||||
|                 } else { |  | ||||||
|                     printf("[menu view] no back/loop\n"); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } break; |  | ||||||
| 
 |  | ||||||
|         // start component from prev
 |  | ||||||
|         case EventTypeUiNext: |  | ||||||
|             printf("[menu view] start component %lX (size %d)\n", (uint32_t)this, this->ctx.size); |  | ||||||
| 
 |  | ||||||
|             // set prev item
 |  | ||||||
|             if(this->prev == NULL) { |  | ||||||
|                 printf("[menu view] set prev element to %lX\n", (uint32_t)store->current_component); |  | ||||||
|                 this->prev = store->current_component; |  | ||||||
|             } |  | ||||||
|             // set current item to self
 |  | ||||||
|             store->current_component = this; |  | ||||||
| 
 |  | ||||||
|             store->is_fullscreen = true; |  | ||||||
| 
 |  | ||||||
|             // render menu
 |  | ||||||
|             this->dirty = true; |  | ||||||
|         break; |  | ||||||
| 
 |  | ||||||
|         case EventTypeTick: |  | ||||||
|             if(this->dirty) { |  | ||||||
|                 draw_menu(&this->ctx, u8g2, area); |  | ||||||
|                 store->dirty_screen = true; |  | ||||||
|                 this->dirty = false; |  | ||||||
|             } |  | ||||||
|         break; |  | ||||||
| 
 |  | ||||||
|         default: break; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
							
								
								
									
										218
									
								
								lib/ui/ui.h
									
									
									
									
									
								
							
							
						
						
									
										218
									
								
								lib/ui/ui.h
									
									
									
									
									
								
							| @ -1,218 +0,0 @@ | |||||||
| #pragma once |  | ||||||
| 
 |  | ||||||
| extern "C" { |  | ||||||
|     #include "main.h" |  | ||||||
|     #include "cmsis_os.h" |  | ||||||
|     #include "u8g2_support.h" |  | ||||||
|     #include "u8g2/u8g2.h" |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #include "events.h" |  | ||||||
| 
 |  | ||||||
| typedef struct { |  | ||||||
|     void* item; |  | ||||||
|     const char* name; |  | ||||||
| } MenuItem; |  | ||||||
| 
 |  | ||||||
| #include "vendor.h" |  | ||||||
| 
 |  | ||||||
| typedef enum { |  | ||||||
|     LayoutActionUp, |  | ||||||
|     LayoutActionDown, |  | ||||||
|     LayoutActionLeft, |  | ||||||
|     LayoutActionRight, |  | ||||||
|     LayoutActionOk, |  | ||||||
|     LayoutActionBack, |  | ||||||
|     LayoutActionTimeout, |  | ||||||
|     LayoutActionUsbConnect, |  | ||||||
|     LayoutActionUsbDisconnect, |  | ||||||
|     LayoutActionEndOfCycle |  | ||||||
| } LayoutAction; |  | ||||||
| 
 |  | ||||||
| typedef struct { |  | ||||||
|     FlipperComponent* item; |  | ||||||
|     LayoutAction action; |  | ||||||
| } ActionItem; |  | ||||||
| 
 |  | ||||||
| void draw_text(const char* text, u8g2_t* u8g2, ScreenArea area); |  | ||||||
| void draw_bitmap(const char* bitmap, u8g2_t* u8g2, ScreenArea area); |  | ||||||
| 
 |  | ||||||
| class LayoutComponent: FlipperComponent { |  | ||||||
| public: |  | ||||||
|     LayoutComponent(void (*draw_fn)(const char* text, u8g2_t* u8g2, ScreenArea area), ActionItem* actions, size_t actions_size, uint32_t timeout, const char* data) { |  | ||||||
|         this->data = data; |  | ||||||
|         this->actions = actions; |  | ||||||
|         this->actions_size = actions_size; |  | ||||||
|         this->timeout = timeout; |  | ||||||
|         this->draw_fn = draw_fn; |  | ||||||
| 
 |  | ||||||
|         this->dirty = true; |  | ||||||
| 
 |  | ||||||
|         this->wait_time = 0; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     virtual void handle(Event* event, struct _Store* store, u8g2_t* u8g2, ScreenArea area); |  | ||||||
| 
 |  | ||||||
| private: |  | ||||||
|     const char* data; |  | ||||||
|     ActionItem* actions; |  | ||||||
|     size_t actions_size; |  | ||||||
|     uint32_t timeout; |  | ||||||
| 
 |  | ||||||
|     void (*draw_fn)(const char* text, u8g2_t* u8g2, ScreenArea area); |  | ||||||
| 
 |  | ||||||
|     uint32_t wait_time; |  | ||||||
| 
 |  | ||||||
|     bool dirty; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| typedef struct { |  | ||||||
|     uint32_t on_time; |  | ||||||
|     Color on_color; |  | ||||||
|     uint32_t off_time; |  | ||||||
|     Color off_color; |  | ||||||
| } BlinkerComponentConfig; |  | ||||||
| 
 |  | ||||||
| class BlinkerComponent: FlipperComponent { |  | ||||||
| public: |  | ||||||
|     BlinkerComponent( |  | ||||||
|         void (*draw_fn)(const char* text, u8g2_t* u8g2, ScreenArea area), |  | ||||||
|         BlinkerComponentConfig config, |  | ||||||
|         const char* data |  | ||||||
|     ) { |  | ||||||
|         this->data = data; |  | ||||||
|         this->draw_fn = draw_fn; |  | ||||||
|         this->config = config; |  | ||||||
| 
 |  | ||||||
|         this->dirty = true; |  | ||||||
| 
 |  | ||||||
|         this->wait_time = 0; |  | ||||||
|         this->is_on = true; |  | ||||||
|         this->active = false; |  | ||||||
|         this->prev = NULL; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     virtual void handle(Event* event, struct _Store* store, u8g2_t* u8g2, ScreenArea area); |  | ||||||
| 
 |  | ||||||
| private: |  | ||||||
|     const char* data; |  | ||||||
|     BlinkerComponentConfig config; |  | ||||||
| 
 |  | ||||||
|     void (*draw_fn)(const char* text, u8g2_t* u8g2, ScreenArea area); |  | ||||||
| 
 |  | ||||||
|     uint32_t wait_time; |  | ||||||
| 
 |  | ||||||
|     bool is_on; |  | ||||||
|     bool active; |  | ||||||
| 
 |  | ||||||
|     bool dirty; |  | ||||||
|     FlipperComponent* prev; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| typedef struct { |  | ||||||
|     uint32_t on_time; |  | ||||||
|     Color on_color; |  | ||||||
|     uint32_t off_time; |  | ||||||
|     Color off_color; |  | ||||||
| } BlinkerComponentOnBtnConfig; |  | ||||||
| 
 |  | ||||||
| class BlinkerComponentOnBtn: FlipperComponent { |  | ||||||
| public: |  | ||||||
|     BlinkerComponentOnBtn( |  | ||||||
|         void (*draw_fn)(const char* text, u8g2_t* u8g2, ScreenArea area), |  | ||||||
|         BlinkerComponentOnBtnConfig config, |  | ||||||
|         const char* data |  | ||||||
|     ) { |  | ||||||
|         this->data = data; |  | ||||||
|         this->draw_fn = draw_fn; |  | ||||||
|         this->config = config; |  | ||||||
| 
 |  | ||||||
|         this->dirty = true; |  | ||||||
| 
 |  | ||||||
|         this->wait_time = 0; |  | ||||||
|         this->is_on = true; |  | ||||||
|         this->active = false; |  | ||||||
|         this->prev = NULL; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     virtual void handle(Event* event, struct _Store* store, u8g2_t* u8g2, ScreenArea area); |  | ||||||
| 
 |  | ||||||
| private: |  | ||||||
|     const char* data; |  | ||||||
|     BlinkerComponentOnBtnConfig config; |  | ||||||
| 
 |  | ||||||
|     void (*draw_fn)(const char* text, u8g2_t* u8g2, ScreenArea area); |  | ||||||
| 
 |  | ||||||
|     uint32_t wait_time; |  | ||||||
| 
 |  | ||||||
|     bool is_on; |  | ||||||
|     bool active; |  | ||||||
| 
 |  | ||||||
|     bool dirty; |  | ||||||
|     FlipperComponent* prev; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| typedef enum { |  | ||||||
|     MenuEventUp, |  | ||||||
|     MenuEventDown |  | ||||||
| } MenuEvent; |  | ||||||
| 
 |  | ||||||
| class MenuCtx { |  | ||||||
| public: |  | ||||||
|     size_t size; |  | ||||||
|     size_t current; |  | ||||||
|     uint8_t cursor; |  | ||||||
|     MenuItem* list; |  | ||||||
| 
 |  | ||||||
|     void handle(MenuEvent event); |  | ||||||
|     void reset(); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| void draw_menu(MenuCtx* ctx, u8g2_t* u8g2, ScreenArea area); |  | ||||||
| 
 |  | ||||||
| class MenuComponent: FlipperComponent { |  | ||||||
| public: |  | ||||||
|     MenuComponent(MenuItem* list, size_t size, const char* name) { |  | ||||||
|         this->ctx.size = size; |  | ||||||
|         this->ctx.current = 0; |  | ||||||
|         this->ctx.cursor = 0; |  | ||||||
| 
 |  | ||||||
|         this->ctx.list = list; |  | ||||||
|          |  | ||||||
|         this->name = name; |  | ||||||
|         this->prev = NULL; |  | ||||||
| 
 |  | ||||||
|         this->dirty = true; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
|     const char* name; |  | ||||||
|     FlipperComponent* prev; |  | ||||||
|     MenuCtx ctx; |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|     bool dirty; |  | ||||||
| 
 |  | ||||||
|     virtual void handle(Event* event, struct _Store* store, u8g2_t* u8g2, ScreenArea area); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| typedef struct { |  | ||||||
|     uint8_t x; |  | ||||||
|     uint8_t y; |  | ||||||
| } Point; |  | ||||||
| 
 |  | ||||||
| typedef struct { |  | ||||||
|     uint8_t width; |  | ||||||
|     uint8_t height; |  | ||||||
|     uint8_t margin_left; |  | ||||||
|     uint8_t margin_top; |  | ||||||
|     uint8_t padding_left; |  | ||||||
|     uint8_t padding_top; |  | ||||||
|     uint8_t background; |  | ||||||
|     uint8_t color; |  | ||||||
|     uint8_t* font; |  | ||||||
| } Block; |  | ||||||
| 
 |  | ||||||
| Point draw_block(u8g2_t* u8g2, const char* text, Block layout, uint8_t x, uint8_t y); |  | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 あく
						あく