summaryrefslogtreecommitdiff
path: root/bsp/samd21/sam_d2x_asflib/common2/services/gfx_mono/gfx_mono_spinctrl.h
blob: 968222334aa9700ff14fb98d632df7ec5529c632 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
/**
 * \file
 *
 * \brief Spin control widget
 *
 * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.
 *
 * \asf_license_start
 *
 * \page License
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * 3. The name of Atmel may not be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * 4. This software may only be redistributed and used in connection with an
 *    Atmel microcontroller product.
 *
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * \asf_license_stop
 *
 */
/*
 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
 */
#ifndef GFX_MONO_SPINCTRL_H
#define GFX_MONO_SPINCTRL_H

#include "gfx_mono.h"
#include "conf_spinctrl.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * \ingroup asfdoc_common2_gfx_mono
 * \defgroup asfdoc_common2_gfx_mono_spinctrl Spinner widget for monochrome graphical displays
 *
 * This module provides a spinner widget system for monochrome graphical
 * displays.
 *
 * There is support for having one single spinner on the screen, or a
 * collection of spinners.
 *
 * Typical flow of an application using the spincollection system:
 *
 * 1) Define spinners.\n
 * 2) Initialize each spinners with \ref gfx_mono_spinctrl_init.\n
 * 3) Define a spincollection struct and initialize it with
 * \ref gfx_mono_spinctrl_spincollection_init.\n
 * 4) Add spinners to spincollection with
 * \ref gfx_mono_spinctrl_spincollection_add_spinner.\n
 * 5) Draw spincollection to screen with
 * \ref gfx_mono_spinctrl_spincollection_show.\n
 * 6) Define a result array to store the spinner choices.\n
 * 7) Update spinners and result array with user input using function
 * \ref gfx_mono_spinctrl_spincollection_process_key.\n
 * 8) Interpret \ref gfx_mono_spinctrl_spincollection_process_key return
 * value.\n
 * 9) Go to 7.\n
 *
 * Typical flow of an application using a single spinner:
 *
 * 1) Define spinner.\n
 * 2) Initialize the spinners with \ref gfx_mono_spinctrl_init with preferred y
 * position on screen.\n
 * 3) Draw spinner to screen with \ref gfx_mono_spinctrl_draw.\n
 * 4) Update spinner with user input using function
 * \ref gfx_mono_spinctrl_process_key.\n
 * 5) Interpret \ref gfx_mono_spinctrl_process_key return value.\n
 * 6) Go to 4.\n
 *
 * Before the spinners can be updated, you need input from the user. Methods
 * for getting input is not part of the spinner widget.
 *
 * \note The spinners will be linked together when added to a spincollection,
 * and can therefore not be used in two spincollections at the same time.
 *
 * As soon as input is received, inform the spincollection system or the single
 * spinner using the \ref gfx_mono_spinctrl_spincollection_process_key function
 * or the \ref gfx_mono_spinctrl_process_key function.
 * These functions will then return a status code and act depending on the
 * given keycode:
 *
 * GFX_MONO_SPINCTRL_KEYCODE_DOWN : Change selection to next spinner value or
 * to next spinner or OK button in a spincollection.
 *
 * GFX_MONO_SPINCTRL_KEYCODE_UP : Change selection to previous spinner value
 * or to previous spinner or OK button in a spincollection.
 *
 * GFX_MONO_SPINCTRL_KEYCODE_ENTER : Select spinner value or select spinner or
 * OK button in a spincollection.
 *
 * GFX_MONO_SPINCTRL_KEYCODE_BACK : Deselect spinner or cancel spincollection
 * application.
 *
 * The value of the keycodes used are defined in conf_spinctrl.h. These values
 * can be changed if needed.
 *
 * The graphical indicators used to indicate spinner selections are defined in
 * conf_spinctrl.h. These indicators can be changed if needed.
 * @{
 */

/** Spinner idle event */
#define GFX_MONO_SPINCTRL_EVENT_IDLE                0xFF
/** Spinner back button pressed event */
#define GFX_MONO_SPINCTRL_EVENT_BACK                0xFE
/** Spinner ok button pressed event */
#define GFX_MONO_SPINCTRL_EVENT_FINISH              0xFD

/** OK button */
#define GFX_MONO_SPINCTRL_BUTTON        0xFF

/** Maximum number of spinner elements on display */
#define GFX_MONO_SPINCTRL_ELEMENTS_PER_SCREEN \
	((GFX_MONO_LCD_HEIGHT / SYSFONT_LINESPACING) - 1)

/**
 * Maximum numbers of spinner elements in a spincollection - limited to
 * one screen.
 */
#define GFX_MONO_SPINCTRL_MAX_ELEMENTS_IN_SPINCOLLECTION \
	GFX_MONO_SPINCTRL_ELEMENTS_PER_SCREEN

/** Width of string spinner choices */
#define GFX_MONO_SPINCTRL_STRING_SPINNER_WIDTH 9
/** Width of integer spinner choices */
#define GFX_MONO_SPINCTRL_INT_SPINNER_WIDTH    9

/** Enum to specify what kind of data spinner should spin */
typedef enum gfx_mono_spinctrl_type_enum {
	SPINTYPE_STRING,
	SPINTYPE_INTEGER
} gfx_mono_spinctrl_type_t;

/** String struct */
struct gfx_mono_spinctrl_string {
	/** Pointer to progmem strings to spin through
	 * \note Each string must be shorter than
	 * \ref  GFX_MONO_SPINCTRL_STRING_SPINNER_WIDTH characters.
	 * If not, printing it to the screen will corrupt the spinner
	 * appearance.
	 */
	PROGMEM_STRING_T *data;
	/** Index in string array */
	uint8_t index;
};

/** Spin control struct */
struct gfx_mono_spinctrl {
	/** Spinner title */
	PROGMEM_STRING_T title;
	/** Type of data to spin */
	gfx_mono_spinctrl_type_t datatype;
	/** Spinner data, depends on spinner datatype. */
	union {
		/** Spinner strings and index */
		struct gfx_mono_spinctrl_string strings;
		/** Spinner integer data */
		int16_t integer_data;
	};
	/** Variable to store the last selected spinner value */
	uint16_t last_saved_value;

	/**
	 * Lower limit for spinning, must be positive and fit in uin8_t for
	 * spinner type SPINTYPE_STRING
	 */
	int16_t lower_limit;

	/**
	 * Upper limit for spinning, must be positive and fit in uin8_t for
	 * spinner type SPINTYPE_STRING
	 */
	int16_t upper_limit;
	/** Y coordinate for placement of spinner on screen */
	gfx_coord_t y;
	/** Boolean to tell if spinner is in focus or not */
	bool in_focus;
	/** Pointer to next spinner in a spincollection */
	struct gfx_mono_spinctrl *next;
	/** Pointer to previous spinner in a spincollection */
	struct gfx_mono_spinctrl *prev;
};

/** Collection of spinners struct */
struct gfx_mono_spinctrl_spincollection {
	/** Pointer to the first spinner in the collection */
	struct gfx_mono_spinctrl *collection;
	/** Pointer to the last spinner in the collection */
	struct gfx_mono_spinctrl *collection_last;
	/** Number of spinners in collection */
	uint8_t number_of_spinners;
	/** Current spinner/button */
	uint8_t current_selection;
	/** Return value from selected spinner */
	uint16_t selection;
	/** Boolean to tell if input should be sent directly to a spinner */
	bool active_spinner;
	/** Boolean to initialize results array when starting key processing */
	bool init;
};

void gfx_mono_spinctrl_init(struct gfx_mono_spinctrl *spinner,
		gfx_mono_spinctrl_type_t datatype, PROGMEM_STRING_T title,
		PROGMEM_STRING_T *data, int16_t lower_limit,
		int16_t upper_limit,
		gfx_coord_t y);
void gfx_mono_spinctrl_draw(struct gfx_mono_spinctrl *spinner, bool redraw);
void gfx_mono_spinctrl_spincollection_init(struct
		gfx_mono_spinctrl_spincollection *collection);
void gfx_mono_spinctrl_spincollection_add_spinner(struct gfx_mono_spinctrl
		*spinner, struct gfx_mono_spinctrl_spincollection *spinners);
void gfx_mono_spinctrl_spincollection_show(struct
		gfx_mono_spinctrl_spincollection *spinners);
int16_t gfx_mono_spinctrl_process_key(struct gfx_mono_spinctrl *spinner,
		uint8_t keycode);

int16_t gfx_mono_spinctrl_spincollection_process_key(struct
gfx_mono_spinctrl_spincollection *spinners, uint8_t keycode,
int16_t results[]);

/** @} */

#ifdef __cplusplus
}
#endif

#endif /* GFX_MONO_SPINCTRL_H */