2015 Pebble Developer Retreat
Developing for Round
Heiko Behrens, WTF Engineer
#PDR15 - Developing for Round
Chalk
the 3rd
Pebble platform
Pebble SDK
Aplite
2.x ✅
Pebble SDK
Aplite Basalt
2.x ✅
3.0 ❌ ✅
Pebble SDK
Aplite Basalt Chalk
2.x ✅
3.0 ❌ ✅
3.6 ❌ ✅
Pebble SDK
Aplite Basalt Chalk
2.x ✅
3.0 ❌ ✅
3.6 ❌ ✅
3.x ✅
Unified 3.x SDK later this year
Aplite Basalt Chalk
CPU
24k

ARM Cortex M3
64k
ARM Cortex M4
Resolution
144x168px

(Rectangular)
180x180
(Circular)
Color black & white 64 Colors
SmartStrap ❌ ✅
Mic ❌ ✅
Hardware
runs on
2.x 3.x
Aplite Basalt
2.x Aplite ✅ ✅
3.x Basalt ❌ ✅
Compatibility
compiledagainst
2.x Aplite runs
on 3.x Basalt
runs on
2.x 3.x
Aplite Aplite Basalt Chalk
2.x Aplite ✅ ✅ ✅ ❌
3.x
Aplite ❌ ✅ ❌ ❌
Basalt ❌ ❌ ✅ ❌
Chalk ❌ ❌ ❌ ✅
Compatibility
compiledagainst
3.x apps
are compiled
per platform
Friday: Kevin talks about multi-platform
Agenda
• Uniform APIs across all platforms
• New support for text flow
• New routines for drawing round
• Improvements of existing APIs
Pebble Emulator
$ pebble build
$ pebble install --emulator chalk
Graphics
Friday: Matt talks about graphics
Timeline
Friday: Jon talks about Timeline
Action Menu
Smartstraps
Friday: Brian talks about Smartstraps
Dictation Service
Friday: Andrew talks about Dictation Service
Text Flow
• Uniform APIs across all platforms
• New support for text flow
• New routines for drawing round
• Improvements of existing APIs
naïve text flow
naïve text flow
naïve text flow
#PDR15 - Developing for Round
#PDR15 - Developing for Round
facilisis egestas.
Proin vitae arcu
ac diam viverra
aliquet. Nunc
gravida libero
130px
120px
facilisis
egestas. Proin
vitae arcu ac diam
viverra aliquet. Nunc
gravida libero nec
massa rutrum, vel
ultriciesenim
180px
180px
facilisis
egestas. Proin
vitae arcu ac diam
viverra aliquet. Nunc
gravida libero nec
massa rutrum, vel
ultriciesenim
(0,0)
(179,179)
facilisis
egestas. Proin
vitae arcu ac diam
viverra aliquet. Nunc
gravida libero nec
massa rutrum, vel
ultriciesenim
(0,0)
(179,179)
Layer *window_layer = window_get_root_layer(

window);

GRect window_bounds = layer_get_bounds(

window_layer);

// window’s bounds are
// GRect(0, 0, 180, 180) (0,0)
(179,179)
window coordinates on Chalk
facilisis egestas. Proin
vitae arcu ac diam
viverra aliquet. Nunc
gravida libero nec massa
rutrum, vel ultriciesenim
tristique. Nam magna
enim, ullamcorper nec
tellus vel, accumsan.
(0,0)
(179,179)
facilisis egestas. Proin
vitae arcu ac diam
viverra aliquet. Nunc
gravida libero nec massa
rutrum, vel ultriciesenim
tristique. Nam magna
enim, ullamcorper nec
tellus vel, accumsan.
(0,0)
(179,179)
s_text_layer = text_layer_create(window_bounds);

layer_add_child(

window_layer, text_layer_get_layer(s_text_layer));



text_layer_set_text(s_text_layer, s_text);

text_layer_set_background_color(

s_text_layer, GColorBlueMoon);
TextLayer
facilisis egestas. Proin
vitae arcu ac diam
viverra aliquet. Nunc
gravida libero nec massa
rutrum, vel ultriciesenim
tristique. Nam magna
enim, ullamcorper nec
tellus vel, accumsan.
(0,0)
(179,179)
facilisis egestas. Proin
vitae arcu ac diam
viverra aliquet. Nunc
gravida libero nec massa
rutrum, vel ultriciesenim
tristique. Nam magna
enim, ullamcorper nec
tellus vel, accumsan.
(0,0)
(179,179)
s_text_layer = text_layer_create(window_bounds);

layer_add_child(

window_layer, text_layer_get_layer(s_text_layer));



text_layer_set_text(s_text_layer, s_text);

text_layer_set_background_color(

s_text_layer, GColorBlueMoon);



text_layer_set_text_alignment(

s_text_layer, GTextAlignmentCenter);
TextLayer
s_text_layer = text_layer_create(window_bounds);

layer_add_child(

window_layer, text_layer_get_layer(s_text_layer));



text_layer_set_text(s_text_layer, s_text);

text_layer_set_background_color(

s_text_layer, GColorBlueMoon);



text_layer_set_text_alignment(

s_text_layer, GTextAlignmentCenter);



uint8_t inset = 10;

