mirror of
https://github.com/i12bp8/TagTinker.git
synced 2026-08-25 03:50:02 +00:00
Refine startup warning UI
This commit is contained in:
@@ -23,8 +23,6 @@ static void about_draw_cb(Canvas* canvas, void* _model) {
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
canvas_draw_str_aligned(canvas, 64, 24, AlignCenter, AlignTop, "Ported by I12BP8");
|
||||
canvas_draw_str_aligned(canvas, 64, 34, AlignCenter, AlignTop, "Research by furrtek");
|
||||
canvas_draw_str_aligned(canvas, 64, 44, AlignCenter, AlignTop, "Owned ESLs only");
|
||||
canvas_draw_str_aligned(canvas, 64, 54, AlignCenter, AlignTop, "No store use");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,42 +3,147 @@
|
||||
*/
|
||||
|
||||
#include "../tagtinker_app.h"
|
||||
#include <gui/elements.h>
|
||||
|
||||
enum {
|
||||
TagTinkerStartupWarningContinue,
|
||||
};
|
||||
|
||||
static const char* startup_warning_text =
|
||||
"\ec\e#TagTinker - Research Tool\n"
|
||||
"\n"
|
||||
"This is an educational research tool for infrared electronic shelf label "
|
||||
"(ESL) protocols.\n"
|
||||
"It implements publicly documented signaling for tags commonly used in "
|
||||
"retail (often referred to as Pricer-style ESLs).\n"
|
||||
"Use ONLY on tags you personally own or have explicit permission to test.\n"
|
||||
"Using this tool on retail store systems without authorization may violate "
|
||||
"laws on fraud or interference with business operations. You are solely "
|
||||
"responsible for your actions. Misuse is not endorsed.\n"
|
||||
"\n"
|
||||
"\ecPress OK to continue.";
|
||||
typedef struct {
|
||||
uint8_t page;
|
||||
} WarningViewModel;
|
||||
|
||||
static void startup_warning_button_cb(GuiButtonType result, InputType type, void* context) {
|
||||
if(type != InputTypeShort || result != GuiButtonTypeCenter) return;
|
||||
typedef struct {
|
||||
const char* title;
|
||||
const char* lines[2];
|
||||
} WarningPage;
|
||||
|
||||
static const WarningPage startup_warning_pages[] = {
|
||||
{
|
||||
.title = "RESEARCH TOOL:",
|
||||
.lines =
|
||||
{
|
||||
"Educational tool for",
|
||||
"infrared ESL study.",
|
||||
},
|
||||
},
|
||||
{
|
||||
.title = "PERMISSION:",
|
||||
.lines =
|
||||
{
|
||||
"Use only on tags",
|
||||
"you own or may test.",
|
||||
},
|
||||
},
|
||||
{
|
||||
.title = "CAUTION:",
|
||||
.lines =
|
||||
{
|
||||
"Unauthorized use",
|
||||
"may be illegal.",
|
||||
},
|
||||
},
|
||||
{
|
||||
.title = "RESPONSIBILITY:",
|
||||
.lines =
|
||||
{
|
||||
"You are responsible",
|
||||
"for your actions.",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const uint8_t startup_warning_page_count =
|
||||
sizeof(startup_warning_pages) / sizeof(startup_warning_pages[0]);
|
||||
|
||||
static bool warning_is_unlocked(const WarningViewModel* model) {
|
||||
return model->page >= (startup_warning_page_count - 1);
|
||||
}
|
||||
|
||||
static void warning_draw_cb(Canvas* canvas, void* _model) {
|
||||
WarningViewModel* model = _model;
|
||||
bool unlocked = warning_is_unlocked(model);
|
||||
const WarningPage* page = &startup_warning_pages[model->page];
|
||||
|
||||
canvas_clear(canvas);
|
||||
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str_aligned(canvas, 64, 13, AlignCenter, AlignCenter, page->title);
|
||||
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
canvas_draw_str_aligned(canvas, 64, 29, AlignCenter, AlignCenter, page->lines[0]);
|
||||
canvas_draw_str_aligned(canvas, 64, 39, AlignCenter, AlignCenter, page->lines[1]);
|
||||
|
||||
if(model->page > 0) {
|
||||
elements_button_left(canvas, "Prev");
|
||||
}
|
||||
|
||||
elements_button_right(canvas, unlocked ? "OK" : "Next");
|
||||
}
|
||||
|
||||
static bool warning_input_cb(InputEvent* event, void* context) {
|
||||
TagTinkerApp* app = context;
|
||||
view_dispatcher_send_custom_event(
|
||||
app->view_dispatcher, TagTinkerStartupWarningContinue);
|
||||
bool handled = false;
|
||||
|
||||
if(event->type != InputTypeShort && event->type != InputTypeRepeat) {
|
||||
return false;
|
||||
}
|
||||
|
||||
WarningViewModel* model = view_get_model(app->warning_view);
|
||||
|
||||
switch(event->key) {
|
||||
case InputKeyDown:
|
||||
case InputKeyRight:
|
||||
if(model->page + 1 < startup_warning_page_count) {
|
||||
model->page++;
|
||||
handled = true;
|
||||
}
|
||||
break;
|
||||
case InputKeyUp:
|
||||
case InputKeyLeft:
|
||||
if(model->page > 0) {
|
||||
model->page--;
|
||||
handled = true;
|
||||
}
|
||||
break;
|
||||
case InputKeyOk:
|
||||
if(event->type == InputTypeShort) {
|
||||
if(warning_is_unlocked(model)) {
|
||||
handled = true;
|
||||
view_commit_model(app->warning_view, false);
|
||||
view_dispatcher_send_custom_event(
|
||||
app->view_dispatcher, TagTinkerStartupWarningContinue);
|
||||
return true;
|
||||
} else if(model->page + 1 < startup_warning_page_count) {
|
||||
model->page++;
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
view_commit_model(app->warning_view, handled);
|
||||
return handled;
|
||||
}
|
||||
|
||||
void tagtinker_scene_warning_on_enter(void* ctx) {
|
||||
TagTinkerApp* app = ctx;
|
||||
|
||||
widget_reset(app->widget);
|
||||
widget_add_text_scroll_element(app->widget, 0, 0, 128, 52, startup_warning_text);
|
||||
widget_add_button_element(
|
||||
app->widget, GuiButtonTypeCenter, "OK", startup_warning_button_cb, app);
|
||||
if(!app->warning_view_allocated) {
|
||||
view_allocate_model(app->warning_view, ViewModelTypeLockFree, sizeof(WarningViewModel));
|
||||
view_set_context(app->warning_view, app);
|
||||
view_set_draw_callback(app->warning_view, warning_draw_cb);
|
||||
view_set_input_callback(app->warning_view, warning_input_cb);
|
||||
app->warning_view_allocated = true;
|
||||
}
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, TagTinkerViewWidget);
|
||||
WarningViewModel* model = view_get_model(app->warning_view);
|
||||
model->page = 0;
|
||||
view_commit_model(app->warning_view, true);
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, TagTinkerViewWarning);
|
||||
}
|
||||
|
||||
bool tagtinker_scene_warning_on_event(void* ctx, SceneManagerEvent event) {
|
||||
@@ -55,6 +160,5 @@ bool tagtinker_scene_warning_on_event(void* ctx, SceneManagerEvent event) {
|
||||
}
|
||||
|
||||
void tagtinker_scene_warning_on_exit(void* ctx) {
|
||||
TagTinkerApp* app = ctx;
|
||||
widget_reset(app->widget);
|
||||
UNUSED(ctx);
|
||||
}
|
||||
|
||||
@@ -209,6 +209,10 @@ static TagTinkerApp* app_alloc(void) {
|
||||
view_dispatcher_add_view(
|
||||
app->view_dispatcher, TagTinkerViewNumlock, numlock_input_get_view(app->numlock));
|
||||
|
||||
app->warning_view = view_alloc();
|
||||
view_dispatcher_add_view(
|
||||
app->view_dispatcher, TagTinkerViewWarning, app->warning_view);
|
||||
|
||||
app->transmit_view = view_alloc();
|
||||
view_dispatcher_add_view(
|
||||
app->view_dispatcher, TagTinkerViewTransmit, app->transmit_view);
|
||||
@@ -246,6 +250,7 @@ static void app_free(TagTinkerApp* app) {
|
||||
view_dispatcher_remove_view(app->view_dispatcher, TagTinkerViewPopup);
|
||||
view_dispatcher_remove_view(app->view_dispatcher, TagTinkerViewWidget);
|
||||
view_dispatcher_remove_view(app->view_dispatcher, TagTinkerViewNumlock);
|
||||
view_dispatcher_remove_view(app->view_dispatcher, TagTinkerViewWarning);
|
||||
view_dispatcher_remove_view(app->view_dispatcher, TagTinkerViewTransmit);
|
||||
view_dispatcher_remove_view(app->view_dispatcher, TagTinkerViewAbout);
|
||||
|
||||
@@ -263,6 +268,7 @@ static void app_free(TagTinkerApp* app) {
|
||||
furi_record_close(RECORD_NOTIFICATION);
|
||||
furi_record_close(RECORD_DIALOGS);
|
||||
|
||||
view_free(app->warning_view);
|
||||
view_free(app->transmit_view);
|
||||
view_free(app->about_view);
|
||||
furi_thread_free(app->tx_thread);
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
|
||||
/* Views */
|
||||
typedef enum {
|
||||
TagTinkerViewWarning,
|
||||
TagTinkerViewSubmenu,
|
||||
TagTinkerViewVarItemList,
|
||||
TagTinkerViewTextInput,
|
||||
@@ -69,9 +70,11 @@ struct TagTinkerApp {
|
||||
Popup* popup;
|
||||
Widget* widget;
|
||||
NumlockInput* numlock;
|
||||
View* warning_view;
|
||||
View* target_actions_view;
|
||||
View* transmit_view;
|
||||
View* about_view;
|
||||
bool warning_view_allocated;
|
||||
bool transmit_view_allocated;
|
||||
bool about_view_allocated;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user