-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlayer_tester.txt
180 lines (146 loc) · 5.91 KB
/
layer_tester.txt
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
#include "pebble.h"
#define NUM_MENU_SECTIONS 2
#define NUM_MENU_ICONS 3
#define NUM_FIRST_MENU_ITEMS 3
#define NUM_SECOND_MENU_ITEMS 1
static Window *window;
// This is a menu layer
// You have more control than with a simple menu layer
static MenuLayer *menu_layer;
// Menu items can optionally have an icon drawn with them
static GBitmap *menu_icons[NUM_MENU_ICONS];
static int current_icon = 0;
// You can draw arbitrary things in a menu item such as a background
static GBitmap *menu_background;
// A callback is used to specify the amount of sections of menu items
// With this, you can dynamically add and remove sections
static uint16_t menu_get_num_sections_callback(MenuLayer *menu_layer, void *data) {
return NUM_MENU_SECTIONS;
}
// Each section has a number of items; we use a callback to specify this
// You can also dynamically add and remove items using this
static uint16_t menu_get_num_rows_callback(MenuLayer *menu_layer, uint16_t section_index, void *data) {
switch (section_index) {
case 0:
return NUM_FIRST_MENU_ITEMS;
case 1:
return NUM_SECOND_MENU_ITEMS;
default:
return 0;
}
}
// A callback is used to specify the height of the section header
static int16_t menu_get_header_height_callback(MenuLayer *menu_layer, uint16_t section_index, void *data) {
// This is a define provided in pebble.h that you may use for the default height
return MENU_CELL_BASIC_HEADER_HEIGHT;
}
// Here we draw what each header is
static void menu_draw_header_callback(GContext* ctx, const Layer *cell_layer, uint16_t section_index, void *data) {
// Determine which section we're working with
switch (section_index) {
case 0:
// Draw title text in the section header
menu_cell_basic_header_draw(ctx, cell_layer, "Some example items");
break;
case 1:
menu_cell_basic_header_draw(ctx, cell_layer, "One more");
break;
}
}
// This is the menu item draw callback where you specify what each item should look like
static void menu_draw_row_callback(GContext* ctx, const Layer *cell_layer, MenuIndex *cell_index, void *data) {
// Determine which section we're going to draw in
switch (cell_index->section) {
case 0:
// Use the row to specify which item we'll draw
switch (cell_index->row) {
case 0:
// This is a basic menu item with a title and subtitle
menu_cell_basic_draw(ctx, cell_layer, "Basic Item", "With a subtitle", NULL);
break;
case 1:
// This is a basic menu icon with a cycling icon
menu_cell_basic_draw(ctx, cell_layer, "Icon Item", "Select to cycle", menu_icons[current_icon]);
break;
case 2:
// Here we use the graphics context to draw something different
// In this case, we show a strip of a watchface's background
graphics_draw_bitmap_in_rect(ctx, menu_background,
(GRect){ .origin = GPointZero, .size = layer_get_frame((Layer*) cell_layer).size });
break;
}
break;
case 1:
switch (cell_index->row) {
case 0:
// There is title draw for something more simple than a basic menu item
menu_cell_title_draw(ctx, cell_layer, "Final Item");
break;
}
}
}
// Here we capture when a user selects a menu item
void menu_select_callback(MenuLayer *menu_layer, MenuIndex *cell_index, void *data) {
// Use the row to specify which item will receive the select action
switch (cell_index->row) {
// This is the menu item with the cycling icon
case 1:
// Cycle the icon
current_icon = (current_icon + 1) % NUM_MENU_ICONS;
// After changing the icon, mark the layer to have it updated
layer_mark_dirty(menu_layer_get_layer(menu_layer));
break;
}
}
// This initializes the menu upon window load
void window_load(Window *window) {
// Here we load the bitmap assets
// resource_init_current_app must be called before all asset loading
int num_menu_icons = 0;
menu_icons[num_menu_icons++] = gbitmap_create_with_resource(RESOURCE_ID_IMAGE_MENU_ICON_BIG_WATCH);
menu_icons[num_menu_icons++] = gbitmap_create_with_resource(RESOURCE_ID_IMAGE_MENU_ICON_SECTOR_WATCH);
menu_icons[num_menu_icons++] = gbitmap_create_with_resource(RESOURCE_ID_IMAGE_MENU_ICON_BINARY_WATCH);
// And also load the background
menu_background = gbitmap_create_with_resource(RESOURCE_ID_IMAGE_BACKGROUND_BRAINS);
// Now we prepare to initialize the menu layer
// We need the bounds to specify the menu layer's viewport size
// In this case, it'll be the same as the window's
Layer *window_layer = window_get_root_layer(window);
GRect bounds = layer_get_frame(window_layer);
// Create the menu layer
menu_layer = menu_layer_create(bounds);
// Set all the callbacks for the menu layer
menu_layer_set_callbacks(menu_layer, NULL, (MenuLayerCallbacks){
.get_num_sections = menu_get_num_sections_callback,
.get_num_rows = menu_get_num_rows_callback,
.get_header_height = menu_get_header_height_callback,
.draw_header = menu_draw_header_callback,
.draw_row = menu_draw_row_callback,
.select_click = menu_select_callback,
});
// Bind the menu layer's click config provider to the window for interactivity
menu_layer_set_click_config_onto_window(menu_layer, window);
// Add it to the window for display
layer_add_child(window_layer, menu_layer_get_layer(menu_layer));
}
void window_unload(Window *window) {
// Destroy the menu layer
menu_layer_destroy(menu_layer);
// Cleanup the menu icons
for (int i = 0; i < NUM_MENU_ICONS; i++) {
gbitmap_destroy(menu_icons[i]);
}
// And cleanup the background
gbitmap_destroy(menu_background);
}
int main(void) {
window = window_create();
// Setup the window handlers
window_set_window_handlers(window, (WindowHandlers) {
.load = window_load,
.unload = window_unload,
});
window_stack_push(window, true /* Animated */);
app_event_loop();
window_destroy(window);
}