text_layer_enable_screen_text_flow_and_paging(

s_text_layer, inset);
facilisis
egestas. Proin
vitae arcu ac diam
viverra aliquet. Nunc
gravida libero nec
massa rutrum, vel
ultriciesenim
(0,0)
(179,179)
facilisis
egestas. Proin
vitae arcu ac diam
viverra aliquet. Nunc
gravida libero nec
massa rutrum, vel
ultriciesenim
(0,0)
(179,179)
10px 10px
10px
10px
TextLayer
#PDR15 - Developing for Round
GTextAttributes
GTextAttributes *attributes = graphics_text_attributes_create();
graphics_text_attributes_enable_screen_text_flow(attributes, 8);


graphics_draw_text(ctx, s_text, ..., attributes);

GSize size = graphics_text_layout_get_content_size_with_attributes(s_text, ..., attributes);

graphics_text_attributes_destroy(attributes);
graphics_draw_text(ctx, s_text, ..., NULL);
Before SDK 3.6: last argument was always NULL
GTextAttributes for extended control when drawing/measuring text
Drawing Round
• Uniform APIs across all platforms
• New support for text flow
• New routines for drawing round
• Improvements of existing APIs
#PDR15 - Developing for Round
const GRect bounds = GRect(0, 0, 10, 10);
const GRect r = GRect(1, 1, 8, 3);

graphics_fill_rect(ctx, r, 0, GCornerNone);
p0
p1
const GRect r = GRect(1, 1, 8, 3);
graphics_fill_rect(ctx, r, 0, GCornerNone);
const GPoint p0 = GPoint(1, 1);

const GPoint p1 = GPoint(8, 3);

graphics_draw_line(ctx, p0, p1);
p0
p1
const GRect r = GRect(1, 1, 8, 3);
graphics_fill_rect(ctx, r, 0, GCornerNone);
const GPoint p0 = GPoint(1, 1);

const GPoint p1 = GPoint(8, 3);

graphics_draw_line(ctx, p0, p1);
const GRect r = GRect(1, 1, 8, 3);
graphics_fill_rect(ctx, r, 0, GCornerNone);
const GPoint p0 = GPoint(1, 1);

const GPoint p1 = GPoint(8, 3);

graphics_draw_line(ctx, p0, p1);
const p_max = GPoint(r.origin.x + r.size.w,

r.origin.y + r.size.h);
p0
p1
pmax
// (9, 4) ?!
r0 = GRect(1, 1, 8, 3);

p0 = GPoint(1, 1);

p1 = GPoint(8, 3);
p0
p1
p2
p3
r1 = GRect(1, 2, 8, 6);

p2 = GPoint(1, 2);

p3 = GPoint(8, 7);
//(2 * 1, 2 * 3)
// 2 * 1
// 2 * 3 + 1 ?!7
2
62
center_a = GPoint(?, ?);

radius_a = ?;

graphics_fill_circle(ctx,

center_a,

radius_a

);
center_a = GPoint(?, ?);

radius_a = ?;

graphics_fill_circle(ctx,

center_a,

radius_a

);
center_a = GPoint(3, 3);

radius_a = 2;

graphics_fill_circle(ctx,

center_a,

radius_a

);
centera
radiusa
center_a = GPoint(3, 3);

radius_a = 2;

graphics_fill_circle(ctx,

center_a,

radius_a

);
centera
radiusa
centera
radiusb
center_b = GPoint(4.5, 4.5);

radius_b = 3.5;

graphics_fill_circle(ctx,

center_b,

radius_b

);
no
floating point
values in our APIs
rect_a = GRect(1, 1, 5, 5);

somehow_fill_circle_inside(
ctx, rect_a

);
rect_b = GRect(1, 1, 8, 8);

somehow_fill_circle_inside(
ctx, rect_b

);
void graphics_fill_radial(
GContext *ctx, 

GRect rect, 

GOvalScaleMode scale_mode,

uint16_t inset_thickness,

int32_t angle_start, 

int32_t angle_end
);
void graphics_draw_arc(

GContext *ctx,

GRect rect,

GOvalScaleMode scale_mode,



int32_t angle_start,

int32_t angle_end
);
new drawing APIs
angle_end
inset
draw_arc & stroke_width
angle_start & angle_end
GOvalScaleModeFitCircle
GOvalScaleModeFillCircle
GPoint gpoint_from_polar(GRect rect,
GOvalScaleMode scale_mode,
int32_t angle);
GRect grect_centered_from_polar(GRect rect, 

GOvalScaleMode scale_mode,
int32_t angle,
GSize size);
GRect grect_inset(GRect rect,

GEdgeInsets insets);
new geometry APIs
gpoint_from_polar
grect_centered_from_polar
grect_inset & GEdgeInsets
GRect a = grect_inset(r, GEdgeInsets(16)); // all sides
GRect b = grect_inset(r, GEdgeInsets(25, 16)); // top & bottom, right & left
GRect c = grect_inset(r, GEdgeInsets(25, 16, 10)); // top, right & left, bottom
GRect c = grect_inset(r, GEdgeInsets(25, -20, 10, 16)); // top, right, bottom, left
a b
c d
16px
16px
25px 25px 25px
25px
10px 10px
16px 16px 16px 16px16px 16px 16px 20px
Friday: Kevin talks about multi-platform
#PDR15 - Developing for Round
Drawing Round
• Uniform APIs across all platforms
• New support for text flow
• New routines for drawing round
• Improvements of existing APIs
#PDR15 - Developing for Round
#PDR15 - Developing for Round
Display
2px
Bezelpotential
view
ing
angle
StatusBar
StatusBar
StatusBar
s_status_bar = status_bar_layer_create();

