This commit is contained in:
Willy-JL
2023-07-25 19:43:51 +02:00
90 changed files with 1764 additions and 1075 deletions

View File

@@ -1,81 +1,52 @@
#include "totp_input_text.h"
#include <gui/view_i.h>
void view_draw(View* view, Canvas* canvas) {
furi_assert(view);
if(view->draw_callback) {
void* data = view_get_model(view);
view->draw_callback(canvas, data);
view_unlock_model(view);
}
#include <gui/view_dispatcher.h>
#include <gui/modules/text_input.h>
typedef struct {
InputTextResult* result;
ViewDispatcher* view_dispatcher;
} InputTextContext;
static void commit_text_input_callback(void* ctx) {
InputTextContext* context = ctx;
context->result->user_input_length = strnlen(context->result->user_input, INPUT_BUFFER_SIZE);
context->result->success = true;
view_dispatcher_stop(context->view_dispatcher);
}
bool view_input(View* view, InputEvent* event) {
furi_assert(view);
if(view->input_callback) {
return view->input_callback(event, view->context);
} else {
return false;
}
static bool back_event_callback(void* ctx) {
InputTextContext* context = ctx;
context->result->success = false;
view_dispatcher_stop(context->view_dispatcher);
return false;
}
void view_unlock_model(View* view) {
furi_assert(view);
if(view->model_type == ViewModelTypeLocking) {
ViewModelLocking* model = (ViewModelLocking*)(view->model);
furi_check(furi_mutex_release(model->mutex) == FuriStatusOk);
}
}
static void commit_text_input_callback(void* context) {
InputTextSceneState* text_input_state = (InputTextSceneState*)context;
if(text_input_state->callback != NULL) {
InputTextSceneCallbackResult* result = malloc(sizeof(InputTextSceneCallbackResult));
furi_check(result != NULL);
result->user_input_length =
strnlen(text_input_state->text_input_buffer, INPUT_BUFFER_SIZE);
result->user_input = malloc(result->user_input_length + 1);
furi_check(result->user_input != NULL);
result->callback_data = text_input_state->callback_data;
strlcpy(
result->user_input,
text_input_state->text_input_buffer,
result->user_input_length + 1);
text_input_state->callback(result);
}
}
InputTextSceneState* totp_input_text_activate(InputTextSceneContext* context) {
InputTextSceneState* text_input_state = malloc(sizeof(InputTextSceneState));
furi_check(text_input_state != NULL);
text_input_state->text_input = text_input_alloc();
text_input_state->text_input_view = text_input_get_view(text_input_state->text_input);
text_input_state->callback = context->callback;
text_input_state->callback_data = context->callback_data;
text_input_set_header_text(text_input_state->text_input, context->header_text);
void totp_input_text(Gui* gui, const char* header_text, InputTextResult* result) {
ViewDispatcher* view_dispatcher = view_dispatcher_alloc();
TextInput* text_input = text_input_alloc();
InputTextContext context = {.result = result, .view_dispatcher = view_dispatcher};
text_input_set_header_text(text_input, header_text);
text_input_set_result_callback(
text_input_state->text_input,
text_input,
commit_text_input_callback,
text_input_state,
&text_input_state->text_input_buffer[0],
&context,
result->user_input,
INPUT_BUFFER_SIZE,
true);
return text_input_state;
}
void totp_input_text_render(Canvas* const canvas, InputTextSceneState* text_input_state) {
view_draw(text_input_state->text_input_view, canvas);
}
view_dispatcher_enable_queue(view_dispatcher);
view_dispatcher_add_view(view_dispatcher, 0, text_input_get_view(text_input));
bool totp_input_text_handle_event(PluginEvent* const event, InputTextSceneState* text_input_state) {
if(event->type == EventTypeKey) {
view_input(text_input_state->text_input_view, &event->input);
}
view_dispatcher_attach_to_gui(view_dispatcher, gui, ViewDispatcherTypeFullscreen);
return true;
}
view_dispatcher_set_navigation_event_callback(view_dispatcher, &back_event_callback);
view_dispatcher_set_event_callback_context(view_dispatcher, &context);
view_dispatcher_switch_to_view(view_dispatcher, 0);
void totp_input_text_free(InputTextSceneState* state) {
text_input_free(state->text_input);
free(state);
view_dispatcher_run(view_dispatcher);
view_dispatcher_remove_view(view_dispatcher, 0);
view_dispatcher_free(view_dispatcher);
text_input_free(text_input);
}

View File

@@ -1,36 +1,13 @@
#pragma once
#include <gui/gui.h>
#include <gui/view.h>
#include <gui/modules/text_input.h>
#include "../../../types/plugin_state.h"
#include "../../../types/plugin_event.h"
#define INPUT_BUFFER_SIZE (255)
typedef struct {
char* user_input;
char user_input[INPUT_BUFFER_SIZE];
size_t user_input_length;
void* callback_data;
} InputTextSceneCallbackResult;
bool success;
} InputTextResult;
typedef void (*InputTextSceneCallback)(InputTextSceneCallbackResult* result);
typedef struct {
InputTextSceneCallback callback;
char* header_text;
void* callback_data;
} InputTextSceneContext;
typedef struct {
TextInput* text_input;
View* text_input_view;
char text_input_buffer[INPUT_BUFFER_SIZE];
InputTextSceneCallback callback;
void* callback_data;
} InputTextSceneState;
InputTextSceneState* totp_input_text_activate(InputTextSceneContext* context);
void totp_input_text_render(Canvas* const canvas, InputTextSceneState* text_input_state);
bool totp_input_text_handle_event(PluginEvent* const event, InputTextSceneState* text_input_state);
void totp_input_text_free(InputTextSceneState* state);
void totp_input_text(Gui* gui, const char* header_text, InputTextResult* result);

View File

@@ -13,9 +13,9 @@
char* TOKEN_ALGO_LIST[] = {"SHA1", "SHA256", "SHA512", "Steam"};
char* TOKEN_DIGITS_TEXT_LIST[] = {"5 digits", "6 digits", "8 digits"};
TokenDigitsCount TOKEN_DIGITS_VALUE_LIST[] = {
TotpFiveDigitsCount,
TotpSixDigitsCount,
TotpEightDigitsCount};
TokenDigitsCountFive,
TokenDigitsCountSix,
TokenDigitsCountEight};
typedef enum {
TokenNameTextBox,
@@ -33,10 +33,6 @@ typedef struct {
size_t token_secret_length;
bool saved;
Control selected_control;
InputTextSceneContext* token_name_input_context;
InputTextSceneContext* token_secret_input_context;
InputTextSceneState* input_state;
bool text_input_mode;
int16_t screen_y_offset;
TokenHashAlgo algo;
uint8_t digits_count_index;
@@ -51,24 +47,6 @@ struct TotpAddContext {
enum TotpIteratorUpdateTokenResultsEx { TotpIteratorUpdateTokenResultInvalidSecret = 1 };
static void on_token_name_user_comitted(InputTextSceneCallbackResult* result) {
SceneState* scene_state = result->callback_data;
free(scene_state->token_name);
scene_state->token_name = result->user_input;
scene_state->token_name_length = result->user_input_length;
scene_state->text_input_mode = false;
free(result);
}
static void on_token_secret_user_comitted(InputTextSceneCallbackResult* result) {
SceneState* scene_state = result->callback_data;
free(scene_state->token_secret);
scene_state->token_secret = result->user_input;
scene_state->token_secret_length = result->user_input_length;
scene_state->text_input_mode = false;
free(result);
}
static void update_duration_text(SceneState* scene_state) {
furi_string_printf(scene_state->duration_text, "%d sec.", scene_state->duration);
}
@@ -95,6 +73,26 @@ static TotpIteratorUpdateTokenResult add_token_handler(TokenInfo* tokenInfo, con
return TotpIteratorUpdateTokenResultSuccess;
}
static void ask_user_input(
const PluginState* plugin_state,
const char* header,
char** user_input,
size_t* user_input_length) {
InputTextResult input_result;
if(*user_input != NULL) {
strlcpy(input_result.user_input, *user_input, INPUT_BUFFER_SIZE);
}
totp_input_text(plugin_state->gui, header, &input_result);
if(input_result.success) {
if(*user_input != NULL) {
free(*user_input);
}
*user_input = strdup(input_result.user_input);
*user_input_length = input_result.user_input_length;
}
}
void totp_scene_add_new_token_activate(PluginState* plugin_state) {
SceneState* scene_state = malloc(sizeof(SceneState));
furi_check(scene_state != NULL);
@@ -104,34 +102,17 @@ void totp_scene_add_new_token_activate(PluginState* plugin_state) {
scene_state->token_secret = "Secret";
scene_state->token_secret_length = strlen(scene_state->token_secret);
scene_state->token_name_input_context = malloc(sizeof(InputTextSceneContext));
furi_check(scene_state->token_name_input_context != NULL);
scene_state->token_name_input_context->header_text = "Enter token name";
scene_state->token_name_input_context->callback_data = scene_state;
scene_state->token_name_input_context->callback = on_token_name_user_comitted;
scene_state->token_secret_input_context = malloc(sizeof(InputTextSceneContext));
furi_check(scene_state->token_secret_input_context != NULL);
scene_state->token_secret_input_context->header_text = "Enter token secret";
scene_state->token_secret_input_context->callback_data = scene_state;
scene_state->token_secret_input_context->callback = on_token_secret_user_comitted;
scene_state->screen_y_offset = 0;
scene_state->digits_count_index = 1;
scene_state->input_state = NULL;
scene_state->duration = TOTP_TOKEN_DURATION_DEFAULT;
scene_state->duration = TokenDurationDefault;
scene_state->duration_text = furi_string_alloc();
update_duration_text(scene_state);
}
void totp_scene_add_new_token_render(Canvas* const canvas, PluginState* plugin_state) {
SceneState* scene_state = plugin_state->current_scene_state;
if(scene_state->text_input_mode) {
totp_input_text_render(canvas, scene_state->input_state);
return;
}
void totp_scene_add_new_token_render(Canvas* const canvas, const PluginState* plugin_state) {
const SceneState* scene_state = plugin_state->current_scene_state;
ui_control_text_box_render(
canvas,
@@ -195,31 +176,15 @@ void update_screen_y_offset(SceneState* scene_state) {
}
}
bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState* plugin_state) {
bool totp_scene_add_new_token_handle_event(
const PluginEvent* const event,
PluginState* plugin_state) {
if(event->type != EventTypeKey) {
return true;
}
SceneState* scene_state = plugin_state->current_scene_state;
if(event->input.type == InputTypeLong && event->input.key == InputKeyBack) {
if(scene_state->text_input_mode) {
scene_state->text_input_mode = false;
} else {
return false;
}
}
if(scene_state->text_input_mode) {
if(event->input.type == InputTypeShort && event->input.key == InputKeyBack) {
PluginEvent long_back_cb_evt = {
.type = event->type, .input.key = InputKeyBack, .input.type = InputTypeLong};
return totp_input_text_handle_event(&long_back_cb_evt, scene_state->input_state);
}
return totp_input_text_handle_event(event, scene_state->input_state);
}
if(event->input.type == InputTypePress) {
switch(event->input.key) {
case InputKeyUp:
@@ -243,7 +208,11 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState
case InputKeyRight:
if(scene_state->selected_control == TokenAlgoSelect) {
totp_roll_value_uint8_t(
&scene_state->algo, 1, SHA1, STEAM, RollOverflowBehaviorRoll);
&scene_state->algo,
1,
TokenHashAlgoSha1,
TokenHashAlgoSteam,
RollOverflowBehaviorRoll);
} else if(scene_state->selected_control == TokenLengthSelect) {
totp_roll_value_uint8_t(
&scene_state->digits_count_index, 1, 0, 2, RollOverflowBehaviorRoll);
@@ -256,7 +225,11 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState
case InputKeyLeft:
if(scene_state->selected_control == TokenAlgoSelect) {
totp_roll_value_uint8_t(
&scene_state->algo, -1, SHA1, STEAM, RollOverflowBehaviorRoll);
&scene_state->algo,
-1,
TokenHashAlgoSha1,
TokenHashAlgoSteam,
RollOverflowBehaviorRoll);
} else if(scene_state->selected_control == TokenLengthSelect) {
totp_roll_value_uint8_t(
&scene_state->digits_count_index, -1, 0, 2, RollOverflowBehaviorRoll);
@@ -277,22 +250,18 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState
} else if(event->input.type == InputTypeRelease && event->input.key == InputKeyOk) {
switch(scene_state->selected_control) {
case TokenNameTextBox:
if(scene_state->input_state != NULL) {
totp_input_text_free(scene_state->input_state);
}
scene_state->input_state =
totp_input_text_activate(scene_state->token_name_input_context);
scene_state->text_input_mode = true;
ask_user_input(
plugin_state,
"Token name",
&scene_state->token_name,
&scene_state->token_name_length);
break;
case TokenSecretTextBox:
if(scene_state->input_state != NULL) {
totp_input_text_free(scene_state->input_state);
}
scene_state->input_state =
totp_input_text_activate(scene_state->token_secret_input_context);
scene_state->text_input_mode = true;
ask_user_input(
plugin_state,
"Token secret",
&scene_state->token_secret,
&scene_state->token_secret_length);
break;
case TokenAlgoSelect:
break;
@@ -344,18 +313,8 @@ void totp_scene_add_new_token_deactivate(PluginState* plugin_state) {
free(scene_state->token_name);
free(scene_state->token_secret);
free(scene_state->token_name_input_context->header_text);
free(scene_state->token_name_input_context);
free(scene_state->token_secret_input_context->header_text);
free(scene_state->token_secret_input_context);
furi_string_free(scene_state->duration_text);
if(scene_state->input_state != NULL) {
totp_input_text_free(scene_state->input_state);
}
free(plugin_state->current_scene_state);
plugin_state->current_scene_state = NULL;
}

View File

@@ -5,6 +5,8 @@
#include "../../../types/plugin_event.h"
void totp_scene_add_new_token_activate(PluginState* plugin_state);
void totp_scene_add_new_token_render(Canvas* const canvas, PluginState* plugin_state);
bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState* plugin_state);
void totp_scene_add_new_token_render(Canvas* const canvas, const PluginState* plugin_state);
bool totp_scene_add_new_token_handle_event(
const PluginEvent* const event,
PluginState* plugin_state);
void totp_scene_add_new_token_deactivate(PluginState* plugin_state);

View File

@@ -2,6 +2,8 @@
#include <math.h>
#include <totp_icons.h>
#include <assets_icons.h>
#include <available_fonts.h>
#include "../../canvas_extensions.h"
#include "../../ui_controls.h"
#include "../../common_dialogs.h"
#include "../../scene_director.h"
@@ -15,18 +17,20 @@
#include "../../../workers/bt_type_code/bt_type_code.h"
#endif
char* YES_NO_LIST[] = {"NO", "YES"};
char* ON_OFF_LIST[] = {"OFF", "ON"};
static const char* YES_NO_LIST[] = {"NO", "YES"};
static const char* ON_OFF_LIST[] = {"OFF", "ON"};
static const char* FONT_TEST_STR = "0123BCD";
static const uint8_t FONT_TEST_STR_LENGTH = 7;
typedef enum {
HoursInput,
MinutesInput,
Sound,
Vibro,
FontSelector,
BadUsb,
FontSelect,
SoundSwitch,
VibroSwitch,
BadUsbSwitch,
#ifdef TOTP_BADBT_TYPE_ENABLED
BadBt,
BadBtSwitch,
#endif
ConfirmButton
} Control;
@@ -36,13 +40,13 @@ typedef struct {
uint8_t tz_offset_minutes;
bool notification_sound;
bool notification_vibro;
uint8_t selected_font;
bool badusb_enabled;
#ifdef TOTP_BADBT_TYPE_ENABLED
bool badbt_enabled;
#endif
uint8_t y_offset;
Control selected_control;
uint8_t active_font;
} SceneState;
void totp_scene_app_settings_activate(PluginState* plugin_state) {
@@ -57,10 +61,10 @@ void totp_scene_app_settings_activate(PluginState* plugin_state) {
scene_state->notification_sound = plugin_state->notification_method & NotificationMethodSound;
scene_state->notification_vibro = plugin_state->notification_method & NotificationMethodVibro;
scene_state->badusb_enabled = plugin_state->automation_method & AutomationMethodBadUsb;
scene_state->selected_font = plugin_state->selected_font;
#ifdef TOTP_BADBT_TYPE_ENABLED
scene_state->badbt_enabled = plugin_state->automation_method & AutomationMethodBadBt;
#endif
scene_state->active_font = plugin_state->active_font_index;
}
static void two_digit_to_str(int8_t num, char* str) {
@@ -114,75 +118,87 @@ void totp_scene_app_settings_render(Canvas* const canvas, const PluginState* plu
&I_totp_arrow_bottom_10x5);
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(
canvas, 0, 64 - scene_state->y_offset, AlignLeft, AlignTop, "Notifications / UI");
canvas_draw_str_aligned(canvas, 0, 64 - scene_state->y_offset, AlignLeft, AlignTop, "Font");
canvas_set_font(canvas, FontSecondary);
canvas_draw_str_aligned(canvas, 0, 78 - scene_state->y_offset, AlignLeft, AlignTop, "Sound:");
const FONT_INFO* const font = available_fonts[scene_state->active_font];
ui_control_select_render(
canvas,
36,
71 - scene_state->y_offset,
SCREEN_WIDTH - 36,
YES_NO_LIST[scene_state->notification_sound],
scene_state->selected_control == Sound);
0,
74 - scene_state->y_offset,
SCREEN_WIDTH,
font->name,
scene_state->selected_control == FontSelect);
canvas_draw_str_aligned(canvas, 0, 94 - scene_state->y_offset, AlignLeft, AlignTop, "Vibro:");
ui_control_select_render(
canvas,
36,
87 - scene_state->y_offset,
SCREEN_WIDTH - 36,
YES_NO_LIST[scene_state->notification_vibro],
scene_state->selected_control == Vibro);
two_digit_to_str(scene_state->selected_font, &tmp_str[0]);
canvas_draw_str_aligned(
canvas, 0, 110 - scene_state->y_offset, AlignLeft, AlignTop, "UI Font:");
ui_control_select_render(
canvas,
36,
103 - scene_state->y_offset,
SCREEN_WIDTH - 36,
&tmp_str[0],
scene_state->selected_control == FontSelector);
uint8_t font_x_offset =
SCREEN_WIDTH_CENTER -
(((font->charInfo[0].width + font->spacePixels) * FONT_TEST_STR_LENGTH) >> 1);
uint8_t font_y_offset = 108 - scene_state->y_offset - (font->height >> 1);
canvas_draw_str_ex(
canvas, font_x_offset, font_y_offset, FONT_TEST_STR, FONT_TEST_STR_LENGTH, font);
canvas_draw_icon(
canvas, SCREEN_WIDTH_CENTER - 5, 123 - scene_state->y_offset, &I_totp_arrow_bottom_10x5);
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(
canvas, 0, 128 - scene_state->y_offset, AlignLeft, AlignTop, "Automation");
canvas, 0, 128 - scene_state->y_offset, AlignLeft, AlignTop, "Notifications");
canvas_set_font(canvas, FontSecondary);
canvas_draw_str_aligned(
canvas, 0, 145 - scene_state->y_offset, AlignLeft, AlignTop, "BadUSB:");
canvas_draw_str_aligned(canvas, 0, 145 - scene_state->y_offset, AlignLeft, AlignTop, "Sound:");
ui_control_select_render(
canvas,
36,
138 - scene_state->y_offset,
SCREEN_WIDTH - 36,
ON_OFF_LIST[scene_state->badusb_enabled],
scene_state->selected_control == BadUsb);
YES_NO_LIST[scene_state->notification_sound],
scene_state->selected_control == SoundSwitch);
#ifdef TOTP_BADBT_TYPE_ENABLED
canvas_draw_str_aligned(canvas, 0, 163 - scene_state->y_offset, AlignLeft, AlignTop, "BadBT:");
canvas_draw_str_aligned(canvas, 0, 163 - scene_state->y_offset, AlignLeft, AlignTop, "Vibro:");
ui_control_select_render(
canvas,
36,
156 - scene_state->y_offset,
SCREEN_WIDTH - 36,
YES_NO_LIST[scene_state->notification_vibro],
scene_state->selected_control == VibroSwitch);
canvas_draw_icon(
canvas, SCREEN_WIDTH_CENTER - 5, 187 - scene_state->y_offset, &I_totp_arrow_bottom_10x5);
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(
canvas, 0, 192 - scene_state->y_offset, AlignLeft, AlignTop, "Automation");
canvas_set_font(canvas, FontSecondary);
canvas_draw_str_aligned(
canvas, 0, 209 - scene_state->y_offset, AlignLeft, AlignTop, "BadUSB:");
ui_control_select_render(
canvas,
36,
202 - scene_state->y_offset,
SCREEN_WIDTH - 36,
ON_OFF_LIST[scene_state->badusb_enabled],
scene_state->selected_control == BadUsbSwitch);
#ifdef TOTP_BADBT_TYPE_ENABLED
canvas_draw_str_aligned(canvas, 0, 227 - scene_state->y_offset, AlignLeft, AlignTop, "BadBT:");
ui_control_select_render(
canvas,
36,
220 - scene_state->y_offset,
SCREEN_WIDTH - 36,
ON_OFF_LIST[scene_state->badbt_enabled],
scene_state->selected_control == BadBt);
scene_state->selected_control == BadBtSwitch);
#endif
ui_control_button_render(
canvas,
SCREEN_WIDTH_CENTER - 24,
#ifdef TOTP_BADBT_TYPE_ENABLED
178 - scene_state->y_offset,
242 - scene_state->y_offset,
#else
165 - scene_state->y_offset,
229 - scene_state->y_offset,
#endif
48,
13,
@@ -207,10 +223,12 @@ bool totp_scene_app_settings_handle_event(
HoursInput,
ConfirmButton,
RollOverflowBehaviorStop);
if(scene_state->selected_control > FontSelector) {
scene_state->y_offset = 128;
if(scene_state->selected_control > VibroSwitch) {
scene_state->y_offset = SCREEN_HEIGHT * 3;
} else if(scene_state->selected_control > FontSelect) {
scene_state->y_offset = SCREEN_HEIGHT * 2;
} else if(scene_state->selected_control > MinutesInput) {
scene_state->y_offset = 64;
scene_state->y_offset = SCREEN_HEIGHT;
} else {
scene_state->y_offset = 0;
}
@@ -222,10 +240,12 @@ bool totp_scene_app_settings_handle_event(
HoursInput,
ConfirmButton,
RollOverflowBehaviorStop);
if(scene_state->selected_control > FontSelector) {
scene_state->y_offset = 128;
if(scene_state->selected_control > VibroSwitch) {
scene_state->y_offset = SCREEN_HEIGHT * 3;
} else if(scene_state->selected_control > FontSelect) {
scene_state->y_offset = SCREEN_HEIGHT * 2;
} else if(scene_state->selected_control > MinutesInput) {
scene_state->y_offset = 64;
scene_state->y_offset = SCREEN_HEIGHT;
} else {
scene_state->y_offset = 0;
}
@@ -237,22 +257,25 @@ bool totp_scene_app_settings_handle_event(
} else if(scene_state->selected_control == MinutesInput) {
totp_roll_value_uint8_t(
&scene_state->tz_offset_minutes, 15, 0, 45, RollOverflowBehaviorRoll);
} else if(scene_state->selected_control == Sound) {
} else if(scene_state->selected_control == FontSelect) {
totp_roll_value_uint8_t(
&scene_state->active_font,
1,
0,
AVAILABLE_FONTS_COUNT - 1,
RollOverflowBehaviorRoll);
} else if(scene_state->selected_control == SoundSwitch) {
scene_state->notification_sound = !scene_state->notification_sound;
} else if(scene_state->selected_control == Vibro) {
} else if(scene_state->selected_control == VibroSwitch) {
scene_state->notification_vibro = !scene_state->notification_vibro;
} else if(scene_state->selected_control == BadUsb) {
} else if(scene_state->selected_control == BadUsbSwitch) {
scene_state->badusb_enabled = !scene_state->badusb_enabled;
}
#ifdef TOTP_BADBT_TYPE_ENABLED
else if(scene_state->selected_control == BadBt) {
else if(scene_state->selected_control == BadBtSwitch) {
scene_state->badbt_enabled = !scene_state->badbt_enabled;
}
#endif
else if(scene_state->selected_control == FontSelector) {
totp_roll_value_uint8_t(
&scene_state->selected_font, 1, 0, MAX_CUSTOM_FONTS, RollOverflowBehaviorStop);
}
break;
case InputKeyLeft:
if(scene_state->selected_control == HoursInput) {
@@ -261,22 +284,25 @@ bool totp_scene_app_settings_handle_event(
} else if(scene_state->selected_control == MinutesInput) {
totp_roll_value_uint8_t(
&scene_state->tz_offset_minutes, -15, 0, 45, RollOverflowBehaviorRoll);
} else if(scene_state->selected_control == Sound) {
} else if(scene_state->selected_control == FontSelect) {
totp_roll_value_uint8_t(
&scene_state->active_font,
-1,
0,
AVAILABLE_FONTS_COUNT - 1,
RollOverflowBehaviorRoll);
} else if(scene_state->selected_control == SoundSwitch) {
scene_state->notification_sound = !scene_state->notification_sound;
} else if(scene_state->selected_control == Vibro) {
} else if(scene_state->selected_control == VibroSwitch) {
scene_state->notification_vibro = !scene_state->notification_vibro;
} else if(scene_state->selected_control == BadUsb) {
} else if(scene_state->selected_control == BadUsbSwitch) {
scene_state->badusb_enabled = !scene_state->badusb_enabled;
}
#ifdef TOTP_BADBT_TYPE_ENABLED
else if(scene_state->selected_control == BadBt) {
else if(scene_state->selected_control == BadBtSwitch) {
scene_state->badbt_enabled = !scene_state->badbt_enabled;
}
#endif
else if(scene_state->selected_control == FontSelector) {
totp_roll_value_uint8_t(
&scene_state->selected_font, -1, 0, MAX_CUSTOM_FONTS, RollOverflowBehaviorStop);
}
break;
case InputKeyOk:
break;
@@ -303,7 +329,8 @@ bool totp_scene_app_settings_handle_event(
plugin_state->automation_method |= scene_state->badbt_enabled ? AutomationMethodBadBt :
AutomationMethodNone;
#endif
plugin_state->selected_font = scene_state->selected_font;
plugin_state->active_font_index = scene_state->active_font;
if(!totp_config_file_update_user_settings(plugin_state)) {
totp_dialogs_config_updating_error(plugin_state);

View File

@@ -4,7 +4,9 @@
#include <totp_icons.h>
#include <assets_icons.h>
#include <roll_value.h>
#include <available_fonts.h>
#include "totp_scene_generate_token.h"
#include "../../canvas_extensions.h"
#include "../../../types/token_info.h"
#include "../../../types/common.h"
#include "../../constants.h"
@@ -17,7 +19,6 @@
#ifdef TOTP_BADBT_TYPE_ENABLED
#include "../../../workers/bt_type_code/bt_type_code.h"
#endif
#include "../../fonts/active_font.h"
#define PROGRESS_BAR_MARGIN (3)
#define PROGRESS_BAR_HEIGHT (4)
@@ -27,18 +28,18 @@ typedef struct {
uint8_t progress_bar_width;
uint8_t code_total_length;
uint8_t code_offset_x;
uint8_t code_offset_x_inc;
uint8_t code_offset_y;
} UiPrecalculatedDimensions;
typedef struct {
char last_code[TOTP_TOKEN_DIGITS_MAX_COUNT + 1];
char last_code[TokenDigitsCountMax + 1];
TotpUsbTypeCodeWorkerContext* usb_type_code_worker_context;
NotificationMessage const** notification_sequence_new_token;
NotificationMessage const** notification_sequence_automation;
FuriMutex* last_code_update_sync;
TotpGenerateCodeWorkerContext* generate_code_worker_context;
UiPrecalculatedDimensions ui_precalculated_dimensions;
const FONT_INFO* active_font;
} SceneState;
static const NotificationSequence*
@@ -142,60 +143,14 @@ static void draw_totp_code(Canvas* const canvas, const PluginState* const plugin
const TokenInfoIteratorContext* iterator_context =
totp_config_get_token_iterator_context(plugin_state);
uint8_t code_length = totp_token_info_iterator_get_current_token(iterator_context)->digits;
uint8_t offset_x = scene_state->ui_precalculated_dimensions.code_offset_x;
const FONT_INFO* current_font;
switch(plugin_state->selected_font) {
case 0:
current_font = &modeNine_15ptFontInfo;
break;
case 1:
current_font = &redHatMono_16ptFontInfo;
break;
case 2:
current_font = &bedstead_17ptFontInfo;
break;
case 3:
current_font = &zector_18ptFontInfo;
break;
case 4:
current_font = &_712Serif_24ptFontInfo;
break;
case 5:
current_font = &graph35pix_12ptFontInfo;
break;
case 6:
current_font = &karmaFuture_14ptFontInfo;
break;
case 7:
current_font = &funclimbingDemo_18ptFontInfo;
break;
case 8:
current_font = &dPComic_18ptFontInfo;
break;
case 9:
current_font = &pixelFlag_18ptFontInfo;
break;
default:
current_font = &modeNine_15ptFontInfo;
break;
}
uint8_t char_width = current_font->charInfo[0].width;
uint8_t offset_x_inc = scene_state->ui_precalculated_dimensions.code_offset_x_inc;
for(uint8_t i = 0; i < code_length; i++) {
char ch = scene_state->last_code[i];
if(ch >= current_font->startChar && ch <= current_font->endChar) {
uint8_t char_index = ch - current_font->startChar;
canvas_draw_xbm(
canvas,
offset_x,
scene_state->ui_precalculated_dimensions.code_offset_y,
char_width,
current_font->height,
&current_font->data[current_font->charInfo[char_index].offset]);
}
offset_x += offset_x_inc;
}
canvas_draw_str_ex(
canvas,
scene_state->ui_precalculated_dimensions.code_offset_x,
scene_state->ui_precalculated_dimensions.code_offset_y,
scene_state->last_code,
code_length,
scene_state->active_font);
}
static void on_new_token_code_generated(bool time_left, void* context) {
@@ -208,53 +163,15 @@ static void on_new_token_code_generated(bool time_left, void* context) {
SceneState* scene_state = plugin_state->current_scene_state;
const TokenInfo* current_token = totp_token_info_iterator_get_current_token(iterator_context);
const FONT_INFO* const font = scene_state->active_font;
const FONT_INFO* current_font;
switch(plugin_state->selected_font) {
case 0:
current_font = &modeNine_15ptFontInfo;
break;
case 1:
current_font = &redHatMono_16ptFontInfo;
break;
case 2:
current_font = &bedstead_17ptFontInfo;
break;
case 3:
current_font = &zector_18ptFontInfo;
break;
case 4:
current_font = &_712Serif_24ptFontInfo;
break;
case 5:
current_font = &graph35pix_12ptFontInfo;
break;
case 6:
current_font = &karmaFuture_14ptFontInfo;
break;
case 7:
current_font = &funclimbingDemo_18ptFontInfo;
break;
case 8:
current_font = &dPComic_18ptFontInfo;
break;
case 9:
current_font = &pixelFlag_18ptFontInfo;
break;
default:
current_font = &modeNine_15ptFontInfo;
break;
}
uint8_t char_width = current_font->charInfo[0].width;
uint8_t char_width = font->charInfo[0].width;
scene_state->ui_precalculated_dimensions.code_total_length =
current_token->digits * (char_width + current_font->spacePixels);
current_token->digits * (char_width + font->spacePixels);
scene_state->ui_precalculated_dimensions.code_offset_x =
(SCREEN_WIDTH - scene_state->ui_precalculated_dimensions.code_total_length) >> 1;
scene_state->ui_precalculated_dimensions.code_offset_x_inc =
char_width + current_font->spacePixels;
scene_state->ui_precalculated_dimensions.code_offset_y =
SCREEN_HEIGHT_CENTER - (current_font->height >> 1);
SCREEN_HEIGHT_CENTER - (font->height >> 1);
if(time_left) {
notification_message(
@@ -284,11 +201,11 @@ void totp_scene_generate_token_activate(PluginState* plugin_state) {
scene_state->last_code_update_sync = furi_mutex_alloc(FuriMutexTypeNormal);
if(plugin_state->automation_method & AutomationMethodBadUsb) {
scene_state->usb_type_code_worker_context = totp_usb_type_code_worker_start(
scene_state->last_code,
TOTP_TOKEN_DIGITS_MAX_COUNT + 1,
scene_state->last_code_update_sync);
scene_state->last_code, TokenDigitsCountMax + 1, scene_state->last_code_update_sync);
}
scene_state->active_font = available_fonts[plugin_state->active_font_index];
#ifdef TOTP_BADBT_TYPE_ENABLED
if(plugin_state->automation_method & AutomationMethodBadBt) {
@@ -298,7 +215,7 @@ void totp_scene_generate_token_activate(PluginState* plugin_state) {
totp_bt_type_code_worker_start(
plugin_state->bt_type_code_worker_context,
scene_state->last_code,
TOTP_TOKEN_DIGITS_MAX_COUNT + 1,
TokenDigitsCountMax + 1,
scene_state->last_code_update_sync);
}
#endif