mirror of
https://github.com/google/pebble.git
synced 2025-11-26 09:12:23 -05:00
Import of the watch repository from Pebble
This commit is contained in:
551
src/fw/apps/demo_apps/pebble_shapes.c
Normal file
551
src/fw/apps/demo_apps/pebble_shapes.c
Normal file
@@ -0,0 +1,551 @@
|
||||
/*
|
||||
* Copyright 2024 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "pebble_shapes.h"
|
||||
|
||||
#include "applib/app.h"
|
||||
#include "applib/graphics/graphics.h"
|
||||
#include "applib/graphics/gpath.h"
|
||||
#include "applib/graphics/gtypes.h"
|
||||
#include "applib/graphics/gtransform.h"
|
||||
#include "applib/graphics/text.h"
|
||||
#include "util/trig.h"
|
||||
#include "applib/ui/action_bar_layer.h"
|
||||
#include "applib/ui/app_window_stack.h"
|
||||
#include "applib/ui/window.h"
|
||||
#include "kernel/pbl_malloc.h"
|
||||
#include "process_state/app_state/app_state.h"
|
||||
#include "system/logging.h"
|
||||
|
||||
typedef enum {
|
||||
POINT,
|
||||
LINE,
|
||||
SQUARE,
|
||||
RECTANGLE,
|
||||
RECTANGLE_ROUND,
|
||||
CIRCLE,
|
||||
GPATH_TRIANGLE,
|
||||
GPATH_OPEN_BUCKET,
|
||||
MAX_SHAPES
|
||||
} DrawShape;
|
||||
|
||||
#define NUM_SHAPES MAX_SHAPES
|
||||
static GColor s_display_colors[NUM_SHAPES];
|
||||
|
||||
#define MAX_STROKE_WIDTH 20
|
||||
|
||||
static const GPathInfo s_triangle_path = {
|
||||
3,
|
||||
(GPoint[]) {
|
||||
{ -10, 0 },
|
||||
{ 0, 10 },
|
||||
{ 10, 0 }
|
||||
}
|
||||
};
|
||||
|
||||
static const GPathInfo s_bucket_path = {
|
||||
4,
|
||||
(GPoint[]) {
|
||||
{ -10, 0 },
|
||||
{ -10, 30 },
|
||||
{ 10, 30 },
|
||||
{ 10, 0 }
|
||||
}
|
||||
};
|
||||
|
||||
static const int TARGET_FPS = 40;
|
||||
static const int PIXEL_SPEED_PER_FRAME = 2;
|
||||
|
||||
#define ANGLE_DEGREES_TO_TRIG_ANGLE(angle) (((angle % 360) * TRIG_MAX_ANGLE) / 360)
|
||||
#define MAX_SCALE 10
|
||||
|
||||
typedef enum {
|
||||
APP_STATE_FILL_NON_AA,
|
||||
APP_STATE_FILL_AA,
|
||||
APP_STATE_DRAW_NON_AA_NO_SW,
|
||||
APP_STATE_DRAW_AA_NO_SW,
|
||||
APP_STATE_DRAW_NON_AA_SW,
|
||||
APP_STATE_DRAW_AA_SW,
|
||||
|
||||
// Add more above
|
||||
APP_STATE_NUM_STATES
|
||||
} AppStateIndex;
|
||||
|
||||
typedef struct AppData {
|
||||
Window window;
|
||||
|
||||
// Point properties
|
||||
GPoint point_p0;
|
||||
int16_t point_velocity_x;
|
||||
int16_t point_velocity_y;
|
||||
|
||||
// Line properties
|
||||
GPoint line_p0;
|
||||
GPoint line_p1;
|
||||
int16_t line_velocity_x;
|
||||
int16_t line_velocity_y;
|
||||
|
||||
// Square properties
|
||||
GRect square;
|
||||
int16_t square_velocity_x;
|
||||
int16_t square_velocity_y;
|
||||
|
||||
// Rectangle properties
|
||||
GRect rect;
|
||||
int16_t rect_velocity_x;
|
||||
int16_t rect_velocity_y;
|
||||
|
||||
// Rectangle Round properties
|
||||
GRect rectr;
|
||||
uint16_t rectr_radius;
|
||||
uint16_t rectr_corners_index;
|
||||
int16_t rectr_velocity_x;
|
||||
int16_t rectr_velocity_y;
|
||||
|
||||
// Circle properties
|
||||
GPoint circle_origin;
|
||||
uint16_t circle_radius;
|
||||
int16_t circle_velocity_x;
|
||||
int16_t circle_velocity_y;
|
||||
GColor circle_color;
|
||||
|
||||
// Triangle
|
||||
GPath *triangle;
|
||||
GPoint triangle_offset;
|
||||
int16_t triangle_velocity_x;
|
||||
int16_t triangle_velocity_y;
|
||||
|
||||
// Bucket
|
||||
GPath *bucket;
|
||||
GPoint bucket_offset;
|
||||
int16_t bucket_velocity_x;
|
||||
int16_t bucket_velocity_y;
|
||||
|
||||
// Generic properties that can be changed as property_index changes
|
||||
bool fill;
|
||||
int16_t color_index;
|
||||
|
||||
int64_t time_started;
|
||||
uint32_t rendered_frames;
|
||||
|
||||
bool moving;
|
||||
AppStateIndex state_index;
|
||||
int16_t stroke_width;
|
||||
bool antialiased;
|
||||
} AppData;
|
||||
|
||||
|
||||
static void log_state(AppData *data) {
|
||||
switch (data->state_index) {
|
||||
case APP_STATE_FILL_NON_AA:
|
||||
PBL_LOG(LOG_LEVEL_DEBUG, "State: Fill Non-Antialiased; SW: N/A (but currently: %d)",
|
||||
data->stroke_width);
|
||||
break;
|
||||
case APP_STATE_FILL_AA:
|
||||
PBL_LOG(LOG_LEVEL_DEBUG, "State: Fill Antialiased; SW: N/A (but currently: %d)",
|
||||
data->stroke_width);
|
||||
break;
|
||||
case APP_STATE_DRAW_NON_AA_NO_SW:
|
||||
PBL_LOG(LOG_LEVEL_DEBUG, "State: Draw Non-Antialiased; SW: N/A (but currently: %d)",
|
||||
data->stroke_width);
|
||||
break;
|
||||
case APP_STATE_DRAW_AA_NO_SW:
|
||||
PBL_LOG(LOG_LEVEL_DEBUG, "State: Draw Antialiased; SW: N/A (but currently: %d)",
|
||||
data->stroke_width);
|
||||
break;
|
||||
case APP_STATE_DRAW_NON_AA_SW:
|
||||
PBL_LOG(LOG_LEVEL_DEBUG, "State: Draw Non-Antialiased; SW: %d", data->stroke_width);
|
||||
break;
|
||||
case APP_STATE_DRAW_AA_SW:
|
||||
PBL_LOG(LOG_LEVEL_DEBUG, "State: Draw Antialiased; SW: %d", data->stroke_width);
|
||||
break;
|
||||
default:
|
||||
PBL_LOG(LOG_LEVEL_DEBUG, "Unknown State");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool stroke_width_enabled(AppStateIndex state_index) {
|
||||
return ((state_index == APP_STATE_DRAW_AA_SW) || (state_index == APP_STATE_DRAW_NON_AA_SW));
|
||||
}
|
||||
|
||||
static void update_state(AppData *data, AppStateIndex state_index) {
|
||||
data->state_index = state_index;
|
||||
data->fill = ((data->state_index == APP_STATE_FILL_NON_AA) ||
|
||||
(data->state_index == APP_STATE_FILL_AA));
|
||||
data->antialiased = ((data->state_index == APP_STATE_DRAW_AA_NO_SW) ||
|
||||
(data->state_index == APP_STATE_DRAW_AA_SW) ||
|
||||
(data->state_index == APP_STATE_FILL_AA));
|
||||
}
|
||||
|
||||
static void back_handler(ClickRecognizerRef recognizer, void *context) {
|
||||
AppData *data = app_state_get_user_data();
|
||||
|
||||
update_state(data, ((data->state_index - 1) % APP_STATE_NUM_STATES));
|
||||
log_state(data);
|
||||
}
|
||||
|
||||
static void up_handler(ClickRecognizerRef recognizer, void *context) {
|
||||
AppData *data = app_state_get_user_data();
|
||||
|
||||
if (stroke_width_enabled(data->state_index)) {
|
||||
data->stroke_width++;
|
||||
if (data->stroke_width >= MAX_STROKE_WIDTH) {
|
||||
data->stroke_width = 1;
|
||||
}
|
||||
}
|
||||
log_state(data);
|
||||
}
|
||||
|
||||
static void select_handler(ClickRecognizerRef recognizer, void *context) {
|
||||
AppData *data = app_state_get_user_data();
|
||||
|
||||
update_state(data, ((data->state_index + 1) % APP_STATE_NUM_STATES));
|
||||
log_state(data);
|
||||
}
|
||||
|
||||
static void down_handler(ClickRecognizerRef recognizer, void *context) {
|
||||
AppData *data = app_state_get_user_data();
|
||||
|
||||
data->moving = !data->moving;
|
||||
|
||||
log_state(data);
|
||||
}
|
||||
|
||||
static void click_config_provider(void *context) {
|
||||
window_single_click_subscribe(BUTTON_ID_BACK, back_handler);
|
||||
window_single_click_subscribe(BUTTON_ID_UP, up_handler);
|
||||
window_single_click_subscribe(BUTTON_ID_SELECT, select_handler);
|
||||
window_single_click_subscribe(BUTTON_ID_DOWN, down_handler);
|
||||
}
|
||||
|
||||
static void prv_move_shape(AppData *data) {
|
||||
for (uint8_t shape = POINT; shape < MAX_SHAPES; shape++) {
|
||||
if (shape == POINT) {
|
||||
// Move the point 4*X per Y
|
||||
data->point_p0.x += (data->point_velocity_x * PIXEL_SPEED_PER_FRAME * 4);
|
||||
if (data->point_p0.x < 0 || data->point_p0.x > data->window.layer.bounds.size.w) {
|
||||
data->point_velocity_x = data->point_velocity_x * -1;
|
||||
}
|
||||
|
||||
data->point_p0.y += (data->point_velocity_y * PIXEL_SPEED_PER_FRAME);
|
||||
if (data->point_p0.y < 0 || data->point_p0.y > data->window.layer.bounds.size.h) {
|
||||
data->point_velocity_y = data->point_velocity_y * -1;
|
||||
}
|
||||
} else if (shape == LINE) {
|
||||
// Move the line 2*X per Y
|
||||
data->line_p0.x += (data->line_velocity_x * PIXEL_SPEED_PER_FRAME * 2);
|
||||
data->line_p1.x += (data->line_velocity_x * PIXEL_SPEED_PER_FRAME * 2);
|
||||
if (data->line_p0.x < 0 || data->line_p0.x > data->window.layer.bounds.size.w ||
|
||||
data->line_p1.x < 0 || data->line_p1.x > data->window.layer.bounds.size.w ) {
|
||||
data->line_velocity_x = data->line_velocity_x * -1;
|
||||
}
|
||||
|
||||
data->line_p0.y += (data->line_velocity_y * PIXEL_SPEED_PER_FRAME);
|
||||
data->line_p1.y += (data->line_velocity_y * PIXEL_SPEED_PER_FRAME);
|
||||
if (data->line_p0.y < 0 || data->line_p0.y > data->window.layer.bounds.size.h ||
|
||||
data->line_p1.y < 0 || data->line_p1.y > data->window.layer.bounds.size.h ) {
|
||||
data->line_velocity_y = data->line_velocity_y * -1;
|
||||
}
|
||||
} else if (shape == SQUARE) {
|
||||
// Move the square X per Y
|
||||
data->square.origin.x += (data->square_velocity_x * PIXEL_SPEED_PER_FRAME);
|
||||
if (data->square.origin.x < 0 ||
|
||||
data->square.origin.x + data->square.size.w > data->window.layer.bounds.size.w) {
|
||||
data->square_velocity_x = data->square_velocity_x * -1;
|
||||
}
|
||||
|
||||
data->square.origin.y += (data->square_velocity_y * PIXEL_SPEED_PER_FRAME);
|
||||
if (data->square.origin.y < 0 ||
|
||||
data->square.origin.y + data->square.size.h > data->window.layer.bounds.size.h) {
|
||||
data->square_velocity_y = data->square_velocity_y * -1;
|
||||
}
|
||||
} else if (shape == RECTANGLE) {
|
||||
// Move the rectangle X per 2*Y
|
||||
data->rect.origin.x += (data->rect_velocity_x * PIXEL_SPEED_PER_FRAME);
|
||||
if (data->rect.origin.x < 0 ||
|
||||
data->rect.origin.x + data->rect.size.w > data->window.layer.bounds.size.w) {
|
||||
data->rect_velocity_x = data->rect_velocity_x * -1;
|
||||
}
|
||||
|
||||
data->rect.origin.y += (data->rect_velocity_y * PIXEL_SPEED_PER_FRAME * 2);
|
||||
if (data->rect.origin.y < 0 ||
|
||||
data->rect.origin.y + data->rect.size.h > data->window.layer.bounds.size.h) {
|
||||
data->rect_velocity_y = data->rect_velocity_y * -1;
|
||||
}
|
||||
} else if (shape == RECTANGLE_ROUND) {
|
||||
// Move rounded line X per 4*Y
|
||||
data->rectr.origin.x += (data->rectr_velocity_x * PIXEL_SPEED_PER_FRAME);
|
||||
if (data->rectr.origin.x < 0 ||
|
||||
data->rectr.origin.x + data->rectr.size.w > data->window.layer.bounds.size.w) {
|
||||
data->rectr_velocity_x = data->rectr_velocity_x * -1;
|
||||
}
|
||||
|
||||
data->rectr.origin.y += (data->rectr_velocity_y * PIXEL_SPEED_PER_FRAME * 4);
|
||||
if (data->rectr.origin.y < 0 ||
|
||||
data->rectr.origin.y + data->rectr.size.h > data->window.layer.bounds.size.h) {
|
||||
data->rectr_velocity_y = data->rectr_velocity_y * -1;
|
||||
}
|
||||
} else if (shape == CIRCLE) {
|
||||
// Move the line X per Y
|
||||
data->circle_origin.x += (data->circle_velocity_x * PIXEL_SPEED_PER_FRAME);
|
||||
if (data->circle_origin.x - data->circle_radius < 0 ||
|
||||
data->circle_origin.x + data->circle_radius > data->window.layer.bounds.size.w) {
|
||||
data->circle_velocity_x = data->circle_velocity_x * -1;
|
||||
data->circle_color.argb = (((data->circle_color.argb + 1) & 0x3F) | 0xC0);
|
||||
}
|
||||
|
||||
data->circle_origin.y += (data->circle_velocity_y * PIXEL_SPEED_PER_FRAME);
|
||||
if (data->circle_origin.y - data->circle_radius < 0 ||
|
||||
data->circle_origin.y + data->circle_radius > data->window.layer.bounds.size.h) {
|
||||
data->circle_velocity_y = data->circle_velocity_y * -1;
|
||||
data->circle_color.argb = (((data->circle_color.argb + 1) & 0x3F) | 0xC0);
|
||||
}
|
||||
} else if (shape == GPATH_TRIANGLE) {
|
||||
// Move the line 3*X per Y
|
||||
data->triangle_offset.x += (data->triangle_velocity_x * PIXEL_SPEED_PER_FRAME * 3);
|
||||
if (data->triangle_offset.x < 0 ||
|
||||
data->triangle_offset.x > data->window.layer.bounds.size.w) {
|
||||
data->triangle_velocity_x = data->triangle_velocity_x * -1;
|
||||
}
|
||||
|
||||
data->triangle_offset.y += (data->triangle_velocity_y * PIXEL_SPEED_PER_FRAME);
|
||||
if (data->triangle_offset.y < 0 ||
|
||||
data->triangle_offset.y > data->window.layer.bounds.size.h) {
|
||||
data->triangle_velocity_y = data->triangle_velocity_y * -1;
|
||||
}
|
||||
gpath_move_to(data->triangle, data->triangle_offset);
|
||||
} else if (shape == GPATH_OPEN_BUCKET) {
|
||||
// Move the line 2*X per 3*Y
|
||||
data->bucket_offset.x += (data->bucket_velocity_x * PIXEL_SPEED_PER_FRAME * 2);
|
||||
if (data->bucket_offset.x < 0 ||
|
||||
data->bucket_offset.x > data->window.layer.bounds.size.w) {
|
||||
data->bucket_velocity_x = data->bucket_velocity_x * -1;
|
||||
}
|
||||
|
||||
data->bucket_offset.y += (data->bucket_velocity_y * PIXEL_SPEED_PER_FRAME * 3);
|
||||
if (data->bucket_offset.y < 0 ||
|
||||
data->bucket_offset.y > data->window.layer.bounds.size.h) {
|
||||
data->bucket_velocity_y = data->bucket_velocity_y * -1;
|
||||
}
|
||||
gpath_move_to(data->bucket, data->bucket_offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_shape(GContext* ctx, AppData *data, DrawShape shape, GColor color) {
|
||||
graphics_context_set_fill_color(ctx, color);
|
||||
graphics_context_set_stroke_color(ctx, color);
|
||||
if (data->fill) {
|
||||
if (shape == POINT) {
|
||||
graphics_draw_pixel(ctx, data->point_p0);
|
||||
} else if (shape == LINE) {
|
||||
graphics_draw_line(ctx, data->line_p0, data->line_p1);
|
||||
} else if (shape == SQUARE) {
|
||||
graphics_fill_rect(ctx, &data->square);
|
||||
} else if (shape == RECTANGLE) {
|
||||
graphics_fill_rect(ctx, &data->rect);
|
||||
} else if (shape == RECTANGLE_ROUND) {
|
||||
graphics_fill_round_rect(ctx, &data->rectr, data->rectr_radius, GCornersAll);
|
||||
} else if (shape == CIRCLE) {
|
||||
graphics_context_set_fill_color(ctx, data->circle_color);
|
||||
graphics_context_set_stroke_color(ctx, data->circle_color);
|
||||
graphics_fill_circle(ctx, data->circle_origin, data->circle_radius);
|
||||
} else if (shape == GPATH_TRIANGLE) {
|
||||
gpath_draw_filled(ctx, data->triangle);
|
||||
} else if (shape == GPATH_OPEN_BUCKET) {
|
||||
gpath_draw_filled(ctx, data->bucket);
|
||||
}
|
||||
} else {
|
||||
if (shape == POINT) {
|
||||
graphics_draw_pixel(ctx, data->point_p0);
|
||||
} else if (shape == LINE) {
|
||||
graphics_draw_line(ctx, data->line_p0, data->line_p1);
|
||||
} else if (shape == SQUARE) {
|
||||
graphics_draw_rect(ctx, &data->square);
|
||||
} else if (shape == RECTANGLE) {
|
||||
graphics_draw_rect(ctx, &data->rect);
|
||||
} else if (shape == RECTANGLE_ROUND) {
|
||||
graphics_draw_round_rect(ctx, &data->rectr, data->rectr_radius);
|
||||
} else if (shape == CIRCLE) {
|
||||
graphics_context_set_fill_color(ctx, data->circle_color);
|
||||
graphics_context_set_stroke_color(ctx, data->circle_color);
|
||||
graphics_draw_circle(ctx, data->circle_origin, data->circle_radius);
|
||||
} else if (shape == GPATH_TRIANGLE) {
|
||||
gpath_draw_outline(ctx, data->triangle);
|
||||
} else if (shape == GPATH_OPEN_BUCKET) {
|
||||
gpath_draw_outline_open(ctx, data->bucket);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int64_t prv_time_64(void) {
|
||||
time_t s;
|
||||
uint16_t ms;
|
||||
rtc_get_time_ms(&s, &ms);
|
||||
return (int64_t)s * 1000 + ms;
|
||||
}
|
||||
|
||||
static void layer_update_proc(Layer *layer, GContext* ctx) {
|
||||
AppData *data = app_state_get_user_data();
|
||||
|
||||
graphics_context_set_fill_color(ctx, GColorBlack);
|
||||
if (stroke_width_enabled(data->state_index)) {
|
||||
graphics_context_set_stroke_width(ctx, data->stroke_width);
|
||||
} else {
|
||||
graphics_context_set_stroke_width(ctx, 1);
|
||||
}
|
||||
graphics_context_set_antialiased(ctx, data->antialiased);
|
||||
|
||||
graphics_fill_rect(ctx, &layer->bounds);
|
||||
|
||||
uint8_t color_index = 0;
|
||||
for (uint8_t shape_index = POINT; shape_index < MAX_SHAPES; shape_index++) {
|
||||
draw_shape(ctx, data, (DrawShape)shape_index, (GColor)s_display_colors[color_index++]);
|
||||
}
|
||||
|
||||
|
||||
if (data->rendered_frames == 0) {
|
||||
data->time_started = prv_time_64();
|
||||
} else {
|
||||
int64_t time_rendered = prv_time_64() - data->time_started;
|
||||
if ((data->rendered_frames % 64) == 0) {
|
||||
PBL_LOG(LOG_LEVEL_DEBUG, "## %d frames rendered", (int)data->rendered_frames);
|
||||
PBL_LOG(LOG_LEVEL_DEBUG, "## at %"PRIu32" FPS",
|
||||
(uint32_t)((uint64_t)data->rendered_frames*1000/time_rendered));
|
||||
}
|
||||
}
|
||||
data->rendered_frames++;
|
||||
}
|
||||
|
||||
|
||||
static void timer_callback(void *cb_data) {
|
||||
AppData *data = app_state_get_user_data();
|
||||
|
||||
if (data->moving) {
|
||||
prv_move_shape(data);
|
||||
}
|
||||
|
||||
layer_mark_dirty(&data->window.layer);
|
||||
|
||||
app_timer_register(1000 / TARGET_FPS, timer_callback, NULL);
|
||||
}
|
||||
|
||||
static void init(void) {
|
||||
AppData *data = task_malloc_check(sizeof(AppData));
|
||||
memset(data, 0x00, sizeof(AppData));
|
||||
|
||||
s_display_colors[0] = GColorWhite;
|
||||
s_display_colors[1] = GColorRed;
|
||||
s_display_colors[2] = GColorGreen;
|
||||
s_display_colors[3] = GColorBlue;
|
||||
s_display_colors[4] = (GColor)((uint8_t)0b11111100);
|
||||
s_display_colors[5] = (GColor)((uint8_t)0b11001111);
|
||||
s_display_colors[6] = (GColor)((uint8_t)0b11110101);
|
||||
s_display_colors[7] = GColorWhite;
|
||||
|
||||
|
||||
app_state_set_user_data(data);
|
||||
|
||||
Window *window = &data->window;
|
||||
window_init(window, WINDOW_NAME("Shapes"));
|
||||
window_set_user_data(window, data);
|
||||
window_set_fullscreen(window, true);
|
||||
layer_set_update_proc(&window->layer, layer_update_proc);
|
||||
|
||||
window_set_click_config_provider(window, click_config_provider);
|
||||
|
||||
const bool animated = true;
|
||||
app_window_stack_push(window, animated);
|
||||
|
||||
// Initialize shapes
|
||||
|
||||
// Point properties
|
||||
data->point_p0 = GPoint(1, 1);
|
||||
data->point_velocity_x = 1;
|
||||
data->point_velocity_y = 1;
|
||||
|
||||
// Line properties
|
||||
data->line_p0 = GPoint(0, 0);
|
||||
data->line_p1 = GPoint(10, 10);
|
||||
data->line_velocity_x = 1;
|
||||
data->line_velocity_y = 1;
|
||||
|
||||
// Square properties
|
||||
data->square = GRect(100, 50, 20, 20);
|
||||
data->square_velocity_x = 1;
|
||||
data->square_velocity_y = 1;
|
||||
|
||||
// Rectangle properties
|
||||
data->rect = GRect(80, 0, 30, 50);
|
||||
data->rect_velocity_x = 1;
|
||||
data->rect_velocity_y = 1;
|
||||
|
||||
// Rectangle Round properties
|
||||
data->rectr = GRect(20, 20, 20, 30);
|
||||
data->rectr_radius = 5;
|
||||
data->rectr_corners_index = GCornersAll;
|
||||
data->rectr_velocity_x = 1;
|
||||
data->rectr_velocity_y = 1;
|
||||
|
||||
// Circle properties
|
||||
data->circle_origin = GPoint(50, 50);
|
||||
data->circle_radius = 20;
|
||||
data->circle_velocity_x = 1;
|
||||
data->circle_velocity_y = 1;
|
||||
data->circle_color = s_display_colors[5];
|
||||
|
||||
// Triangle
|
||||
data->triangle = gpath_create(&s_triangle_path);
|
||||
data->triangle_offset = GPoint(10, 80);
|
||||
gpath_move_to(data->triangle, data->triangle_offset);
|
||||
data->triangle_velocity_x = 1;
|
||||
data->triangle_velocity_y = 1;
|
||||
|
||||
// Open bucket
|
||||
data->bucket = gpath_create(&s_bucket_path);
|
||||
data->bucket_offset = GPoint(20, 30);
|
||||
gpath_move_to(data->bucket, data->bucket_offset);
|
||||
data->bucket_velocity_x = 1;
|
||||
data->bucket_velocity_y = 1;
|
||||
|
||||
// Other properties
|
||||
update_state(data, APP_STATE_FILL_NON_AA);
|
||||
data->stroke_width = 1;
|
||||
data->moving = true;
|
||||
app_timer_register(33, timer_callback, NULL);
|
||||
}
|
||||
|
||||
static void deinit(void) {
|
||||
AppData *data = app_state_get_user_data();
|
||||
task_free(data);
|
||||
}
|
||||
|
||||
static void s_main(void) {
|
||||
init();
|
||||
|
||||
app_event_loop();
|
||||
|
||||
deinit();
|
||||
}
|
||||
|
||||
const PebbleProcessMd* pebble_shapes_get_app_info(void) {
|
||||
static const PebbleProcessMdSystem s_app_info = {
|
||||
.common.main_func = s_main,
|
||||
.name = "Pebble Shapes"
|
||||
};
|
||||
return (const PebbleProcessMd*) &s_app_info;
|
||||
}
|
||||
Reference in New Issue
Block a user