GRect status_bar_rect = window_bounds;

status_bar_rect.size.h = STATUS_BAR_LAYER_HEIGHT;

layer_set_frame(
status_bar_layer_get_layer(s_status_bar),

status_bar_rect);



// top/bottom: statusbar, left/right: 0
GEdgeInsets insets = GEdgeInsets(
STATUS_BAR_LAYER_HEIGHT, 0);
GRect menu_layer_rect = grect_inset(
window_bounds, insets);
ActionBar
ActionBar
ActionBar
s_action_bar = action_bar_layer_create();

action_bar_layer_add_to_window(
s_action_bar, window);



// top: statusbar, right: actionbar, bottom/left:0
GEdgeInsets insets = GEdgeInsets(

STATUS_BAR_LAYER_HEIGHT, ACTION_BAR_WIDTH, 0, 0);

GRect content_rect = grect_inset(
window_bounds, insets);
MenuLayer
MENU_CELL_ROUND_UNFOCUSED_SHORT_CELL_HEIGHT
MENU_CELL_ROUND_FOCUSED_TALL_CELL_HEIGHT

MENU_CELL_ROUND_UNFOCUSED_SHORT_CELL_HEIGHT
MENU_CELL_ROUND_UNFOCUSED_TALL_CELL_HEIGHT
MENU_CELL_ROUND_FOCUSED_SHORT_CELL_HEIGHT
MENU_CELL_ROUND_UNFOCUSED_TALL_CELL_HEIGHT
MENU_CELL_BASIC_CELL_HEIGHT
MENU_CELL_BASIC_CELL_HEIGHT
MENU_CELL_BASIC_CELL_HEIGHT
Standard Cell Heights
// default on Chalk
menu_layer_set_center_focused(menu_layer, true);
static int16_t get_cell_height_callback(
MenuLayer *menu_layer, MenuIndex *cell_index,

void *callback_context) {

// when center_focused, MenuLayer can handle cell heights
// that change based on the selection status
if (menu_layer_is_index_selected(menu_layer, cell_index)) {

return MENU_CELL_ROUND_FOCUSED_TALL_CELL_HEIGHT;

} else {

return MENU_CELL_ROUND_UNFOCUSED_SHORT_CELL_HEIGHT;

}

}

GBitmapFormat8BitCircular
144px
168px
180px 180px
180px 1Rect Round Square
Rect Round Square
Visible Pixels 24,192 25,792 32,400
Δ Rect 1,600 (+7%) 8,208 (+34%)
Δ Round 6,608 (+26%)
144px
168px
180px 180px
180px 180pxRect Round Square
0 1 2 3
7 8 9 106 11
13 14 15 1612 17
19 20 21 2218 23
25 26 27 2824 29
31 32 33 3430 35
37 38 39 4036 41
43 44 45 46
4
42 47
5
GBitmap pixel data
int offset = y * bytes_per_row + x;
0 1 2 3
5 6 7 84 9
12 13 14 1511 1610 17
20 21 22 2319 2418 25
28 29 30 3127 3226 33
36 37 38 3935 4034 41
43 44 45 4642 47
48 49 50 51
0 1 2 3
7 8 9 106 11
13 14 15 1612 17
19 20 21 2218 23
25 26 27 2824 29
31 32 33 3430 35
37 38 39 4036 41
43 44 45 46
4
42 47
5
GBitmap pixel data
0 1 2 3
5 6 7 84 9
12 13 14 1511 1610 17
20 21 22 2319 2418 25
28 29 30 3127 3226 33
36 37 38 3935 4034 41
43 44 45 4642 47
48 49 50 51
data min_x max_x
-2 2 5
3 1 6
10 0 7
18 0 7
26 0 7
34 0 7
41 1 6
46 2 5
41
46 47
3
-2 -1
52 53
0 1 2 3
7 8 9 106 11
13 14 15 1612 17
19 20 21 2218 23
25 26 27 2824 29
31 32 33 3430 35
37 38 39 4036 41
43 44 45 46
4
42 47
5
gbitmap_get_data_row_info
uint16_t bytes_per_row =
gbitmap_get_bytes_per_row(fb);

uint8_t *pixel_data =
gbitmap_get_data(fb);


uint8_t *pixel =
pixel_data + y * bytes_per_row + x;
GBitmapDataRowInfo row_info =
gbitmap_get_data_row_info(fb, y);

uint8_t *pixel = row_info.data + x;
rectangular only general approach
• pointer retrieval
• offset calculaton
• horizontal boundary checks
GBitmap *fb = graphics_capture_frame_buffer(ctx);

GSize size = gbitmap_get_bounds(fb).size;



uint16_t bytes_per_row =
gbitmap_get_bytes_per_row(fb);

uint8_t *pixel_data = gbitmap_get_data(fb);

for (uint16_t y = 0; y < size.h; y++) {

uint8_t *pixel = pixel_data + y * bytes_per_row;

for (uint16_t x = 0; x < size.w; x++) {

*pixel = some_color.argb;

pixel++;

}

}

GBitmap *fb = graphics_capture_frame_buffer(ctx);

