simple_dialog.c (3288B)
1 /* 2 * Copyright (c) 2016, Natacha Porté 3 * 4 * Permission to use, copy, modify, and distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #include <pebble.h> 18 19 #include "simple_dialog.h" 20 21 #define DIALOG_MESSAGE_WINDOW_MARGIN 10 22 23 static void 24 leave_window(ClickRecognizerRef recognizer, void *context) { 25 (void)recognizer; 26 (void)context; 27 window_stack_pop(true); 28 } 29 30 static void 31 click_config(void *context) { 32 (void)context; 33 window_single_click_subscribe(BUTTON_ID_BACK, &leave_window); 34 window_single_click_subscribe(BUTTON_ID_UP, &leave_window); 35 window_single_click_subscribe(BUTTON_ID_SELECT, &leave_window); 36 window_single_click_subscribe(BUTTON_ID_DOWN, &leave_window); 37 } 38 39 static Window *dialog_window; 40 static TextLayer *message_layer; 41 static const char *message_text = 0; 42 static bool static_message_text = true; 43 44 static void 45 window_load(Window *window) { 46 Layer *window_layer = window_get_root_layer(window); 47 GRect bounds = layer_get_bounds(window_layer); 48 49 message_layer = text_layer_create(GRect(DIALOG_MESSAGE_WINDOW_MARGIN, 50 bounds.size.h / 3, 51 bounds.size.w - (2 * DIALOG_MESSAGE_WINDOW_MARGIN), 52 (bounds.size.h + 2) / 3)); 53 text_layer_set_text(message_layer, message_text); 54 text_layer_set_text_alignment(message_layer, GTextAlignmentCenter); 55 text_layer_set_font(message_layer, 56 fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD)); 57 layer_add_child(window_layer, text_layer_get_layer(message_layer)); 58 } 59 60 static void 61 window_unload(Window *window) { 62 text_layer_destroy(message_layer); 63 message_layer = 0; 64 65 if (!static_message_text) free((void *)message_text); 66 message_text = 0; 67 } 68 69 static bool 70 update_text(const char *original_text, bool is_static) { 71 const char *new_text = 0; 72 73 if (is_static) { 74 new_text = original_text; 75 } else { 76 size_t text_size = strlen(original_text) + 1; 77 char *buffer = malloc(text_size); 78 79 if (!buffer) { 80 APP_LOG(APP_LOG_LEVEL_ERROR, "Unable to allocate" 81 " message text for simple dialog"); 82 return false; 83 } 84 85 memcpy(buffer, original_text, text_size); 86 new_text = buffer; 87 } 88 89 if (message_layer) { 90 text_layer_set_text(message_layer, new_text); 91 } 92 93 if (!static_message_text) free((void *)message_text); 94 message_text = new_text; 95 static_message_text = is_static; 96 return true; 97 } 98 99 void 100 push_simple_dialog(const char *message, bool is_static) { 101 update_text(message, is_static); 102 103 if (!dialog_window) { 104 dialog_window = window_create(); 105 window_set_window_handlers(dialog_window, (WindowHandlers){ 106 .load = &window_load, 107 .unload = &window_unload 108 }); 109 window_set_click_config_provider(dialog_window, &click_config); 110 } 111 112 window_stack_push(dialog_window, true); 113 }