mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-04-25 03:29:58 -07:00
361 lines
13 KiB
C
361 lines
13 KiB
C
#include <furi.h>
|
|
#include <gui/elements.h>
|
|
#include <assets_icons.h>
|
|
#include <xtreme/settings.h>
|
|
#include <furi_hal_rtc.h>
|
|
|
|
#include "../desktop_i.h"
|
|
#include "desktop_view_lock_menu.h"
|
|
|
|
static const NotificationSequence sequence_note_c = {
|
|
&message_note_c5,
|
|
&message_delay_100,
|
|
&message_sound_off,
|
|
NULL,
|
|
};
|
|
|
|
typedef enum {
|
|
DesktopLockMenuIndexLefthandedMode,
|
|
DesktopLockMenuIndexSettings,
|
|
DesktopLockMenuIndexDarkMode,
|
|
DesktopLockMenuIndexLock,
|
|
DesktopLockMenuIndexBluetooth,
|
|
DesktopLockMenuIndexXtreme,
|
|
DesktopLockMenuIndexBrightness,
|
|
DesktopLockMenuIndexVolume,
|
|
|
|
DesktopLockMenuIndexTotalCount
|
|
} DesktopLockMenuIndex;
|
|
|
|
void desktop_lock_menu_set_callback(
|
|
DesktopLockMenuView* lock_menu,
|
|
DesktopLockMenuViewCallback callback,
|
|
void* context) {
|
|
furi_assert(lock_menu);
|
|
furi_assert(callback);
|
|
lock_menu->callback = callback;
|
|
lock_menu->context = context;
|
|
}
|
|
|
|
void desktop_lock_menu_set_pin_state(DesktopLockMenuView* lock_menu, bool pin_is_set) {
|
|
with_view_model(
|
|
lock_menu->view,
|
|
DesktopLockMenuViewModel * model,
|
|
{
|
|
model->pin_is_set = pin_is_set;
|
|
model->pin_lock = pin_is_set;
|
|
},
|
|
true);
|
|
}
|
|
|
|
void desktop_lock_menu_set_idx(DesktopLockMenuView* lock_menu, uint8_t idx) {
|
|
furi_assert(idx < DesktopLockMenuIndexTotalCount);
|
|
with_view_model(
|
|
lock_menu->view, DesktopLockMenuViewModel * model, { model->idx = idx; }, true);
|
|
}
|
|
|
|
void desktop_lock_menu_draw_callback(Canvas* canvas, void* model) {
|
|
DesktopLockMenuViewModel* m = model;
|
|
|
|
canvas_set_color(canvas, ColorBlack);
|
|
canvas_set_font(canvas, FontBatteryPercent);
|
|
|
|
int x, y, w, h;
|
|
bool selected, toggle;
|
|
bool enabled = false;
|
|
uint value = 0;
|
|
int total = 58;
|
|
const Icon* icon = NULL;
|
|
for(size_t i = 0; i < DesktopLockMenuIndexTotalCount; ++i) {
|
|
selected = m->idx == i;
|
|
toggle = i < 6;
|
|
if(toggle) {
|
|
x = 2 + 32 * (i / 2);
|
|
y = 2 + 32 * (i % 2);
|
|
w = 28;
|
|
h = 28;
|
|
enabled = false;
|
|
} else {
|
|
x = 98 + 16 * (i % 2);
|
|
y = 2;
|
|
w = 12;
|
|
h = 60;
|
|
value = 0;
|
|
}
|
|
|
|
switch(i) {
|
|
case DesktopLockMenuIndexLefthandedMode:
|
|
icon = &I_CC_LefthandedMode_16x16;
|
|
enabled = furi_hal_rtc_is_flag_set(FuriHalRtcFlagHandOrient);
|
|
break;
|
|
case DesktopLockMenuIndexSettings:
|
|
icon = &I_CC_Settings_16x16;
|
|
break;
|
|
case DesktopLockMenuIndexDarkMode:
|
|
icon = &I_CC_DarkMode_16x16;
|
|
enabled = XTREME_SETTINGS()->dark_mode;
|
|
break;
|
|
case DesktopLockMenuIndexLock:
|
|
icon = &I_CC_Lock_16x16;
|
|
break;
|
|
case DesktopLockMenuIndexBluetooth:
|
|
icon = &I_CC_Bluetooth_16x16;
|
|
enabled = m->lock_menu->bt->bt_settings.enabled;
|
|
break;
|
|
case DesktopLockMenuIndexXtreme:
|
|
icon = &I_CC_Xtreme_16x16;
|
|
break;
|
|
case DesktopLockMenuIndexBrightness:
|
|
icon = &I_Pin_star_7x7;
|
|
value = total - m->lock_menu->notification->settings.display_brightness * total;
|
|
break;
|
|
case DesktopLockMenuIndexVolume:
|
|
icon = &I_Volup_8x6;
|
|
value = total - m->lock_menu->notification->settings.speaker_volume * total;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if(selected) {
|
|
elements_bold_rounded_frame(canvas, x - 1, y - 1, w + 1, h + 1);
|
|
} else {
|
|
canvas_draw_rframe(canvas, x, y, w, h, 5);
|
|
}
|
|
|
|
if(toggle) {
|
|
if(enabled) {
|
|
canvas_draw_rbox(canvas, x, y, w, h, 5);
|
|
canvas_set_color(canvas, ColorWhite);
|
|
}
|
|
canvas_draw_icon(
|
|
canvas,
|
|
x + (w - icon_get_width(icon)) / 2,
|
|
y + (h - icon_get_height(icon)) / 2,
|
|
icon);
|
|
if(enabled) {
|
|
canvas_set_color(canvas, ColorBlack);
|
|
}
|
|
} else {
|
|
canvas_draw_icon(
|
|
canvas,
|
|
x + (w - icon_get_width(icon)) / 2,
|
|
y + (h - icon_get_height(icon)) / 2,
|
|
icon);
|
|
canvas_set_color(canvas, ColorXOR);
|
|
canvas_draw_box(canvas, x + 1, y + 1 + value, w - 2, h - 2 - value);
|
|
if(selected) {
|
|
canvas_set_color(canvas, ColorBlack);
|
|
} else {
|
|
canvas_set_color(canvas, ColorWhite);
|
|
}
|
|
canvas_draw_dot(canvas, x + 1, y + 1);
|
|
canvas_draw_dot(canvas, x + 1, y + h - 2);
|
|
canvas_draw_dot(canvas, x + w - 2, y + 1);
|
|
canvas_draw_dot(canvas, x + w - 2, y + h - 2);
|
|
canvas_set_color(canvas, ColorBlack);
|
|
canvas_draw_rframe(canvas, x, y, w, h, 5);
|
|
}
|
|
}
|
|
|
|
if(m->show_lock_menu) {
|
|
canvas_set_font(canvas, FontSecondary);
|
|
elements_bold_rounded_frame(canvas, 24, 4, 80, 56);
|
|
canvas_draw_str_aligned(canvas, 64, 16, AlignCenter, AlignCenter, "Keypad Lock");
|
|
canvas_draw_str_aligned(canvas, 64, 32, AlignCenter, AlignCenter, "PIN Code Lock");
|
|
canvas_draw_str_aligned(canvas, 64, 48, AlignCenter, AlignCenter, "PIN Lock + OFF");
|
|
elements_frame(canvas, 28, 8 + m->pin_lock * 16, 72, 15);
|
|
}
|
|
}
|
|
|
|
View* desktop_lock_menu_get_view(DesktopLockMenuView* lock_menu) {
|
|
furi_assert(lock_menu);
|
|
return lock_menu->view;
|
|
}
|
|
|
|
bool desktop_lock_menu_input_callback(InputEvent* event, void* context) {
|
|
furi_assert(event);
|
|
furi_assert(context);
|
|
|
|
DesktopLockMenuView* lock_menu = context;
|
|
uint8_t idx = 0;
|
|
int pin_lock = 0;
|
|
bool show_lock_menu = false;
|
|
bool consumed = true;
|
|
|
|
with_view_model(
|
|
lock_menu->view,
|
|
DesktopLockMenuViewModel * model,
|
|
{
|
|
show_lock_menu = model->show_lock_menu;
|
|
if((event->type == InputTypeShort) || (event->type == InputTypeRepeat)) {
|
|
if(model->show_lock_menu) {
|
|
if(event->key == InputKeyUp) {
|
|
model->pin_lock--;
|
|
if(model->pin_lock < 0) {
|
|
model->pin_lock = 2;
|
|
}
|
|
} else if(event->key == InputKeyDown) {
|
|
model->pin_lock++;
|
|
if(model->pin_lock > 2) {
|
|
model->pin_lock = 0;
|
|
}
|
|
} else if(event->key == InputKeyBack || event->key == InputKeyOk) {
|
|
model->show_lock_menu = false;
|
|
}
|
|
} else {
|
|
if(model->idx == DesktopLockMenuIndexLock && event->key == InputKeyOk) {
|
|
model->show_lock_menu = true;
|
|
} else if(model->idx < 6) {
|
|
if(event->key == InputKeyUp || event->key == InputKeyDown) {
|
|
if(model->idx % 2) {
|
|
model->idx--;
|
|
} else {
|
|
model->idx++;
|
|
}
|
|
} else if(event->key == InputKeyLeft) {
|
|
if(model->idx < 2) {
|
|
model->idx = 7;
|
|
} else {
|
|
model->idx -= 2;
|
|
}
|
|
} else if(event->key == InputKeyRight) {
|
|
if(model->idx >= 4) {
|
|
model->idx = 6;
|
|
} else {
|
|
model->idx += 2;
|
|
}
|
|
}
|
|
} else {
|
|
if(event->key == InputKeyLeft) {
|
|
model->idx--;
|
|
} else if(event->key == InputKeyRight) {
|
|
if(model->idx >= 7) {
|
|
model->idx = 1;
|
|
} else {
|
|
model->idx++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
idx = model->idx;
|
|
pin_lock = model->pin_lock;
|
|
},
|
|
true);
|
|
|
|
DesktopEvent desktop_event = 0;
|
|
if(show_lock_menu) {
|
|
if(event->key == InputKeyOk && event->type == InputTypeShort) {
|
|
switch(pin_lock) {
|
|
case 0:
|
|
desktop_event = DesktopLockMenuEventLock;
|
|
break;
|
|
case 1:
|
|
desktop_event = DesktopLockMenuEventLockPin;
|
|
break;
|
|
case 2:
|
|
desktop_event = DesktopLockMenuEventLockPinOff;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
if(event->key == InputKeyBack) {
|
|
consumed = false;
|
|
} else if(event->key == InputKeyOk && event->type == InputTypeShort) {
|
|
switch(idx) {
|
|
case DesktopLockMenuIndexLefthandedMode:
|
|
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagHandOrient)) {
|
|
furi_hal_rtc_reset_flag(FuriHalRtcFlagHandOrient);
|
|
} else {
|
|
furi_hal_rtc_set_flag(FuriHalRtcFlagHandOrient);
|
|
}
|
|
break;
|
|
case DesktopLockMenuIndexSettings:
|
|
desktop_event = DesktopLockMenuEventSettings;
|
|
break;
|
|
case DesktopLockMenuIndexDarkMode:
|
|
XTREME_SETTINGS()->dark_mode = !XTREME_SETTINGS()->dark_mode;
|
|
lock_menu->save_xtreme = true;
|
|
break;
|
|
case DesktopLockMenuIndexBluetooth:
|
|
lock_menu->bt->bt_settings.enabled = !lock_menu->bt->bt_settings.enabled;
|
|
if(lock_menu->bt->bt_settings.enabled) {
|
|
furi_hal_bt_start_advertising();
|
|
} else {
|
|
furi_hal_bt_stop_advertising();
|
|
}
|
|
lock_menu->save_bt = true;
|
|
break;
|
|
case DesktopLockMenuIndexXtreme:
|
|
desktop_event = DesktopLockMenuEventXtreme;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
} else if(idx >= 6 && (event->type == InputTypeShort || event->type == InputTypeRepeat)) {
|
|
int8_t offset = 0;
|
|
if(event->key == InputKeyUp) {
|
|
offset = 1;
|
|
} else if(event->key == InputKeyDown) {
|
|
offset = -1;
|
|
}
|
|
if(offset) {
|
|
float value;
|
|
switch(idx) {
|
|
case DesktopLockMenuIndexBrightness:
|
|
value = lock_menu->notification->settings.display_brightness + 0.05 * offset;
|
|
lock_menu->notification->settings.display_brightness =
|
|
value < 0.00f ? 0.00f : (value > 1.00f ? 1.00f : value);
|
|
lock_menu->save_notification = true;
|
|
notification_message(lock_menu->notification, &sequence_display_backlight_on);
|
|
break;
|
|
case DesktopLockMenuIndexVolume:
|
|
value = lock_menu->notification->settings.speaker_volume + 0.05 * offset;
|
|
lock_menu->notification->settings.speaker_volume =
|
|
value < 0.00f ? 0.00f : (value > 1.00f ? 1.00f : value);
|
|
lock_menu->save_notification = true;
|
|
notification_message(lock_menu->notification, &sequence_note_c);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(desktop_event) {
|
|
lock_menu->callback(desktop_event, lock_menu->context);
|
|
}
|
|
|
|
return consumed;
|
|
}
|
|
|
|
DesktopLockMenuView* desktop_lock_menu_alloc() {
|
|
DesktopLockMenuView* lock_menu = malloc(sizeof(DesktopLockMenuView));
|
|
lock_menu->bt = furi_record_open(RECORD_BT);
|
|
lock_menu->notification = furi_record_open(RECORD_NOTIFICATION);
|
|
lock_menu->view = view_alloc();
|
|
view_allocate_model(lock_menu->view, ViewModelTypeLocking, sizeof(DesktopLockMenuViewModel));
|
|
with_view_model(
|
|
lock_menu->view,
|
|
DesktopLockMenuViewModel * model,
|
|
{ model->lock_menu = lock_menu; },
|
|
false);
|
|
view_set_context(lock_menu->view, lock_menu);
|
|
view_set_draw_callback(lock_menu->view, (ViewDrawCallback)desktop_lock_menu_draw_callback);
|
|
view_set_input_callback(lock_menu->view, desktop_lock_menu_input_callback);
|
|
|
|
return lock_menu;
|
|
}
|
|
|
|
void desktop_lock_menu_free(DesktopLockMenuView* lock_menu_view) {
|
|
furi_assert(lock_menu_view);
|
|
|
|
view_free(lock_menu_view->view);
|
|
furi_record_close(RECORD_NOTIFICATION);
|
|
furi_record_close(RECORD_BT);
|
|
free(lock_menu_view);
|
|
}
|