|
| 1 | +#include "xbox_controller.h" |
| 2 | +#include "media_controller_view.h" |
| 3 | + |
| 4 | +#include <infrared_worker.h> |
| 5 | +#include <infrared_transmit.h> |
| 6 | + |
| 7 | +struct MediaControllerView { |
| 8 | + View* view; |
| 9 | + NotificationApp* notifications; |
| 10 | +}; |
| 11 | + |
| 12 | +typedef struct { |
| 13 | + bool left_pressed; |
| 14 | + bool up_pressed; |
| 15 | + bool right_pressed; |
| 16 | + bool down_pressed; |
| 17 | + bool ok_pressed; |
| 18 | + bool back_pressed; |
| 19 | + bool connected; |
| 20 | +} MediaControllerViewModel; |
| 21 | + |
| 22 | +static void |
| 23 | + media_controller_view_draw_icon(Canvas* canvas, uint8_t x, uint8_t y, CanvasDirection dir) { |
| 24 | + if(dir == CanvasDirectionBottomToTop) { |
| 25 | + canvas_draw_icon(canvas, x - 7, y - 5, &I_Volup_Icon_11x11); |
| 26 | + } else if(dir == CanvasDirectionTopToBottom) { |
| 27 | + canvas_draw_icon(canvas, x - 7, y - 5, &I_Voldown_Icon_11x11); |
| 28 | + } else if(dir == CanvasDirectionRightToLeft) { |
| 29 | + canvas_draw_triangle(canvas, x, y, 8, 5, CanvasDirectionRightToLeft); |
| 30 | + canvas_draw_line(canvas, x - 5, y - 4, x - 5, y + 4); |
| 31 | + } else if(dir == CanvasDirectionLeftToRight) { |
| 32 | + canvas_draw_triangle(canvas, x - 4, y, 8, 5, CanvasDirectionLeftToRight); |
| 33 | + canvas_draw_line(canvas, x + 1, y - 4, x + 1, y + 4); |
| 34 | + } |
| 35 | +} |
| 36 | + |
| 37 | +static void media_controller_view_draw_arrow_button( |
| 38 | + Canvas* canvas, |
| 39 | + bool pressed, |
| 40 | + uint8_t x, |
| 41 | + uint8_t y, |
| 42 | + CanvasDirection direction) { |
| 43 | + canvas_draw_icon(canvas, x, y, &I_Button_18x18); |
| 44 | + if(pressed) { |
| 45 | + elements_slightly_rounded_box(canvas, x + 3, y + 2, 13, 13); |
| 46 | + canvas_set_color(canvas, ColorWhite); |
| 47 | + } |
| 48 | + media_controller_view_draw_icon(canvas, x + 11, y + 8, direction); |
| 49 | + canvas_set_color(canvas, ColorBlack); |
| 50 | +} |
| 51 | + |
| 52 | +static void media_controller_draw_wide_button( |
| 53 | + Canvas* canvas, |
| 54 | + bool pressed, |
| 55 | + uint8_t x, |
| 56 | + uint8_t y, |
| 57 | + char* text, |
| 58 | + const Icon* icon) { |
| 59 | + // canvas_draw_icon(canvas, 0, 25, &I_Space_65x18); |
| 60 | + elements_slightly_rounded_frame(canvas, x, y, 64, 17); |
| 61 | + if(pressed) { |
| 62 | + elements_slightly_rounded_box(canvas, x + 2, y + 2, 60, 13); |
| 63 | + canvas_set_color(canvas, ColorWhite); |
| 64 | + } |
| 65 | + canvas_draw_icon(canvas, x + 11, y + 4, icon); |
| 66 | + elements_multiline_text_aligned(canvas, x + 28, y + 12, AlignLeft, AlignBottom, text); |
| 67 | + canvas_set_color(canvas, ColorBlack); |
| 68 | +} |
| 69 | + |
| 70 | +static void media_controller_view_draw_callback(Canvas* canvas, void* context) { |
| 71 | + furi_assert(context); |
| 72 | + MediaControllerViewModel* model = context; |
| 73 | + |
| 74 | + canvas_set_font(canvas, FontPrimary); |
| 75 | + elements_multiline_text_aligned(canvas, 0, 0, AlignLeft, AlignTop, "Media"); |
| 76 | + |
| 77 | + canvas_set_font(canvas, FontSecondary); |
| 78 | + |
| 79 | + canvas_draw_icon(canvas, 0, 12, &I_Pin_back_arrow_10x8); |
| 80 | + canvas_draw_str(canvas, 12, 20, "Hold"); |
| 81 | + |
| 82 | + media_controller_view_draw_arrow_button( |
| 83 | + canvas, model->up_pressed, 23, 74, CanvasDirectionBottomToTop); |
| 84 | + media_controller_view_draw_arrow_button( |
| 85 | + canvas, model->down_pressed, 23, 110, CanvasDirectionTopToBottom); |
| 86 | + media_controller_view_draw_arrow_button( |
| 87 | + canvas, model->left_pressed, 0, 92, CanvasDirectionRightToLeft); |
| 88 | + media_controller_view_draw_arrow_button( |
| 89 | + canvas, model->right_pressed, 46, 92, CanvasDirectionLeftToRight); |
| 90 | + |
| 91 | + int buttons_post = 30; |
| 92 | + // Ok |
| 93 | + media_controller_draw_wide_button( |
| 94 | + canvas, model->ok_pressed, 0, buttons_post, "Play", &I_Ok_btn_9x9); |
| 95 | + // Back |
| 96 | + media_controller_draw_wide_button( |
| 97 | + canvas, model->back_pressed, 0, buttons_post + 19, "Mute", &I_Pin_back_arrow_10x8); |
| 98 | +} |
| 99 | + |
| 100 | +static void |
| 101 | + media_controller_view_process(MediaControllerView* media_controller_view, InputEvent* event) { |
| 102 | + with_view_model( |
| 103 | + media_controller_view->view, |
| 104 | + MediaControllerViewModel * model, |
| 105 | + { |
| 106 | + if(event->type == InputTypePress || event->type == InputTypeRepeat) { |
| 107 | + bool repeat = event->type == InputTypeRepeat; |
| 108 | + if(event->key == InputKeyUp) { |
| 109 | + model->up_pressed = true; |
| 110 | + send_xbox_ir(0xEF10, media_controller_view->notifications, repeat); |
| 111 | + } else if(event->key == InputKeyDown) { |
| 112 | + model->down_pressed = true; |
| 113 | + send_xbox_ir(0xEE11, media_controller_view->notifications, repeat); |
| 114 | + } else if(event->key == InputKeyLeft) { |
| 115 | + model->left_pressed = true; |
| 116 | + send_xbox_ir(0xE41B, media_controller_view->notifications, repeat); |
| 117 | + } else if(event->key == InputKeyRight) { |
| 118 | + model->right_pressed = true; |
| 119 | + send_xbox_ir(0xE51A, media_controller_view->notifications, repeat); |
| 120 | + } else if(event->key == InputKeyOk) { |
| 121 | + model->ok_pressed = true; |
| 122 | + send_xbox_ir(0x8F70, media_controller_view->notifications, repeat); |
| 123 | + } else if(event->key == InputKeyBack) { |
| 124 | + model->back_pressed = true; |
| 125 | + send_xbox_ir(0xF10E, media_controller_view->notifications, repeat); |
| 126 | + } |
| 127 | + } else if(event->type == InputTypeRelease) { |
| 128 | + if(event->key == InputKeyUp) { |
| 129 | + model->up_pressed = false; |
| 130 | + } else if(event->key == InputKeyDown) { |
| 131 | + model->down_pressed = false; |
| 132 | + } else if(event->key == InputKeyLeft) { |
| 133 | + model->left_pressed = false; |
| 134 | + } else if(event->key == InputKeyRight) { |
| 135 | + model->right_pressed = false; |
| 136 | + } else if(event->key == InputKeyOk) { |
| 137 | + model->ok_pressed = false; |
| 138 | + } else if(event->key == InputKeyBack) { |
| 139 | + model->back_pressed = false; |
| 140 | + } |
| 141 | + } |
| 142 | + }, |
| 143 | + true); |
| 144 | +} |
| 145 | + |
| 146 | +static bool media_controller_view_input_callback(InputEvent* event, void* context) { |
| 147 | + furi_assert(context); |
| 148 | + MediaControllerView* media_controller_view = context; |
| 149 | + bool consumed = false; |
| 150 | + |
| 151 | + if(event->type == InputTypeLong && event->key == InputKeyBack) { |
| 152 | + // LONG KEY BACK PRESS HANDLER |
| 153 | + } else { |
| 154 | + media_controller_view_process(media_controller_view, event); |
| 155 | + consumed = true; |
| 156 | + } |
| 157 | + |
| 158 | + return consumed; |
| 159 | +} |
| 160 | + |
| 161 | +MediaControllerView* media_controller_view_alloc(NotificationApp* notifications) { |
| 162 | + MediaControllerView* media_controller_view = malloc(sizeof(MediaControllerView)); |
| 163 | + media_controller_view->view = view_alloc(); |
| 164 | + media_controller_view->notifications = notifications; |
| 165 | + view_set_orientation(media_controller_view->view, ViewOrientationVertical); |
| 166 | + view_set_context(media_controller_view->view, media_controller_view); |
| 167 | + view_allocate_model( |
| 168 | + media_controller_view->view, ViewModelTypeLocking, sizeof(MediaControllerViewModel)); |
| 169 | + view_set_draw_callback(media_controller_view->view, media_controller_view_draw_callback); |
| 170 | + view_set_input_callback(media_controller_view->view, media_controller_view_input_callback); |
| 171 | + |
| 172 | + return media_controller_view; |
| 173 | +} |
| 174 | + |
| 175 | +void media_controller_view_free(MediaControllerView* media_controller_view) { |
| 176 | + furi_assert(media_controller_view); |
| 177 | + view_free(media_controller_view->view); |
| 178 | + free(media_controller_view); |
| 179 | +} |
| 180 | + |
| 181 | +View* media_controller_view_get_view(MediaControllerView* media_controller_view) { |
| 182 | + furi_assert(media_controller_view); |
| 183 | + return media_controller_view->view; |
| 184 | +} |
| 185 | + |
| 186 | +void media_controller_view_set_connected_status( |
| 187 | + MediaControllerView* media_controller_view, |
| 188 | + bool connected) { |
| 189 | + furi_assert(media_controller_view); |
| 190 | + with_view_model( |
| 191 | + media_controller_view->view, |
| 192 | + MediaControllerViewModel * model, |
| 193 | + { model->connected = connected; }, |
| 194 | + true); |
| 195 | +} |
0 commit comments