Skip to content

Commit e59ae3c

Browse files
committed
Test and update C tutorial part 2
Signed-off-by: C-D-Lewis <[email protected]>
1 parent d54ed3d commit e59ae3c

File tree

2 files changed

+149
-28
lines changed

2 files changed

+149
-28
lines changed

source/tutorials/watchface-tutorial/part1.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,6 @@ static void tick_handler(struct tm *tick_time, TimeUnits units_changed) {
484484
update_time();
485485
}
486486

487-
488487
static void init() {
489488
// Create main Window element and assign to pointer
490489
s_main_window = window_create();

source/tutorials/watchface-tutorial/part2.md

Lines changed: 149 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -77,23 +77,26 @@ Let's improve it!
7777

7878
App resources (fonts and images etc.) are managed in the `package.json`
7979
file in the project's root directory, as detailed in
80-
[*App Resources*](/guides/app-resources/). All image files and fonts must
81-
reside in subfolders of the `/resources` folder of your project. Below is an
82-
example entry in the `media` array:
80+
[*App Resources*](/guides/app-resources/). Below is an example entry in the
81+
`resources` section:
8382

8483
```json
85-
"media": [
86-
{
87-
"type": "font",
88-
"name": "FONT_PERFECT_DOS_48",
89-
"file": "fonts/perfect-dos-vga.ttf",
90-
"compatibility":"2.7"
91-
}
92-
]
84+
"resources": {
85+
"media": [
86+
{
87+
"type": "font",
88+
"name": "FONT_PERFECT_DOS_48",
89+
"file": "fonts/perfect-dos-vga.ttf",
90+
"compatibility":"2.7"
91+
}
92+
]
93+
}
9394
```
9495

95-
In the example above, we would place our `perfect-dos-vga.ttf` file in the
96-
`/resources/fonts/` folder of our project.
96+
All image files and fonts must reside in subfolders of the `/resources` folder
97+
of your project. In the example above, we would place our `perfect-dos-vga.ttf`
98+
file in the `/resources/fonts/` folder of our project. So, create this if it
99+
doesn't already exist.
97100

98101
A custom font file must be a
99102
[TrueType](http://en.wikipedia.org/wiki/TrueType) font in the `.ttf` file format.
@@ -103,7 +106,8 @@ A custom font file must be a
103106
Now we will substitute the system font used before (`FONT_KEY_BITHAM_42_BOLD`)
104107
for our newly imported one.
105108

106-
To do this, we will declare a ``GFont`` globally.
109+
To do this, we will declare a ``GFont`` globally near the top of the source
110+
file.
107111

108112
```c
109113
// Declare globally
@@ -121,7 +125,7 @@ void main_window_load() {
121125
// Create GFont
122126
s_time_font = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_PERFECT_DOS_48));
123127

124-
// Apply to TextLayer
128+
// Apply custom font to TextLayer
125129
text_layer_set_font(s_time_layer, s_time_font);
126130
// ...
127131
}
@@ -157,11 +161,12 @@ An example screenshot is shown below:
157161

158162
## Adding a Bitmap
159163

160-
The Pebble SDK also allows you to use a 2-color (black and white) bitmap image
161-
in your watchface project. You can ensure that you meet this requirement by
162-
checking the export settings in your graphics package, or by purely using only
163-
white (`#FFFFFF`) and black (`#000000`) in the image's creation. Another
164-
alternative is to use a dithering tool such as
164+
The Pebble SDK also allows you to use images in your project and handles the
165+
process of preparing them for the watch. In this tutorial we will use a 2-color
166+
(black and white) bitmap image as an example. You can ensure that you meet this
167+
requirement by checking the export settings in your graphics package, or by
168+
purely using only white (`#FFFFFF`) and black (`#000000`) in the image's
169+
creation. Another alternative is to use a dithering tool such as
165170
[HyperDither](http://2002-2010.tinrocket.com/software/hyperdither/index.html).
166171
This will be loaded from the watchface's resources into a ``GBitmap`` data
167172
structure before being displayed using a ``BitmapLayer`` element. These two
@@ -181,7 +186,7 @@ object will have a `type` of `bitmap`. Below is an example:
181186
```
182187

183188
As before, here is an example bitmap we have created for you to use, which looks
184-
like this:
189+
as shown below. Be sure to save it to a `resources/images` directory.
185190

186191
[![background](/images/getting-started/watchface-tutorial/background.png "background")]({{ site.asset_path }}/images/getting-started/watchface-tutorial/background.png)
187192

@@ -219,17 +224,18 @@ As always, the final step should be to ensure we free up the memory consumed by
219224
these new elements in `main_window_unload()`:
220225
221226
```c
222-
// Destroy GBitmap
223-
gbitmap_destroy(s_background_bitmap);
224-
225227
// Destroy BitmapLayer
226228
bitmap_layer_destroy(s_background_layer);
229+
230+
// Destroy GBitmap
231+
gbitmap_destroy(s_background_bitmap);
227232
```
228233

229234
The final step is to set the background color of the main ``Window`` to match
230-
the background image. Do this in `init()`:
235+
the background image. Do this in `init()` after `window_create()`:
231236

232237
```c
238+
// Change the background color
233239
window_set_background_color(s_main_window, GColorBlack);
234240
```
235241
@@ -259,9 +265,125 @@ the same way as the time display one to show the current date (hint: look at the
259265
available for `strftime()`!)
260266
261267
As with last time, you can compare your own code to the example source code
262-
using the button below.
268+
provided below.
269+
270+
<details>
271+
<summary>View source code</summary>
272+
{% markdown %}
273+
```c
274+
#include <pebble.h>
275+
276+
static Window *s_main_window;
277+
static TextLayer *s_time_layer;
278+
static BitmapLayer *s_background_layer;
279+
280+
static GFont s_time_font;
281+
static GBitmap *s_background_bitmap;
282+
283+
static void update_time() {
284+
// Get a tm structure
285+
time_t temp = time(NULL);
286+
struct tm *tick_time = localtime(&temp);
287+
288+
// Write the current hours and minutes into a buffer
289+
static char s_buffer[8];
290+
strftime(s_buffer, sizeof(s_buffer), clock_is_24h_style() ?
291+
"%H:%M" : "%I:%M", tick_time);
292+
293+
// Display this time on the TextLayer
294+
text_layer_set_text(s_time_layer, s_buffer);
295+
}
296+
297+
static void main_window_load(Window *window) {
298+
// Get information about the Window
299+
Layer *window_layer = window_get_root_layer(window);
300+
GRect bounds = layer_get_bounds(window_layer);
301+
302+
// Create GBitmap
303+
s_background_bitmap = gbitmap_create_with_resource(RESOURCE_ID_IMAGE_BACKGROUND);
304+
305+
// Create BitmapLayer to display the GBitmap
306+
s_background_layer = bitmap_layer_create(bounds);
307+
308+
// Set the bitmap onto the layer and add to the window
309+
bitmap_layer_set_bitmap(s_background_layer, s_background_bitmap);
310+
layer_add_child(window_layer, bitmap_layer_get_layer(s_background_layer));
311+
312+
// Create GFont
313+
s_time_font = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_PERFECT_DOS_48));
263314
264-
[View Source Code >{center,bg-lightblue,fg-white}](https://gist.github.com/d216d9e0b840ed296539)
315+
// Create the TextLayer with specific bounds
316+
s_time_layer = text_layer_create(
317+
GRect(0, PBL_IF_ROUND_ELSE(58, 52), bounds.size.w, 50));
318+
319+
// Improve the layout to be more like a watchface
320+
text_layer_set_background_color(s_time_layer, GColorClear);
321+
text_layer_set_text_color(s_time_layer, GColorBlack);
322+
text_layer_set_text(s_time_layer, "00:00");
323+
text_layer_set_font(s_time_layer, fonts_get_system_font(FONT_KEY_BITHAM_42_BOLD));
324+
text_layer_set_text_alignment(s_time_layer, GTextAlignmentCenter);
325+
326+
// Apply custom font to TextLayer
327+
text_layer_set_font(s_time_layer, s_time_font);
328+
329+
// Add it as a child layer to the Window's root layer
330+
layer_add_child(window_layer, text_layer_get_layer(s_time_layer));
331+
}
332+
333+
static void main_window_unload(Window *window) {
334+
// Destroy TextLayer
335+
text_layer_destroy(s_time_layer);
336+
337+
// Unload GFont
338+
fonts_unload_custom_font(s_time_font);
339+
340+
// Destroy BitmapLayer
341+
bitmap_layer_destroy(s_background_layer);
342+
343+
// Destroy GBitmap
344+
gbitmap_destroy(s_background_bitmap);
345+
}
346+
347+
static void tick_handler(struct tm *tick_time, TimeUnits units_changed) {
348+
update_time();
349+
}
350+
351+
static void init() {
352+
// Create main Window element and assign to pointer
353+
s_main_window = window_create();
354+
355+
// Change the background color
356+
window_set_background_color(s_main_window, GColorBlack);
357+
358+
// Set handlers to manage the elements inside the Window
359+
window_set_window_handlers(s_main_window, (WindowHandlers) {
360+
.load = main_window_load,
361+
.unload = main_window_unload
362+
});
363+
364+
// Show the Window on the watch, with animated=true
365+
window_stack_push(s_main_window, true);
366+
367+
// Register with TickTimerService
368+
tick_timer_service_subscribe(MINUTE_UNIT, tick_handler);
369+
370+
// Make sure the time is displayed from the start
371+
update_time();
372+
}
373+
374+
static void deinit() {
375+
// Destroy Window
376+
window_destroy(s_main_window);
377+
}
378+
379+
int main(void) {
380+
init();
381+
app_event_loop();
382+
deinit();
383+
}
384+
```
385+
{% endmarkdown %}
386+
</details>
265387

266388

267389
## What's Next?

0 commit comments

Comments
 (0)