3
3
#include <input/input.h>
4
4
#include <stdlib.h>
5
5
#include <counter_icons.h>
6
+ #include <notification/notification.h>
7
+ #include <notification/notification_messages.h>
6
8
7
- #define MAX_COUNT 99
9
+ #define MAX_COUNT 99999
10
+ #define NUM_WIDTH 12
8
11
#define BOXTIME 2
9
- #define BOXWIDTH 30
10
- #define MIDDLE_X 64 - BOXWIDTH / 2
11
- #define MIDDLE_Y 32 - BOXWIDTH / 2
12
+ #define MIN_BOXWIDTH 30
13
+ #define BOXHEIGHT 30
14
+ #define MIDDLE_Y 32 - BOXHEIGHT / 2
15
+ #define OFFSET_X 8
12
16
#define OFFSET_Y 9
17
+ #define VIBRO_TIME_MS 20
13
18
14
19
typedef struct {
15
20
FuriMessageQueue * input_queue ;
16
21
ViewPort * view_port ;
17
22
Gui * gui ;
18
23
FuriMutex * * mutex ;
24
+ NotificationApp * notifications ;
19
25
20
26
int count ;
21
27
bool pressed ;
22
28
int boxtimer ;
29
+ bool vibro ;
23
30
} Counter ;
24
31
25
32
void state_free (Counter * c ) {
@@ -33,7 +40,7 @@ void state_free(Counter* c) {
33
40
34
41
static void input_callback (InputEvent * input_event , void * ctx ) {
35
42
Counter * c = ctx ;
36
- if (input_event -> type == InputTypeShort ) {
43
+ if (input_event -> type == InputTypeShort || input_event -> type == InputTypeLong ) {
37
44
furi_message_queue_put (c -> input_queue , input_event , 0 );
38
45
}
39
46
}
@@ -47,19 +54,25 @@ static void render_callback(Canvas* canvas, void* ctx) {
47
54
canvas_draw_str_aligned (canvas , 64 , 10 , AlignCenter , AlignCenter , "Counter :)" );
48
55
canvas_set_font (canvas , FontBigNumbers );
49
56
50
- char scount [5 ];
57
+ char scount [8 ];
58
+ snprintf (scount , sizeof (scount ), "%d" , c -> count );
59
+ size_t cntr_len = strlen (scount );
60
+ size_t boxwidth = cntr_len * NUM_WIDTH + OFFSET_X ;
61
+ if (boxwidth < MIN_BOXWIDTH ) {
62
+ boxwidth = MIN_BOXWIDTH ;
63
+ }
64
+ size_t middle_x = 64 - boxwidth / 2 ;
51
65
if (c -> pressed == true || c -> boxtimer > 0 ) {
52
- canvas_draw_rframe (canvas , MIDDLE_X , MIDDLE_Y + OFFSET_Y , BOXWIDTH , BOXWIDTH , 5 );
66
+ canvas_draw_rframe (canvas , middle_x , MIDDLE_Y + OFFSET_Y , boxwidth , BOXHEIGHT , 5 );
53
67
canvas_draw_rframe (
54
- canvas , MIDDLE_X - 1 , MIDDLE_Y + OFFSET_Y - 1 , BOXWIDTH + 2 , BOXWIDTH + 2 , 5 );
68
+ canvas , middle_x - 1 , MIDDLE_Y + OFFSET_Y - 1 , boxwidth + 2 , BOXHEIGHT + 2 , 5 );
55
69
canvas_draw_rframe (
56
- canvas , MIDDLE_X - 2 , MIDDLE_Y + OFFSET_Y - 2 , BOXWIDTH + 4 , BOXWIDTH + 4 , 5 );
70
+ canvas , middle_x - 2 , MIDDLE_Y + OFFSET_Y - 2 , boxwidth + 4 , BOXHEIGHT + 4 , 5 );
57
71
c -> pressed = false;
58
72
c -> boxtimer -- ;
59
73
} else {
60
- canvas_draw_rframe (canvas , MIDDLE_X , MIDDLE_Y + OFFSET_Y , BOXWIDTH , BOXWIDTH , 5 );
74
+ canvas_draw_rframe (canvas , middle_x , MIDDLE_Y + OFFSET_Y , boxwidth , BOXHEIGHT , 5 );
61
75
}
62
- snprintf (scount , sizeof (scount ), "%d" , c -> count );
63
76
canvas_draw_str_aligned (canvas , 64 , 32 + OFFSET_Y , AlignCenter , AlignCenter , scount );
64
77
furi_mutex_release (c -> mutex );
65
78
}
@@ -70,8 +83,10 @@ Counter* state_init() {
70
83
c -> view_port = view_port_alloc ();
71
84
c -> gui = furi_record_open (RECORD_GUI );
72
85
c -> mutex = furi_mutex_alloc (FuriMutexTypeNormal );
86
+ c -> notifications = furi_record_open (RECORD_NOTIFICATION );
73
87
c -> count = 0 ;
74
88
c -> boxtimer = 0 ;
89
+ c -> vibro = false;
75
90
view_port_input_callback_set (c -> view_port , input_callback , c );
76
91
view_port_draw_callback_set (c -> view_port , render_callback , c );
77
92
gui_add_view_port (c -> gui , c -> view_port , GuiLayerFullscreen );
@@ -81,25 +96,55 @@ Counter* state_init() {
81
96
int32_t counterapp (void ) {
82
97
Counter * c = state_init ();
83
98
84
- while ( 1 ) {
85
- InputEvent input ;
99
+ InputEvent input ;
100
+ for ( bool processing = true; processing ;) {
86
101
while (furi_message_queue_get (c -> input_queue , & input , FuriWaitForever ) == FuriStatusOk ) {
87
102
furi_check (furi_mutex_acquire (c -> mutex , FuriWaitForever ) == FuriStatusOk );
88
103
89
- if (input .key == InputKeyBack ) {
90
- furi_mutex_release (c -> mutex );
91
- state_free (c );
92
- return 0 ;
93
- } else if ((input .key == InputKeyUp || input .key == InputKeyOk ) && c -> count < MAX_COUNT ) {
94
- c -> pressed = true;
95
- c -> boxtimer = BOXTIME ;
96
- c -> count ++ ;
97
- } else if (input .key == InputKeyDown && c -> count != 0 ) {
98
- c -> pressed = true;
99
- c -> boxtimer = BOXTIME ;
100
- c -> count -- ;
104
+ if (input .type == InputTypeShort ) {
105
+ switch (input .key ) {
106
+ case InputKeyBack :
107
+ processing = false;
108
+ break ;
109
+ case InputKeyUp :
110
+ case InputKeyOk :
111
+ if (c -> count < MAX_COUNT ) {
112
+ c -> pressed = true;
113
+ c -> boxtimer = BOXTIME ;
114
+ c -> count ++ ;
115
+ if (c -> vibro ) {
116
+ notification_message (c -> notifications , & sequence_set_vibro_on );
117
+ furi_delay_ms (VIBRO_TIME_MS );
118
+ notification_message (c -> notifications , & sequence_reset_vibro );
119
+ }
120
+ }
121
+ break ;
122
+ case InputKeyDown :
123
+ if (c -> count > 0 ) {
124
+ c -> pressed = true;
125
+ c -> boxtimer = BOXTIME ;
126
+ c -> count -- ;
127
+ }
128
+ break ;
129
+ default :
130
+ break ;
131
+ }
132
+ } else if (input .type == InputTypeLong ) {
133
+ switch (input .key ) {
134
+ case InputKeyBack :
135
+ c -> count = 0 ;
136
+ break ;
137
+ case InputKeyOk :
138
+ c -> vibro = !c -> vibro ;
139
+ break ;
140
+ default :
141
+ break ;
142
+ }
101
143
}
102
144
furi_mutex_release (c -> mutex );
145
+ if (!processing ) {
146
+ break ;
147
+ }
103
148
view_port_update (c -> view_port );
104
149
}
105
150
}
0 commit comments