@@ -77,23 +77,26 @@ Let's improve it!
7777
7878App resources (fonts and images etc.) are managed in the ` package.json `
7979file 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
98101A 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
103106Now we will substitute the system font used before (` FONT_KEY_BITHAM_42_BOLD ` )
104107for 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 ) .
166171This will be loaded from the watchface's resources into a `` GBitmap `` data
167172structure 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
183188As 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
219224these new elements in `main_window_unload()`:
220225
221226```c
222- // Destroy GBitmap
223- gbitmap_destroy(s_background_bitmap);
224-
225227// Destroy BitmapLayer
226228bitmap_layer_destroy(s_background_layer);
229+
230+ // Destroy GBitmap
231+ gbitmap_destroy(s_background_bitmap);
227232```
228233
229234The 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
233239window_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
259265available for `strftime()`!)
260266
261267As 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