1 /** 2 * \file 3 * 4 * \brief Spin control widget 5 * 6 * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. 7 * 8 * \asf_license_start 9 * 10 * \page License 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions are met: 14 * 15 * 1. Redistributions of source code must retain the above copyright notice, 16 * this list of conditions and the following disclaimer. 17 * 18 * 2. Redistributions in binary form must reproduce the above copyright notice, 19 * this list of conditions and the following disclaimer in the documentation 20 * and/or other materials provided with the distribution. 21 * 22 * 3. The name of Atmel may not be used to endorse or promote products derived 23 * from this software without specific prior written permission. 24 * 25 * 4. This software may only be redistributed and used in connection with an 26 * Atmel microcontroller product. 27 * 28 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED 29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 31 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR 32 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38 * POSSIBILITY OF SUCH DAMAGE. 39 * 40 * \asf_license_stop 41 * 42 */ 43 /* 44 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> 45 */ 46 #ifndef GFX_MONO_SPINCTRL_H 47 #define GFX_MONO_SPINCTRL_H 48 49 #include "gfx_mono.h" 50 #include "conf_spinctrl.h" 51 52 #ifdef __cplusplus 53 extern "C" { 54 #endif 55 56 /** 57 * \ingroup asfdoc_common2_gfx_mono 58 * \defgroup asfdoc_common2_gfx_mono_spinctrl Spinner widget for monochrome graphical displays 59 * 60 * This module provides a spinner widget system for monochrome graphical 61 * displays. 62 * 63 * There is support for having one single spinner on the screen, or a 64 * collection of spinners. 65 * 66 * Typical flow of an application using the spincollection system: 67 * 68 * 1) Define spinners.\n 69 * 2) Initialize each spinners with \ref gfx_mono_spinctrl_init.\n 70 * 3) Define a spincollection struct and initialize it with 71 * \ref gfx_mono_spinctrl_spincollection_init.\n 72 * 4) Add spinners to spincollection with 73 * \ref gfx_mono_spinctrl_spincollection_add_spinner.\n 74 * 5) Draw spincollection to screen with 75 * \ref gfx_mono_spinctrl_spincollection_show.\n 76 * 6) Define a result array to store the spinner choices.\n 77 * 7) Update spinners and result array with user input using function 78 * \ref gfx_mono_spinctrl_spincollection_process_key.\n 79 * 8) Interpret \ref gfx_mono_spinctrl_spincollection_process_key return 80 * value.\n 81 * 9) Go to 7.\n 82 * 83 * Typical flow of an application using a single spinner: 84 * 85 * 1) Define spinner.\n 86 * 2) Initialize the spinners with \ref gfx_mono_spinctrl_init with preferred y 87 * position on screen.\n 88 * 3) Draw spinner to screen with \ref gfx_mono_spinctrl_draw.\n 89 * 4) Update spinner with user input using function 90 * \ref gfx_mono_spinctrl_process_key.\n 91 * 5) Interpret \ref gfx_mono_spinctrl_process_key return value.\n 92 * 6) Go to 4.\n 93 * 94 * Before the spinners can be updated, you need input from the user. Methods 95 * for getting input is not part of the spinner widget. 96 * 97 * \note The spinners will be linked together when added to a spincollection, 98 * and can therefore not be used in two spincollections at the same time. 99 * 100 * As soon as input is received, inform the spincollection system or the single 101 * spinner using the \ref gfx_mono_spinctrl_spincollection_process_key function 102 * or the \ref gfx_mono_spinctrl_process_key function. 103 * These functions will then return a status code and act depending on the 104 * given keycode: 105 * 106 * GFX_MONO_SPINCTRL_KEYCODE_DOWN : Change selection to next spinner value or 107 * to next spinner or OK button in a spincollection. 108 * 109 * GFX_MONO_SPINCTRL_KEYCODE_UP : Change selection to previous spinner value 110 * or to previous spinner or OK button in a spincollection. 111 * 112 * GFX_MONO_SPINCTRL_KEYCODE_ENTER : Select spinner value or select spinner or 113 * OK button in a spincollection. 114 * 115 * GFX_MONO_SPINCTRL_KEYCODE_BACK : Deselect spinner or cancel spincollection 116 * application. 117 * 118 * The value of the keycodes used are defined in conf_spinctrl.h. These values 119 * can be changed if needed. 120 * 121 * The graphical indicators used to indicate spinner selections are defined in 122 * conf_spinctrl.h. These indicators can be changed if needed. 123 * @{ 124 */ 125 126 /** Spinner idle event */ 127 #define GFX_MONO_SPINCTRL_EVENT_IDLE 0xFF 128 /** Spinner back button pressed event */ 129 #define GFX_MONO_SPINCTRL_EVENT_BACK 0xFE 130 /** Spinner ok button pressed event */ 131 #define GFX_MONO_SPINCTRL_EVENT_FINISH 0xFD 132 133 /** OK button */ 134 #define GFX_MONO_SPINCTRL_BUTTON 0xFF 135 136 /** Maximum number of spinner elements on display */ 137 #define GFX_MONO_SPINCTRL_ELEMENTS_PER_SCREEN \ 138 ((GFX_MONO_LCD_HEIGHT / SYSFONT_LINESPACING) - 1) 139 140 /** 141 * Maximum numbers of spinner elements in a spincollection - limited to 142 * one screen. 143 */ 144 #define GFX_MONO_SPINCTRL_MAX_ELEMENTS_IN_SPINCOLLECTION \ 145 GFX_MONO_SPINCTRL_ELEMENTS_PER_SCREEN 146 147 /** Width of string spinner choices */ 148 #define GFX_MONO_SPINCTRL_STRING_SPINNER_WIDTH 9 149 /** Width of integer spinner choices */ 150 #define GFX_MONO_SPINCTRL_INT_SPINNER_WIDTH 9 151 152 /** Enum to specify what kind of data spinner should spin */ 153 typedef enum gfx_mono_spinctrl_type_enum { 154 SPINTYPE_STRING, 155 SPINTYPE_INTEGER 156 } gfx_mono_spinctrl_type_t; 157 158 /** String struct */ 159 struct gfx_mono_spinctrl_string { 160 /** Pointer to progmem strings to spin through 161 * \note Each string must be shorter than 162 * \ref GFX_MONO_SPINCTRL_STRING_SPINNER_WIDTH characters. 163 * If not, printing it to the screen will corrupt the spinner 164 * appearance. 165 */ 166 PROGMEM_STRING_T *data; 167 /** Index in string array */ 168 uint8_t index; 169 }; 170 171 /** Spin control struct */ 172 struct gfx_mono_spinctrl { 173 /** Spinner title */ 174 PROGMEM_STRING_T title; 175 /** Type of data to spin */ 176 gfx_mono_spinctrl_type_t datatype; 177 /** Spinner data, depends on spinner datatype. */ 178 union { 179 /** Spinner strings and index */ 180 struct gfx_mono_spinctrl_string strings; 181 /** Spinner integer data */ 182 int16_t integer_data; 183 }; 184 /** Variable to store the last selected spinner value */ 185 uint16_t last_saved_value; 186 187 /** 188 * Lower limit for spinning, must be positive and fit in uin8_t for 189 * spinner type SPINTYPE_STRING 190 */ 191 int16_t lower_limit; 192 193 /** 194 * Upper limit for spinning, must be positive and fit in uin8_t for 195 * spinner type SPINTYPE_STRING 196 */ 197 int16_t upper_limit; 198 /** Y coordinate for placement of spinner on screen */ 199 gfx_coord_t y; 200 /** Boolean to tell if spinner is in focus or not */ 201 bool in_focus; 202 /** Pointer to next spinner in a spincollection */ 203 struct gfx_mono_spinctrl *next; 204 /** Pointer to previous spinner in a spincollection */ 205 struct gfx_mono_spinctrl *prev; 206 }; 207 208 /** Collection of spinners struct */ 209 struct gfx_mono_spinctrl_spincollection { 210 /** Pointer to the first spinner in the collection */ 211 struct gfx_mono_spinctrl *collection; 212 /** Pointer to the last spinner in the collection */ 213 struct gfx_mono_spinctrl *collection_last; 214 /** Number of spinners in collection */ 215 uint8_t number_of_spinners; 216 /** Current spinner/button */ 217 uint8_t current_selection; 218 /** Return value from selected spinner */ 219 uint16_t selection; 220 /** Boolean to tell if input should be sent directly to a spinner */ 221 bool active_spinner; 222 /** Boolean to initialize results array when starting key processing */ 223 bool init; 224 }; 225 226 void gfx_mono_spinctrl_init(struct gfx_mono_spinctrl *spinner, 227 gfx_mono_spinctrl_type_t datatype, PROGMEM_STRING_T title, 228 PROGMEM_STRING_T *data, int16_t lower_limit, 229 int16_t upper_limit, 230 gfx_coord_t y); 231 void gfx_mono_spinctrl_draw(struct gfx_mono_spinctrl *spinner, bool redraw); 232 void gfx_mono_spinctrl_spincollection_init(struct 233 gfx_mono_spinctrl_spincollection *collection); 234 void gfx_mono_spinctrl_spincollection_add_spinner(struct gfx_mono_spinctrl 235 *spinner, struct gfx_mono_spinctrl_spincollection *spinners); 236 void gfx_mono_spinctrl_spincollection_show(struct 237 gfx_mono_spinctrl_spincollection *spinners); 238 int16_t gfx_mono_spinctrl_process_key(struct gfx_mono_spinctrl *spinner, 239 uint8_t keycode); 240 241 int16_t gfx_mono_spinctrl_spincollection_process_key(struct 242 gfx_mono_spinctrl_spincollection *spinners, uint8_t keycode, 243 int16_t results[]); 244 245 /** @} */ 246 247 #ifdef __cplusplus 248 } 249 #endif 250 251 #endif /* GFX_MONO_SPINCTRL_H */ 252