GSize size = gbitmap_get_bounds(fb).size;

for (uint16_t y = 0; y < size.h; y++) {

GBitmapDataRowInfo row_info =
gbitmap_get_data_row_info(fb, y);

uint8_t *pixel = row_info.data + row_info.min_x;

for (int16_t x = row_info.min_x; x <= row_info.max_x; x++) {

*pixel = some_color.argb;

pixel++;

}

}

Aplite Basalt Chalk
Resolution
144x168px

(Rectangular)
180x180
(Circular)
Color b/w 64 Colors
PBL_IF_RECT_ELSE("rect", "otherwise");

PBL_IF_ROUND_ELSE("round", "otherwise");

PBL_IF_COLOR_ELSE("color", "otherwise");

PBL_IF_BW_ELSE("bw", "otherwise");
file~rect.png

file~round.png

file~color.png

file~bw.png
#defines
#resources
Feature Selection
Friday: Kevin talks about multi-platform
iOS
Starting with Chalk, you
need to compile with
PebbleKit iOS 3.0
Since PebbleOS 3.0,
you need to compile
with PebbleKit Android
3.0
Android
Friday: Marcel talks about PebbleKit iOS
Pebble SDK
• Uniform APIs across all platforms
• New support for text flow
• New routines for drawing round
• Improvements of existing APIs
Questions?

More Related Content

PDF
Advanced Techniques: Graphics | Pebble Developer Retreat 2014
PDF
Overlay Technique | Pebble Developer Retreat 2014
PDF
#PDR15 Creating Pebble Apps for Aplite, Basalt, and Chalk
PDF
Phil Bartie QGIS PLPython
PDF
Fun with click house window functions webinar slides 2021-08-19
PDF
EGL 1.4 Reference Card
PPTX
Seminar PSU 09.04.2013 - 10.04.2013 MiFIT, Arbuzov Vyacheslav
PPT
Circles graphic
Advanced Techniques: Graphics | Pebble Developer Retreat 2014
Overlay Technique | Pebble Developer Retreat 2014
#PDR15 Creating Pebble Apps for Aplite, Basalt, and Chalk
Phil Bartie QGIS PLPython
Fun with click house window functions webinar slides 2021-08-19
EGL 1.4 Reference Card
Seminar PSU 09.04.2013 - 10.04.2013 MiFIT, Arbuzov Vyacheslav
Circles graphic

What's hot (20)

PDF
C++ Programs
PDF
OpenVG 1.1 Reference Card
PDF
Go. why it goes v2
PPTX
Penn graphics
PDF
Spark 4th Meetup Londond - Building a Product with Spark
PDF
PDF
Functional C++
DOCX
Computer graphics
PDF
Byterun, a Python bytecode interpreter - Allison Kaptur at NYCPython
PDF
Faster persistent data structures through hashing
PDF
Whats new in ES2019
PDF
Diving into HHVM Extensions (Brno PHP Conference 2015)
PPT
Python (1)
PDF
Transition graph using free monads and existentials
PDF
81818088 isc-class-xii-computer-science-project-java-programs
PPTX
Story of static code analyzer development
PDF
OpenVX 1.1 Reference Guide
PPTX
TCO in Python via bytecode manipulation.
PPTX
Reproducible Computational Research in R
PPTX
Project gnuplot
C++ Programs
OpenVG 1.1 Reference Card
Go. why it goes v2
Penn graphics
Spark 4th Meetup Londond - Building a Product with Spark
Functional C++
Computer graphics
Byterun, a Python bytecode interpreter - Allison Kaptur at NYCPython
Faster persistent data structures through hashing
Whats new in ES2019
Diving into HHVM Extensions (Brno PHP Conference 2015)
Python (1)
Transition graph using free monads and existentials
81818088 isc-class-xii-computer-science-project-java-programs
Story of static code analyzer development
OpenVX 1.1 Reference Guide
TCO in Python via bytecode manipulation.
Reproducible Computational Research in R
Project gnuplot
Ad

Similar to #PDR15 - Developing for Round (20)

PDF
Pebble NYC Meetup Pebble Time Round and the Chalk SDK
PPTX
pebble - Building apps on pebble
PDF
SVGo: a Go Library for SVG generation
ODP
Creating masterpieces with raphael
KEY
Getting Started with CoreGraphics
PDF
SVGo workshop
KEY
Processing presentation
PDF
The Ring programming language version 1.5.4 book - Part 60 of 185
PDF
Chameleon game engine
PPTX
Fill area algorithm on computer graphics course
PPTX
Ogdc 2013 lets remake the wheel
PPTX
OGDC2013_Lets remake the wheel_ Mr Nguyen Trung Hung
PPT
Some examples of shapes are Lines, Polygons, Axes, and Text
PDF
[1D6]RE-view of Android L developer PRE-view
KEY
Proga 0706
PDF
Slides mihail-ivanchev-1
PPTX
ACM Mid-Southeast Slides
PDF
Programming methodology lecture11
PPT
JavaYDL13
PDF
The Ring programming language version 1.9 book - Part 171 of 210
Pebble NYC Meetup Pebble Time Round and the Chalk SDK
pebble - Building apps on pebble
SVGo: a Go Library for SVG generation
Creating masterpieces with raphael
Getting Started with CoreGraphics
SVGo workshop
Processing presentation
The Ring programming language version 1.5.4 book - Part 60 of 185
Chameleon game engine
Fill area algorithm on computer graphics course
Ogdc 2013 lets remake the wheel
OGDC2013_Lets remake the wheel_ Mr Nguyen Trung Hung
Some examples of shapes are Lines, Polygons, Axes, and Text
[1D6]RE-view of Android L developer PRE-view
Proga 0706
Slides mihail-ivanchev-1
ACM Mid-Southeast Slides
Programming methodology lecture11
JavaYDL13
The Ring programming language version 1.9 book - Part 171 of 210
Ad

