#include "air_mouse_view.h" #include #include "../imu_mouse.h" #include "vgm_air_mouse_icons.h" struct AirMouseView { View* view; void* imu_device; ImuThread* imu; const ImuHidApi* hid_api; void* hid_inst; AirMouseViewExit exit_callback; void* context; }; typedef struct { bool left_pressed; bool up_pressed; bool ok_pressed; bool connected; bool show_ble_icon; } AirMouseModel; static void air_mouse_view_draw_callback(Canvas* canvas, void* context) { furi_assert(context); AirMouseModel* model = context; canvas_set_color(canvas, ColorBlack); if(model->show_ble_icon) { if(model->connected) { canvas_draw_icon(canvas, 0, 0, &I_Ble_connected_15x15); } else { canvas_draw_icon(canvas, 0, 0, &I_Ble_disconnected_15x15); } } canvas_draw_icon(canvas, 78, 8, &I_Circles_47x47); if(model->ok_pressed) { canvas_set_bitmap_mode(canvas, true); canvas_draw_icon(canvas, 95, 25, &I_Pressed_Button_13x13); canvas_set_bitmap_mode(canvas, false); canvas_set_color(canvas, ColorWhite); } canvas_draw_icon(canvas, 97, 27, &I_Left_mouse_icon_9x9); canvas_set_color(canvas, ColorBlack); if(model->up_pressed) { canvas_set_bitmap_mode(canvas, true); canvas_draw_icon(canvas, 95, 9, &I_Pressed_Button_13x13); canvas_set_bitmap_mode(canvas, false); canvas_set_color(canvas, ColorWhite); } canvas_draw_icon(canvas, 97, 11, &I_Right_mouse_icon_9x9); canvas_set_color(canvas, ColorBlack); if(model->left_pressed) { canvas_set_bitmap_mode(canvas, true); canvas_draw_icon(canvas, 79, 25, &I_Pressed_Button_13x13); canvas_set_bitmap_mode(canvas, false); canvas_set_color(canvas, ColorWhite); } canvas_draw_icon(canvas, 81, 27, &I_Scroll_icon_9x9); canvas_set_color(canvas, ColorBlack); canvas_set_font(canvas, FontPrimary); canvas_draw_str(canvas, 17, 12, "Air Mouse"); canvas_set_font(canvas, FontSecondary); canvas_draw_str(canvas, 0, 56, "Press Back to exit"); } static bool air_mouse_view_input_callback(InputEvent* event, void* context) { furi_assert(context); AirMouseView* air_mouse = context; bool consumed = false; if(event->key == InputKeyOk) { if((event->type == InputTypePress) || (event->type == InputTypeRelease)) { bool state = (event->type == InputTypePress); imu_mouse_key_press(air_mouse->imu, ImuMouseKeyLeft, state); with_view_model( air_mouse->view, AirMouseModel * model, { model->ok_pressed = state; }, true); } consumed = true; } else if(event->key == InputKeyUp) { if((event->type == InputTypePress) || (event->type == InputTypeRelease)) { bool state = (event->type == InputTypePress); imu_mouse_key_press(air_mouse->imu, ImuMouseKeyRight, state); with_view_model( air_mouse->view, AirMouseModel * model, { model->up_pressed = state; }, true); } consumed = true; } else if(event->key == InputKeyLeft) { if((event->type == InputTypePress) || (event->type == InputTypeRelease)) { bool state = (event->type == InputTypePress); imu_mouse_scroll_mode(air_mouse->imu, state); with_view_model( air_mouse->view, AirMouseModel * model, { model->left_pressed = state; }, true); } consumed = true; } return consumed; } static void air_mouse_view_enter(void* context) { furi_assert(context); AirMouseView* air_mouse = context; furi_assert(air_mouse->imu == NULL); air_mouse->imu = imu_start(air_mouse->imu_device, air_mouse->hid_api, air_mouse->hid_inst); } static void air_mouse_view_exit(void* context) { furi_assert(context); AirMouseView* air_mouse = context; imu_stop(air_mouse->imu); air_mouse->imu = NULL; if(air_mouse->exit_callback) { air_mouse->exit_callback(air_mouse->context); } } AirMouseView* air_mouse_view_alloc(AirMouseViewExit exit_callback, void* context) { AirMouseView* air_mouse = malloc(sizeof(AirMouseView)); air_mouse->view = view_alloc(); air_mouse->exit_callback = exit_callback; air_mouse->context = context; view_set_context(air_mouse->view, air_mouse); view_allocate_model(air_mouse->view, ViewModelTypeLocking, sizeof(AirMouseModel)); view_set_draw_callback(air_mouse->view, air_mouse_view_draw_callback); view_set_input_callback(air_mouse->view, air_mouse_view_input_callback); view_set_enter_callback(air_mouse->view, air_mouse_view_enter); view_set_exit_callback(air_mouse->view, air_mouse_view_exit); with_view_model(air_mouse->view, AirMouseModel * model, { model->connected = true; }, true); return air_mouse; } void air_mouse_view_free(AirMouseView* air_mouse) { furi_assert(air_mouse); view_free(air_mouse->view); free(air_mouse); } View* air_mouse_view_get_view(AirMouseView* air_mouse) { furi_assert(air_mouse); return air_mouse->view; } void air_mouse_view_set_device(AirMouseView* air_mouse, void* imu_device) { furi_assert(air_mouse); air_mouse->imu_device = imu_device; } void air_mouse_view_set_hid_api( AirMouseView* air_mouse, const ImuHidApi* hid, void* hid_inst, bool is_ble_interface) { furi_assert(air_mouse); air_mouse->hid_api = hid; air_mouse->hid_inst = hid_inst; with_view_model( air_mouse->view, AirMouseModel * model, { model->show_ble_icon = is_ble_interface; }, false); } void air_mouse_view_set_connected_status(AirMouseView* air_mouse, bool connected) { furi_assert(air_mouse); with_view_model( air_mouse->view, AirMouseModel * model, { model->connected = connected; }, true); }