Skip to content

Commit

Permalink
revamped UI, settings, icons
Browse files Browse the repository at this point in the history
  • Loading branch information
rdefeo committed Mar 12, 2024
1 parent 16c4ea1 commit a7c4386
Show file tree
Hide file tree
Showing 23 changed files with 1,207 additions and 81 deletions.
20 changes: 10 additions & 10 deletions actions/action_rfid.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,18 @@ void action_rfid_tx(void* context, FuriString* action_path, FuriString* error) {
size_t data_size = protocol_dict_get_max_data_size(dict);
uint8_t* data = malloc(data_size);

FURI_LOG_I(TAG, "Max dict data size is %d", data_size);
// FURI_LOG_I(TAG, "Max dict data size is %d", data_size);
bool successful_read = false;
do {
if(!flipper_format_file_open_existing(fff_data_file, furi_string_get_cstr(file_name))) {
ACTION_SET_ERROR("RFID: Error opening %s", furi_string_get_cstr(file_name));
break;
}
FURI_LOG_I(TAG, "Opened file");
if(!flipper_format_read_header(fff_data_file, temp_str, &temp_data32)) {
ACTION_SET_ERROR("RFID: Missing or incorrect header");
break;
}
FURI_LOG_I(TAG, "Read file headers");
// FURI_LOG_I(TAG, "Read file headers");
// TODO: add better header checks here...
if(!strcmp(furi_string_get_cstr(temp_str), "Flipper RFID key")) {
} else {
Expand All @@ -67,9 +66,9 @@ void action_rfid_tx(void* context, FuriString* action_path, FuriString* error) {

// read and check data field
size_t required_size = protocol_dict_get_data_size(dict, protocol);
FURI_LOG_I(TAG, "Protocol req data size is %d", required_size);
// FURI_LOG_I(TAG, "Protocol req data size is %d", required_size);
if(!flipper_format_read_hex(fff_data_file, "Data", data, required_size)) {
FURI_LOG_E(TAG, "Error reading data");
FURI_LOG_E(TAG, "RFID: Error reading data");
ACTION_SET_ERROR("RFID: Error reading data");
break;
}
Expand All @@ -86,7 +85,7 @@ void action_rfid_tx(void* context, FuriString* action_path, FuriString* error) {

protocol_dict_set_data(dict, protocol, data, data_size);
successful_read = true;
FURI_LOG_I(TAG, "protocol dict setup complete!");
// FURI_LOG_I(TAG, "protocol dict setup complete!");
} while(false);

if(successful_read) {
Expand All @@ -95,14 +94,15 @@ void action_rfid_tx(void* context, FuriString* action_path, FuriString* error) {
lfrfid_worker_start_thread(worker);
lfrfid_worker_emulate_start(worker, protocol);

FURI_LOG_I(TAG, "Emulating RFID...");
int16_t time_ms = 3000;
int16_t interval_ms = 200;
int16_t time_ms = app->settings.rfid_duration;
FURI_LOG_I(
TAG, "RFID: Emulating RFID (%s) for %d ms", furi_string_get_cstr(file_name), time_ms);
int16_t interval_ms = 100;
while(time_ms > 0) {
furi_delay_ms(interval_ms);
time_ms -= interval_ms;
}
FURI_LOG_I(TAG, "Emulation stopped");
FURI_LOG_I(TAG, "RFID: Emulation stopped");

lfrfid_worker_stop(worker);
lfrfid_worker_stop_thread(worker);
Expand Down
Binary file added images/ArrowDown_8x4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/ArrowUp_8x4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/Directory_10px.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/IR_10px.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/NFC_10px.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/Playlist_10px.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/RFID_10px.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/Settings_10px.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/SubGHz_10px.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 17 additions & 11 deletions item.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,34 +78,40 @@ ItemsView* item_get_items_view_from_path(void* context, FuriString* input_path)
furi_string_free(filename_tmp);
furi_string_free(path);

// DEBUG: Now print our array in original order
FileArray_it_t iter;
for(FileArray_it(iter, flist); !FileArray_end_p(iter); FileArray_next(iter)) {
const char* f = furi_string_get_cstr(*FileArray_cref(iter));
FURI_LOG_I(TAG, "Found: %s", f);
}

FURI_LOG_I(TAG, "Creating our ItemsArray");
ItemArray_init(iview->items);
for(FileArray_it(iter, flist); !FileArray_end_p(iter); FileArray_next(iter)) {
path = *FileArray_ref(iter);
const char* found_path = furi_string_get_cstr(path);

Item* item = ItemArray_push_new(iview->items);

// Action files have extensions, so item->ext starts with '.' - ehhhh
// Action files have extensions, so item->ext starts with '.'
item->ext[0] = 0;
path_extract_extension(path, item->ext, MAX_EXT_LEN);
item->type = (item->ext[0] == '.') ? Item_Action : Item_Group;
// FURI_LOG_I(TAG, ". EXT = %s", item->ext);
if(item->ext[0] == '.') {
// TODO: hack alert - make a helper fn here, or something
if(item->ext[1] == 's')
item->type = Item_SubGhz;
else if(item->ext[1] == 'r')
item->type = Item_RFID;
else if(item->ext[1] == 'q')
item->type = Item_Playlist;
else if(item->ext[1] == 'i')
item->type = Item_IR;
} else {
item->type = Item_Group;
}

item->name = furi_string_alloc();
path_extract_filename_no_ext(found_path, item->name);
FURI_LOG_I(TAG, "Basename: %s", furi_string_get_cstr(item->name));
// FURI_LOG_I(TAG, "Basename: %s", furi_string_get_cstr(item->name));
item_prettify_name(item->name);

item->path = furi_string_alloc();
furi_string_set(item->path, path);
FURI_LOG_I(TAG, "Path: %s", furi_string_get_cstr(item->path));
// FURI_LOG_I(TAG, "Path: %s", furi_string_get_cstr(item->path));
}

FileArray_clear(flist);
Expand Down
9 changes: 8 additions & 1 deletion item.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@
* on-screen as well as to perform that action.
*/

typedef enum { Item_Action, Item_Group } ItemType;
typedef enum {
Item_SubGhz,
Item_RFID,
Item_IR,
Item_Playlist,
Item_Group,
Item_Settings
} ItemType;

typedef struct Item {
ItemType type;
Expand Down
31 changes: 27 additions & 4 deletions quac.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <gui/scene_manager.h>
#include <gui/modules/button_menu.h>
#include <gui/modules/dialog_ex.h>
#include <gui/modules/variable_item_list.h>

#include <storage/storage.h>
#include <notification/notification_messages.h>
Expand All @@ -14,6 +15,7 @@
#include "scenes/scene_items.h"

#include "quac.h"
#include "quac_settings.h"

/* generated by fbt from .png files in images folder */
#include <quac_icons.h>
Expand All @@ -30,10 +32,18 @@ App* app_alloc() {
// Create our UI elements
app->btn_menu = button_menu_alloc();
view_dispatcher_add_view(
app->view_dispatcher, SR_ButtonMenu, button_menu_get_view(app->btn_menu));
app->view_dispatcher, Q_ButtonMenu, button_menu_get_view(app->btn_menu));

app->action_menu = action_menu_alloc();
view_dispatcher_add_view(
app->view_dispatcher, Q_ActionMenu, action_menu_get_view(app->action_menu));

app->vil_settings = variable_item_list_alloc();
view_dispatcher_add_view(
app->view_dispatcher, Q_Settings, variable_item_list_get_view(app->vil_settings));

app->dialog = dialog_ex_alloc();
view_dispatcher_add_view(app->view_dispatcher, SR_Dialog, dialog_ex_get_view(app->dialog));
view_dispatcher_add_view(app->view_dispatcher, Q_Dialog, dialog_ex_get_view(app->dialog));

// Storage
app->storage = furi_record_open(RECORD_STORAGE);
Expand All @@ -45,6 +55,16 @@ App* app_alloc() {
app->depth = 0;
app->selected_item = -1;

// Default settings
// TODO: Store settings in apps_data/quac/.quac.conf as a Flipper Format File!
// Create Settings Scene, save settings _on_exit
// Always use settings in _on_enter of other scenes

app->settings.rfid_duration = 3000;
app->settings.layout = QUAC_APP_LANDSCAPE;
// app->settings.layout = QUAC_APP_PORTRAIT;
app->settings.show_icons = true;

app->items_view = item_get_items_view_from_path(app, NULL);

return app;
Expand All @@ -55,9 +75,11 @@ void app_free(App* app) {

item_items_view_free(app->items_view);

view_dispatcher_remove_view(app->view_dispatcher, SR_ButtonMenu);
view_dispatcher_remove_view(app->view_dispatcher, Q_ButtonMenu);

button_menu_free(app->btn_menu);
action_menu_free(app->action_menu);

scene_manager_free(app->scene_manager);
view_dispatcher_free(app->view_dispatcher);

Expand All @@ -73,10 +95,11 @@ int32_t quac_app(void* p) {
FURI_LOG_I(TAG, "QUAC! QUAC!");

App* app = app_alloc();
quac_load_settings(app);

Gui* gui = furi_record_open(RECORD_GUI);
view_dispatcher_attach_to_gui(app->view_dispatcher, gui, ViewDispatcherTypeFullscreen);
scene_manager_next_scene(app->scene_manager, SR_Scene_Items);
scene_manager_next_scene(app->scene_manager, Q_Scene_Items);
view_dispatcher_run(app->view_dispatcher);

furi_record_close(RECORD_GUI);
Expand Down
16 changes: 16 additions & 0 deletions quac.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@
#include <gui/view_dispatcher.h>
#include <gui/modules/button_menu.h>
#include <gui/modules/dialog_ex.h>
#include <gui/modules/variable_item_list.h>

#include <storage/storage.h>
#include <notification/notification_messages.h>

#include "views/action_menu.h"

#include "item.h"

#define QUAC_NAME "Quac!"
Expand All @@ -17,18 +21,30 @@
// Full path to actions
#define QUAC_DATA_PATH EXT_PATH(QUAC_PATH)

typedef enum { QUAC_APP_PORTRAIT, QUAC_APP_LANDSCAPE } QuacAppLayout;

typedef struct App {
SceneManager* scene_manager;
ViewDispatcher* view_dispatcher;
ButtonMenu* btn_menu;
DialogEx* dialog;
VariableItemList* vil_settings;
ActionMenu* action_menu;

Storage* storage;
NotificationApp* notifications;

int depth;
ItemsView* items_view;
int selected_item;

struct {
QuacAppLayout layout; // Defaults to Portrait
bool show_icons; // Defaults to True
bool show_headers; // Defaults to True
uint32_t rfid_duration; // Defaults to 2500 ms
} settings;

} App;

App* app_alloc();
Expand Down
142 changes: 142 additions & 0 deletions quac_settings.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
#include "quac_settings.h"

#include <flipper_format/flipper_format.h>

// Quac Settings File Info
// TODO: Fix this path to use existing #defs for /ext, etc
#define QUAC_SETTINGS_FILENAME "/ext/apps_data/quac/.quac.conf"
#define QUAC_SETTINGS_FILE_TYPE "Quac Settings File"
#define QUAC_SETTINGS_FILE_VERSION 1

// Quac Settings Defaults
#define QUAC_SETTINGS_DEFAULT_RFID_DURATION 2500
#define QUAC_SETTINGS_DEFAULT_LAYOUT QUAC_APP_LANDSCAPE // QUAC_APP_PORTRAIT
#define QUAC_SETTINGS_DEFAULT_SHOW_ICONS true
#define QUAC_SETTINGS_DEFAULT_SHOW_HEADERS true

void quac_set_default_settings(App* app) {
app->settings.rfid_duration = QUAC_SETTINGS_DEFAULT_RFID_DURATION;
app->settings.layout = QUAC_SETTINGS_DEFAULT_LAYOUT;
app->settings.show_icons = QUAC_SETTINGS_DEFAULT_SHOW_ICONS;
app->settings.show_headers = QUAC_SETTINGS_DEFAULT_SHOW_HEADERS;
}

void quac_load_settings(App* app) {
FlipperFormat* fff_settings = flipper_format_file_alloc(app->storage);
FuriString* temp_str;
temp_str = furi_string_alloc();
uint32_t temp_data32 = 0;

FURI_LOG_I(TAG, "SETTINGS: Reading settings file");
bool successful = false;
do {
if(!flipper_format_file_open_existing(fff_settings, QUAC_SETTINGS_FILENAME)) {
FURI_LOG_I(TAG, "SETTINGS: File not found, loading defaults");
break;
}

if(!flipper_format_read_header(fff_settings, temp_str, &temp_data32)) {
FURI_LOG_E(TAG, "SETTINGS: Missing or incorrect header");
break;
}

if((!strcmp(furi_string_get_cstr(temp_str), QUAC_SETTINGS_FILE_TYPE)) &&
(temp_data32 == QUAC_SETTINGS_FILE_VERSION)) {
} else {
FURI_LOG_E(TAG, "SETTINGS: Type or version mismatch");
break;
}

// Now read actual values we care about
if(!flipper_format_read_string(fff_settings, "Layout", temp_str)) {
FURI_LOG_E(TAG, "SETTINGS: Missing Layout");
break;
}
if(!strcmp(furi_string_get_cstr(temp_str), "Landscape")) {
app->settings.layout = QUAC_APP_LANDSCAPE;
} else if(!strcmp(furi_string_get_cstr(temp_str), "Portrait")) {
app->settings.layout = QUAC_APP_PORTRAIT;
} else {
FURI_LOG_E(TAG, "SETTINGS: Invalid Layout");
break;
}

if(!flipper_format_read_uint32(fff_settings, "Show Icons", &temp_data32, 1)) {
FURI_LOG_E(TAG, "SETTINGS: Missing 'Show Icons'");
break;
}
app->settings.show_icons = (temp_data32 == 0) ? false : true;

if(!flipper_format_read_uint32(fff_settings, "Show Headers", &temp_data32, 1)) {
FURI_LOG_E(TAG, "SETTINGS: Missing 'Show Headers'");
break;
}
app->settings.show_headers = (temp_data32 == 0) ? false : true;

if(!flipper_format_read_uint32(fff_settings, "RFID Duration", &temp_data32, 1)) {
FURI_LOG_E(TAG, "SETTINGS: Missing 'RFID Duration'");
break;
}
app->settings.rfid_duration = temp_data32;

successful = true;
} while(false);

if(!successful) {
quac_set_default_settings(app);
}

furi_string_free(temp_str);
flipper_format_free(fff_settings);
}

void quac_save_settings(App* app) {
FlipperFormat* fff_settings = flipper_format_file_alloc(app->storage);
uint32_t temp_data32;

bool successful = false;
do {
if(!flipper_format_file_open_always(fff_settings, QUAC_SETTINGS_FILENAME)) {
FURI_LOG_E(TAG, "SETTINGS: Unable to open file for save!!");
break;
}

if(!flipper_format_write_header_cstr(
fff_settings, QUAC_SETTINGS_FILE_TYPE, QUAC_SETTINGS_FILE_VERSION)) {
FURI_LOG_E(TAG, "SETTINGS: Failed writing file type and version");
break;
}
// layout, icons, headers, duration
if(!flipper_format_write_string_cstr(
fff_settings,
"Layout",
app->settings.layout == QUAC_APP_LANDSCAPE ? "Landscape" : "Portrait")) {
FURI_LOG_E(TAG, "SETTINGS: Failed to write Layout");
break;
}

temp_data32 = app->settings.show_icons ? 1 : 0;
if(!flipper_format_write_uint32(fff_settings, "Show Icons", &temp_data32, 1)) {
FURI_LOG_E(TAG, "SETTINGS: Failed to write 'Show Icons'");
break;
}
temp_data32 = app->settings.show_headers ? 1 : 0;
if(!flipper_format_write_uint32(fff_settings, "Show Headers", &temp_data32, 1)) {
FURI_LOG_E(TAG, "SETTINGS: Failed to write 'Show Headers'");
break;
}
if(!flipper_format_write_uint32(
fff_settings, "RFID Duration", &app->settings.rfid_duration, 1)) {
FURI_LOG_E(TAG, "SETTINGS: Failed to write 'RFID Duration'");
break;
}
successful = true;
} while(false);

if(!successful) {
FURI_LOG_E(TAG, "SETTINGS: Failed to save settings!!");
}

flipper_format_file_close(fff_settings);
flipper_format_free(fff_settings);
}
Loading

0 comments on commit a7c4386

Please sign in to comment.