More from Pebble Technology (19)

PDF
#PDR15 - Awesome Appstore Assets
PDF
#PDR15 - Smartstrap Workshop
PDF
#PDR15 - Data Analytics and Pebble
PDF
#PDR15 - Best Use Cases For Timeline
PDF
#PDR15 - waf, wscript and Your Pebble App
PDF
#PDR15 - PebbleKit iOS 3.0
PDF
#PDR15 - Voice API
PDF
#PDR15 - Pebble Graphics
PDF
#PDR15 - Designing for Pebble
PDF
#PDR15 Kick-Off
PDF
Pebble Slate Workshop
PDF
Overlay & Libraries | Pebble Meetup Oct. 2014
PDF
Connecting Pebble to the World
PDF
Guest Presentation - Strap | Pebble Developer Retreat 2014
PDF
Battery Life | Pebble Developer Retreat 2014
PDF
Thomas Sarlandie Kickoff Talk | Pebble Developer Retreat 2014
PDF
Advanced Techniques: Size | Pebble Developer Retreat 2014
PDF
Pebble wearables devcon
PDF
Announcing Pebble SDK 2.0
#PDR15 - Awesome Appstore Assets
#PDR15 - Smartstrap Workshop
#PDR15 - Data Analytics and Pebble
#PDR15 - Best Use Cases For Timeline
#PDR15 - waf, wscript and Your Pebble App
#PDR15 - PebbleKit iOS 3.0
#PDR15 - Voice API
#PDR15 - Pebble Graphics
#PDR15 - Designing for Pebble
#PDR15 Kick-Off
Pebble Slate Workshop
Overlay & Libraries | Pebble Meetup Oct. 2014
Connecting Pebble to the World
Guest Presentation - Strap | Pebble Developer Retreat 2014
Battery Life | Pebble Developer Retreat 2014
Thomas Sarlandie Kickoff Talk | Pebble Developer Retreat 2014
Advanced Techniques: Size | Pebble Developer Retreat 2014
Pebble wearables devcon
Announcing Pebble SDK 2.0

Recently uploaded (20)

PPTX
Chapter 5: Probability Theory and Statistics
DOCX
search engine optimization ppt fir known well about this
PDF
Unlock new opportunities with location data.pdf
PPT
Module 1.ppt Iot fundamentals and Architecture
PDF
A Late Bloomer's Guide to GenAI: Ethics, Bias, and Effective Prompting - Boha...
PDF
Transform Your ITIL® 4 & ITSM Strategy with AI in 2025.pdf
PPTX
Benefits of Physical activity for teenagers.pptx
PPTX
MicrosoftCybserSecurityReferenceArchitecture-April-2025.pptx
PDF
NewMind AI Weekly Chronicles – August ’25 Week III
PDF
TrustArc Webinar - Click, Consent, Trust: Winning the Privacy Game
PDF
How ambidextrous entrepreneurial leaders react to the artificial intelligence...
PPT
What is a Computer? Input Devices /output devices
PPTX
Modernising the Digital Integration Hub
PDF
Hybrid horned lizard optimization algorithm-aquila optimizer for DC motor
PDF
Taming the Chaos: How to Turn Unstructured Data into Decisions
PDF
A comparative study of natural language inference in Swahili using monolingua...
PDF
WOOl fibre morphology and structure.pdf for textiles
PPTX
Group 1 Presentation -Planning and Decision Making .pptx
PDF
A novel scalable deep ensemble learning framework for big data classification...
PDF
Architecture types and enterprise applications.pdf
Chapter 5: Probability Theory and Statistics
search engine optimization ppt fir known well about this
Unlock new opportunities with location data.pdf
Module 1.ppt Iot fundamentals and Architecture
A Late Bloomer's Guide to GenAI: Ethics, Bias, and Effective Prompting - Boha...
Transform Your ITIL® 4 & ITSM Strategy with AI in 2025.pdf
Benefits of Physical activity for teenagers.pptx
MicrosoftCybserSecurityReferenceArchitecture-April-2025.pptx
NewMind AI Weekly Chronicles – August ’25 Week III
TrustArc Webinar - Click, Consent, Trust: Winning the Privacy Game
How ambidextrous entrepreneurial leaders react to the artificial intelligence...
What is a Computer? Input Devices /output devices
Modernising the Digital Integration Hub
Hybrid horned lizard optimization algorithm-aquila optimizer for DC motor
Taming the Chaos: How to Turn Unstructured Data into Decisions
A comparative study of natural language inference in Swahili using monolingua...
WOOl fibre morphology and structure.pdf for textiles
Group 1 Presentation -Planning and Decision Making .pptx
A novel scalable deep ensemble learning framework for big data classification...
Architecture types and enterprise applications.pdf

