Files
Momentum-Firmware/applications/services/desktop/views/desktop_view_lock_menu.c
2023-04-09 19:35:22 +01:00

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);
}