Restore floating action bar (legacy style)

This commit is contained in:
2026-06-12 20:07:16 -04:00
parent aa37a05984
commit e13c3a37ca
5 changed files with 79 additions and 29 deletions
+5 -3
View File
@@ -1,7 +1,9 @@
REcounter
=======
## REcounter
Why? Because, in an era where a simple counter app would likely be left up to the AI overlords, I'd rather just fork [something some guy made in 2014](https://github.com/matthewbauer/counter) and add touch support.
Because in an era where a simple counter app would likely be left up to the AI overlords, I'd rather just fork something some guy made in 2014 and add touch support.
This ended up being a pretty cool mini-project, as I learned about how the Pebble SDK has changed over the years. Immediately upon porting to the new SDK, there were various things that didn't quite look like they used to. This includes the lack of a status bar, the lack of margin&rounded corners on the action bar, the inability to render the previously valid menu icon, and the weird way bitmaps used to work regarding color and translucency. I addressed all of these to preserve the legacy Pebble SDK look with this app!
In addition to Emery+touch support, this version of the app also supports all other Pebbles.
## Original README
Counter is an app I made to learn how to use the Pebble SDK. It's pretty minimalist but can be useful from time to time. My official description reads:
+18 -2
View File
@@ -11,15 +11,17 @@
"dependencies": {},
"pebble": {
"displayName": "REcounter",
"uuid": "36bab645-70c5-472b-b99f-afc9f8656c71",
"uuid": "44fcf599-ed1b-4261-b818-d59471db9a18",
"sdkVersion": "3",
"enableMultiJS": false,
"targetPlatforms": [
"aplite",
"basalt",
"chalk",
"diorite",
"flint",
"emery"
"emery",
"gabbro"
],
"watchapp": {
"watchface": false
@@ -48,6 +50,20 @@
"spaceOptimization": "storage",
"type": "bitmap"
},
{
"file": "patch_bottom.png",
"memoryFormat": "Smallest",
"name": "PATCH_BOTTOM",
"spaceOptimization": "storage",
"type": "bitmap"
},
{
"file": "patch_top.png",
"memoryFormat": "Smallest",
"name": "PATCH_TOP",
"spaceOptimization": "storage",
"type": "bitmap"
},
{
"file": "icon.png",
"memoryFormat": "Smallest",
Binary file not shown.

After

Width:  |  Height:  |  Size: 91 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 B

+56 -24
View File
@@ -1,7 +1,6 @@
#include <pebble.h>
#define COUNT_PKEY 1
#define COUNT_DEFAULT 0
#define REPEAT_INTERVAL 50
static Window *s_window;
@@ -10,28 +9,42 @@ static TextLayer *s_text_layer;
static GBitmap *s_action_icon_plus;
static GBitmap *s_action_icon_minus;
static GBitmap *s_action_icon_reset;
static GBitmap *s_legacy_actionbar_patch_bottom;
static GBitmap *s_legacy_actionbar_patch_top;
static ActionBarLayer *s_action_bar;
static StatusBarLayer *s_status_bar;
static ActionBarLayer *s_action_bar_layer;
static StatusBarLayer *s_status_bar_layer;
static BitmapLayer *s_patch_bottom_layer;
static BitmapLayer *s_patch_top_layer;
static int count = COUNT_DEFAULT;
static int s_count;
#if PBL_RECT
#if PBL_DISPLAY_WIDTH == 200
static const GRect s_patch_bottom_grect = GRect(166, 223, 34, 5);
static const GRect s_patch_top_grect = GRect(166, 20, 34, 5);
#else
static const GRect s_patch_bottom_grect = GRect(114, 163, 34, 5);
static const GRect s_patch_top_grect = GRect(114, 16, 34, 5);
#endif
#endif
void update() {
static char buffer[10];
snprintf(buffer, sizeof(buffer), "%i", count);
snprintf(buffer, sizeof(buffer), "%i", s_count);
text_layer_set_text(s_text_layer, buffer);
}
void increment() {
count++;
s_count++;
}
void decrement() {
count--;
s_count--;
}
void reset() {
count = 0;
s_count = 0;
}
void select_click_handler(ClickRecognizerRef recognizer, void *context) {
@@ -56,39 +69,58 @@ void click_config_provider(void *context) {
}
void window_load(Window *window) {
s_action_bar = action_bar_layer_create();
action_bar_layer_add_to_window(s_action_bar, window);
action_bar_layer_set_click_config_provider(s_action_bar, click_config_provider);
Layer *window_layer = window_get_root_layer(window);
action_bar_layer_set_icon(s_action_bar, BUTTON_ID_UP, s_action_icon_reset);
action_bar_layer_set_icon(s_action_bar, BUTTON_ID_SELECT, s_action_icon_plus);
action_bar_layer_set_icon(s_action_bar, BUTTON_ID_DOWN, s_action_icon_minus);
s_action_bar_layer = action_bar_layer_create();
action_bar_layer_set_click_config_provider(s_action_bar_layer, click_config_provider);
action_bar_layer_set_icon(s_action_bar_layer, BUTTON_ID_UP, s_action_icon_reset);
action_bar_layer_set_icon(s_action_bar_layer, BUTTON_ID_SELECT, s_action_icon_plus);
action_bar_layer_set_icon(s_action_bar_layer, BUTTON_ID_DOWN, s_action_icon_minus);
action_bar_layer_add_to_window(s_action_bar_layer, window);
Layer *layer = window_get_root_layer(window);
GRect bounds = layer_get_frame(layer);
const int16_t width = layer_get_frame(layer).size.w - ACTION_BAR_WIDTH - 3;
#if PBL_RECT
s_patch_bottom_layer = bitmap_layer_create(s_patch_bottom_grect);
bitmap_layer_set_bitmap(s_patch_bottom_layer, s_legacy_actionbar_patch_bottom);
bitmap_layer_set_background_color(s_patch_bottom_layer, GColorClear);
bitmap_layer_set_compositing_mode(s_patch_bottom_layer, GCompOpSet);
layer_add_child(window_layer, bitmap_layer_get_layer(s_patch_bottom_layer));
s_patch_top_layer = bitmap_layer_create(s_patch_top_grect);
bitmap_layer_set_bitmap(s_patch_top_layer, s_legacy_actionbar_patch_top);
bitmap_layer_set_background_color(s_patch_top_layer, GColorClear);
bitmap_layer_set_compositing_mode(s_patch_top_layer, GCompOpSet);
layer_add_child(window_layer, bitmap_layer_get_layer(s_patch_top_layer));
#endif
GRect bounds = layer_get_frame(window_layer);
const int16_t width = layer_get_frame(window_layer).size.w - ACTION_BAR_WIDTH - 3;
s_text_layer = text_layer_create(GRect(0, 44, width, bounds.size.h));
text_layer_set_font(s_text_layer, fonts_get_system_font(FONT_KEY_BITHAM_42_BOLD));
text_layer_set_background_color(s_text_layer, GColorClear);
update();
text_layer_set_text_alignment(s_text_layer, GTextAlignmentCenter);
layer_add_child(layer, text_layer_get_layer(s_text_layer));
layer_add_child(window_layer, text_layer_get_layer(s_text_layer));
s_status_bar = status_bar_layer_create();
layer_add_child(layer, status_bar_layer_get_layer(s_status_bar));
s_status_bar_layer = status_bar_layer_create();
layer_add_child(window_layer, status_bar_layer_get_layer(s_status_bar_layer));
}
void window_unload(Window *window) {
status_bar_layer_destroy(s_status_bar);
status_bar_layer_destroy(s_status_bar_layer);
text_layer_destroy(s_text_layer);
action_bar_layer_destroy(s_action_bar);
#if PBL_RECT
bitmap_layer_destroy(s_patch_top_layer);
bitmap_layer_destroy(s_patch_bottom_layer);
#endif
action_bar_layer_destroy(s_action_bar_layer);
}
void init() {
s_action_icon_plus = gbitmap_create_with_resource(RESOURCE_ID_PLUS);
s_action_icon_minus = gbitmap_create_with_resource(RESOURCE_ID_MINUS);
s_action_icon_reset = gbitmap_create_with_resource(RESOURCE_ID_RESET);
s_legacy_actionbar_patch_bottom = gbitmap_create_with_resource(RESOURCE_ID_PATCH_BOTTOM);
s_legacy_actionbar_patch_top = gbitmap_create_with_resource(RESOURCE_ID_PATCH_TOP);
s_window = window_create();
@@ -97,13 +129,13 @@ void init() {
.unload = window_unload,
});
count = persist_exists(COUNT_PKEY) ? persist_read_int(COUNT_PKEY) : COUNT_DEFAULT;
s_count = persist_exists(COUNT_PKEY) ? persist_read_int(COUNT_PKEY) : 0;
window_stack_push(s_window, true);
}
void deinit() {
persist_write_int(COUNT_PKEY, count);
persist_write_int(COUNT_PKEY, s_count);
window_destroy(s_window);
gbitmap_destroy(s_action_icon_plus);
gbitmap_destroy(s_action_icon_minus);