#PDR15 - Developing for Round

  • 1. 2015 Pebble Developer Retreat Developing for Round Heiko Behrens, WTF Engineer
  • 6. Pebble SDK Aplite Basalt Chalk 2.x ✅ 3.0 ❌ ✅ 3.6 ❌ ✅
  • 7. Pebble SDK Aplite Basalt Chalk 2.x ✅ 3.0 ❌ ✅ 3.6 ❌ ✅ 3.x ✅ Unified 3.x SDK later this year
  • 8. Aplite Basalt Chalk CPU 24k
 ARM Cortex M3 64k ARM Cortex M4 Resolution 144x168px
 (Rectangular) 180x180 (Circular) Color black & white 64 Colors SmartStrap ❌ ✅ Mic ❌ ✅ Hardware
  • 9. runs on 2.x 3.x Aplite Basalt 2.x Aplite ✅ ✅ 3.x Basalt ❌ ✅ Compatibility compiledagainst 2.x Aplite runs on 3.x Basalt
  • 10. runs on 2.x 3.x Aplite Aplite Basalt Chalk 2.x Aplite ✅ ✅ ✅ ❌ 3.x Aplite ❌ ✅ ❌ ❌ Basalt ❌ ❌ ✅ ❌ Chalk ❌ ❌ ❌ ✅ Compatibility compiledagainst 3.x apps are compiled per platform Friday: Kevin talks about multi-platform
  • 11. Agenda • Uniform APIs across all platforms • New support for text flow • New routines for drawing round • Improvements of existing APIs
  • 12. Pebble Emulator $ pebble build $ pebble install --emulator chalk
  • 13. Graphics Friday: Matt talks about graphics
  • 14. Timeline Friday: Jon talks about Timeline
  • 16. Smartstraps Friday: Brian talks about Smartstraps
  • 17. Dictation Service Friday: Andrew talks about Dictation Service
  • 18. Text Flow • Uniform APIs across all platforms • New support for text flow • New routines for drawing round • Improvements of existing APIs
  • 24. facilisis egestas. Proin vitae arcu ac diam viverra aliquet. Nunc gravida libero 130px 120px facilisis egestas. Proin vitae arcu ac diam viverra aliquet. Nunc gravida libero nec massa rutrum, vel ultriciesenim 180px 180px
  • 25. facilisis egestas. Proin vitae arcu ac diam viverra aliquet. Nunc gravida libero nec massa rutrum, vel ultriciesenim (0,0) (179,179) facilisis egestas. Proin vitae arcu ac diam viverra aliquet. Nunc gravida libero nec massa rutrum, vel ultriciesenim (0,0) (179,179) Layer *window_layer = window_get_root_layer(
 window);
 GRect window_bounds = layer_get_bounds(
 window_layer);
 // window’s bounds are // GRect(0, 0, 180, 180) (0,0) (179,179) window coordinates on Chalk
  • 26. facilisis egestas. Proin vitae arcu ac diam viverra aliquet. Nunc gravida libero nec massa rutrum, vel ultriciesenim tristique. Nam magna enim, ullamcorper nec tellus vel, accumsan. (0,0) (179,179) facilisis egestas. Proin vitae arcu ac diam viverra aliquet. Nunc gravida libero nec massa rutrum, vel ultriciesenim tristique. Nam magna enim, ullamcorper nec tellus vel, accumsan. (0,0) (179,179) s_text_layer = text_layer_create(window_bounds);
 layer_add_child(
 window_layer, text_layer_get_layer(s_text_layer));
 
 text_layer_set_text(s_text_layer, s_text);
 text_layer_set_background_color(
 s_text_layer, GColorBlueMoon); TextLayer
  • 27. facilisis egestas. Proin vitae arcu ac diam viverra aliquet. Nunc gravida libero nec massa rutrum, vel ultriciesenim tristique. Nam magna enim, ullamcorper nec tellus vel, accumsan. (0,0) (179,179) facilisis egestas. Proin vitae arcu ac diam viverra aliquet. Nunc gravida libero nec massa rutrum, vel ultriciesenim tristique. Nam magna enim, ullamcorper nec tellus vel, accumsan. (0,0) (179,179) s_text_layer = text_layer_create(window_bounds);
 layer_add_child(
 window_layer, text_layer_get_layer(s_text_layer));
 
 text_layer_set_text(s_text_layer, s_text);
 text_layer_set_background_color(
 s_text_layer, GColorBlueMoon);
 
 text_layer_set_text_alignment(
 s_text_layer, GTextAlignmentCenter); TextLayer
  • 28. s_text_layer = text_layer_create(window_bounds);
 layer_add_child(
 window_layer, text_layer_get_layer(s_text_layer));
 
 text_layer_set_text(s_text_layer, s_text);
 text_layer_set_background_color(
 s_text_layer, GColorBlueMoon);
 
 text_layer_set_text_alignment(
 s_text_layer, GTextAlignmentCenter);
 
 uint8_t inset = 10;
 text_layer_enable_screen_text_flow_and_paging(
 s_text_layer, inset); facilisis egestas. Proin vitae arcu ac diam viverra aliquet. Nunc gravida libero nec massa rutrum, vel ultriciesenim (0,0) (179,179) facilisis egestas. Proin vitae arcu ac diam viverra aliquet. Nunc gravida libero nec massa rutrum, vel ultriciesenim (0,0) (179,179) 10px 10px 10px 10px TextLayer
  • 30. GTextAttributes GTextAttributes *attributes = graphics_text_attributes_create(); graphics_text_attributes_enable_screen_text_flow(attributes, 8); 
 graphics_draw_text(ctx, s_text, ..., attributes);
 GSize size = graphics_text_layout_get_content_size_with_attributes(s_text, ..., attributes);
 graphics_text_attributes_destroy(attributes); graphics_draw_text(ctx, s_text, ..., NULL); Before SDK 3.6: last argument was always NULL GTextAttributes for extended control when drawing/measuring text
  • 31. Drawing Round • Uniform APIs across all platforms • New support for text flow • New routines for drawing round • Improvements of existing APIs
  • 33. const GRect bounds = GRect(0, 0, 10, 10);
  • 34. const GRect r = GRect(1, 1, 8, 3);
 graphics_fill_rect(ctx, r, 0, GCornerNone);
  • 35. p0 p1 const GRect r = GRect(1, 1, 8, 3); graphics_fill_rect(ctx, r, 0, GCornerNone); const GPoint p0 = GPoint(1, 1);
 const GPoint p1 = GPoint(8, 3);
 graphics_draw_line(ctx, p0, p1);
  • 36. p0 p1 const GRect r = GRect(1, 1, 8, 3); graphics_fill_rect(ctx, r, 0, GCornerNone); const GPoint p0 = GPoint(1, 1);
 const GPoint p1 = GPoint(8, 3);
 graphics_draw_line(ctx, p0, p1);
  • 37. const GRect r = GRect(1, 1, 8, 3); graphics_fill_rect(ctx, r, 0, GCornerNone); const GPoint p0 = GPoint(1, 1);
 const GPoint p1 = GPoint(8, 3);
 graphics_draw_line(ctx, p0, p1); const p_max = GPoint(r.origin.x + r.size.w,
 r.origin.y + r.size.h); p0 p1 pmax // (9, 4) ?!
  • 38. r0 = GRect(1, 1, 8, 3);
 p0 = GPoint(1, 1);
 p1 = GPoint(8, 3); p0 p1 p2 p3 r1 = GRect(1, 2, 8, 6);
 p2 = GPoint(1, 2);
 p3 = GPoint(8, 7); //(2 * 1, 2 * 3) // 2 * 1 // 2 * 3 + 1 ?!7 2 62
  • 39. center_a = GPoint(?, ?);
 radius_a = ?;
 graphics_fill_circle(ctx,
 center_a,
 radius_a
 );
  • 40. center_a = GPoint(?, ?);
 radius_a = ?;
 graphics_fill_circle(ctx,
 center_a,
 radius_a
 );
  • 41. center_a = GPoint(3, 3);
 radius_a = 2;
 graphics_fill_circle(ctx,
 center_a,
 radius_a
 ); centera radiusa
  • 42. center_a = GPoint(3, 3);
 radius_a = 2;
 graphics_fill_circle(ctx,
 center_a,
 radius_a
 ); centera radiusa centera radiusb center_b = GPoint(4.5, 4.5);
 radius_b = 3.5;
 graphics_fill_circle(ctx,
 center_b,
 radius_b
 );
  • 44. rect_a = GRect(1, 1, 5, 5);
 somehow_fill_circle_inside( ctx, rect_a
 ); rect_b = GRect(1, 1, 8, 8);
 somehow_fill_circle_inside( ctx, rect_b
 );
  • 45. void graphics_fill_radial( GContext *ctx, 
 GRect rect, 
 GOvalScaleMode scale_mode,
 uint16_t inset_thickness,
 int32_t angle_start, 
 int32_t angle_end ); void graphics_draw_arc(
 GContext *ctx,
 GRect rect,
 GOvalScaleMode scale_mode,
 
 int32_t angle_start,
 int32_t angle_end ); new drawing APIs
  • 47. inset
  • 52. GPoint gpoint_from_polar(GRect rect, GOvalScaleMode scale_mode, int32_t angle); GRect grect_centered_from_polar(GRect rect, 
 GOvalScaleMode scale_mode, int32_t angle, GSize size); GRect grect_inset(GRect rect,
 GEdgeInsets insets); new geometry APIs
  • 55. grect_inset & GEdgeInsets GRect a = grect_inset(r, GEdgeInsets(16)); // all sides GRect b = grect_inset(r, GEdgeInsets(25, 16)); // top & bottom, right & left GRect c = grect_inset(r, GEdgeInsets(25, 16, 10)); // top, right & left, bottom GRect c = grect_inset(r, GEdgeInsets(25, -20, 10, 16)); // top, right, bottom, left a b c d 16px 16px 25px 25px 25px 25px 10px 10px 16px 16px 16px 16px16px 16px 16px 20px Friday: Kevin talks about multi-platform
  • 57. Drawing Round • Uniform APIs across all platforms • New support for text flow • New routines for drawing round • Improvements of existing APIs
  • 63. StatusBar s_status_bar = status_bar_layer_create();
 GRect status_bar_rect = window_bounds;
 status_bar_rect.size.h = STATUS_BAR_LAYER_HEIGHT;
 layer_set_frame( status_bar_layer_get_layer(s_status_bar),
 status_bar_rect);
 
 // top/bottom: statusbar, left/right: 0 GEdgeInsets insets = GEdgeInsets( STATUS_BAR_LAYER_HEIGHT, 0); GRect menu_layer_rect = grect_inset( window_bounds, insets);
  • 66. ActionBar s_action_bar = action_bar_layer_create();
 action_bar_layer_add_to_window( s_action_bar, window);
 
 // top: statusbar, right: actionbar, bottom/left:0 GEdgeInsets insets = GEdgeInsets(
 STATUS_BAR_LAYER_HEIGHT, ACTION_BAR_WIDTH, 0, 0);
 GRect content_rect = grect_inset( window_bounds, insets);
  • 69. Standard Cell Heights // default on Chalk menu_layer_set_center_focused(menu_layer, true); static int16_t get_cell_height_callback( MenuLayer *menu_layer, MenuIndex *cell_index,
 void *callback_context) {
 // when center_focused, MenuLayer can handle cell heights // that change based on the selection status if (menu_layer_is_index_selected(menu_layer, cell_index)) {
 return MENU_CELL_ROUND_FOCUSED_TALL_CELL_HEIGHT;
 } else {
 return MENU_CELL_ROUND_UNFOCUSED_SHORT_CELL_HEIGHT;
 }
 }

  • 71. Rect Round Square Visible Pixels 24,192 25,792 32,400 Δ Rect 1,600 (+7%) 8,208 (+34%) Δ Round 6,608 (+26%) 144px 168px 180px 180px 180px 180pxRect Round Square
  • 72. 0 1 2 3 7 8 9 106 11 13 14 15 1612 17 19 20 21 2218 23 25 26 27 2824 29 31 32 33 3430 35 37 38 39 4036 41 43 44 45 46 4 42 47 5 GBitmap pixel data int offset = y * bytes_per_row + x;
  • 73. 0 1 2 3 5 6 7 84 9 12 13 14 1511 1610 17 20 21 22 2319 2418 25 28 29 30 3127 3226 33 36 37 38 3935 4034 41 43 44 45 4642 47 48 49 50 51 0 1 2 3 7 8 9 106 11 13 14 15 1612 17 19 20 21 2218 23 25 26 27 2824 29 31 32 33 3430 35 37 38 39 4036 41 43 44 45 46 4 42 47 5 GBitmap pixel data
  • 74. 0 1 2 3 5 6 7 84 9 12 13 14 1511 1610 17 20 21 22 2319 2418 25 28 29 30 3127 3226 33 36 37 38 3935 4034 41 43 44 45 4642 47 48 49 50 51 data min_x max_x -2 2 5 3 1 6 10 0 7 18 0 7 26 0 7 34 0 7 41 1 6 46 2 5 41 46 47 3 -2 -1 52 53 0 1 2 3 7 8 9 106 11 13 14 15 1612 17 19 20 21 2218 23 25 26 27 2824 29 31 32 33 3430 35 37 38 39 4036 41 43 44 45 46 4 42 47 5 gbitmap_get_data_row_info uint16_t bytes_per_row = gbitmap_get_bytes_per_row(fb);
 uint8_t *pixel_data = gbitmap_get_data(fb); 
 uint8_t *pixel = pixel_data + y * bytes_per_row + x; GBitmapDataRowInfo row_info = gbitmap_get_data_row_info(fb, y);
 uint8_t *pixel = row_info.data + x;
  • 75. rectangular only general approach • pointer retrieval • offset calculaton • horizontal boundary checks GBitmap *fb = graphics_capture_frame_buffer(ctx);
 GSize size = gbitmap_get_bounds(fb).size;
 
 uint16_t bytes_per_row = gbitmap_get_bytes_per_row(fb);
 uint8_t *pixel_data = gbitmap_get_data(fb);
 for (uint16_t y = 0; y < size.h; y++) {
 uint8_t *pixel = pixel_data + y * bytes_per_row;
 for (uint16_t x = 0; x < size.w; x++) {
 *pixel = some_color.argb;
 pixel++;
 }
 }
 GBitmap *fb = graphics_capture_frame_buffer(ctx);
 GSize size = gbitmap_get_bounds(fb).size;
 for (uint16_t y = 0; y < size.h; y++) {
 GBitmapDataRowInfo row_info = gbitmap_get_data_row_info(fb, y);
 uint8_t *pixel = row_info.data + row_info.min_x;
 for (int16_t x = row_info.min_x; x <= row_info.max_x; x++) {
 *pixel = some_color.argb;
 pixel++;
 }
 }

  • 76. Aplite Basalt Chalk Resolution 144x168px
 (Rectangular) 180x180 (Circular) Color b/w 64 Colors PBL_IF_RECT_ELSE("rect", "otherwise");
 PBL_IF_ROUND_ELSE("round", "otherwise");
 PBL_IF_COLOR_ELSE("color", "otherwise");
 PBL_IF_BW_ELSE("bw", "otherwise"); file~rect.png
 file~round.png
 file~color.png
 file~bw.png #defines #resources Feature Selection Friday: Kevin talks about multi-platform
  • 77. iOS Starting with Chalk, you need to compile with PebbleKit iOS 3.0 Since PebbleOS 3.0, you need to compile with PebbleKit Android 3.0 Android Friday: Marcel talks about PebbleKit iOS
  • 78. Pebble SDK • Uniform APIs across all platforms • New support for text flow • New routines for drawing round • Improvements of existing APIs