diff --git a/README.md b/README.md index c08816f..c91fd44 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,22 @@ # neat_bar -A more customizable replacement for the built-in Pebble action bar. +`neat_bar` is a (mostly) drop-in replacement for the stock Pebble action bar that adds a bunch of customizability. ## VS Stock Action Bar ### New Features -- Floating mode -- Rectangular mode on round watches -- Adjustable spread (distance between icons) -- Increased max icon size (unlimited width; 25px height) -- Custom bar corner radius -- Custom bar width/height -- Custom bar x/y positions -### Removed Features +- Floating mode! +- Rectangular/round backgrounds on all watches! +- Adjustable spread (distance between icons)! +- Increased max icon size (unlimited width; 25px height)! +- Custom bar corner radius! +- Custom bar width/height! +- Custom bar x/y positions! +### Missing Features (unplanned) - Anything to do with back button overrides - Fully custom animations - Built-in animations can still be customized - Duration, move distance/direction, and move axis are all configurable -- Round style - - Using a rectangular bar on a round watch saves space and IMO looks way better - - Use custom corner radius for a nice effect on round watches! + - They can also be disabled ### Pending Features +- Auto-background-adding on b&w watches +- Optional AA on bar corners - Legacy (background invert) animations support -- Y offset for all icons diff --git a/src/c/neat_bar.c b/src/c/neat_bar.c index 1521581..9fa8932 100644 --- a/src/c/neat_bar.c +++ b/src/c/neat_bar.c @@ -4,6 +4,9 @@ #include "neat_bar.h" #include +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define ABS(a) (((a) < 0) ? -(a) : (a)) + #if PBL_DISPLAY_HEIGHT >= 260 && PBL_ROUND #define DEFAULT_SPREAD 41 #define SELECT_Y 118 @@ -138,9 +141,19 @@ static void s_select_up_handler(ClickRecognizerRef recognizer, void *context) { } static void s_main_layer_update_proc(Layer *layer, GContext *ctx) { - graphics_context_set_antialiased(ctx, false); - graphics_context_set_fill_color(ctx, s_current_neat_bar->background_color); - graphics_fill_rect(ctx, layer_get_bounds(layer), s_current_neat_bar->bar_corner_radius, s_current_neat_bar->bar_x_offset > 0 ? GCornersAll : GCornersLeft); + if (s_current_neat_bar->bar_use_round_style) { + const uint32_t action_bar_circle_diameter = PBL_DISPLAY_HEIGHT * 19 / 9; + GRect neat_bar_circle_frame = (GRect){.size = GSize(action_bar_circle_diameter, action_bar_circle_diameter)}; + GRect bounds = layer_get_bounds(layer); + grect_align(&neat_bar_circle_frame, &bounds, GAlignLeft, false); + graphics_context_set_fill_color(ctx, s_current_neat_bar->background_color); + const int32_t inset_thickness = MAX(ABS(neat_bar_circle_frame.size.h), ABS(neat_bar_circle_frame.size.w)); + graphics_fill_radial(ctx, neat_bar_circle_frame, GOvalScaleModeFitCircle, inset_thickness, 0, TRIG_MAX_ANGLE); + } else { + graphics_context_set_antialiased(ctx, false); + graphics_context_set_fill_color(ctx, s_current_neat_bar->background_color); + graphics_fill_rect(ctx, layer_get_bounds(layer), s_current_neat_bar->rect_bar_corner_radius, s_current_neat_bar->bar_x_offset > 0 ? GCornersAll : GCornersLeft); + } } static void s_base_click_config_provider(void *config_context) { @@ -225,8 +238,17 @@ void neat_bar_layer_set_animations_duration(NeatBarLayer *neat_bar, uint8_t dura neat_bar->animations_duration = duration_ms; } +// default: false +void neat_bar_layer_set_bar_style(NeatBarLayer *neat_bar, bool use_round_style) { + if (use_round_style == neat_bar->bar_use_round_style) { + return; + } + neat_bar->bar_use_round_style = use_round_style; + layer_mark_dirty(neat_bar->main_layer); +} + // default: 0 -void neat_bar_layer_set_bar_floating(NeatBarLayer *neat_bar, uint16_t x_offset) { +void neat_bar_layer_set_rect_bar_floating(NeatBarLayer *neat_bar, uint16_t x_offset) { if (x_offset == neat_bar->bar_x_offset) { return; } @@ -236,6 +258,15 @@ void neat_bar_layer_set_bar_floating(NeatBarLayer *neat_bar, uint16_t x_offset) layer_mark_dirty(neat_bar->main_layer); } +// default: 0 +void neat_bar_layer_set_rect_bar_corner_radius(NeatBarLayer *neat_bar, uint16_t corner_radius) { + if (corner_radius == neat_bar->rect_bar_corner_radius) { + return; + } + neat_bar->rect_bar_corner_radius = corner_radius; + layer_mark_dirty(neat_bar->main_layer); +} + // default: ACTION_BAR_WIDTH void neat_bar_layer_set_bar_width(NeatBarLayer *neat_bar, uint16_t width) { if (width == neat_bar->main_grect.size.w) { @@ -247,7 +278,7 @@ void neat_bar_layer_set_bar_width(NeatBarLayer *neat_bar, uint16_t width) { if (neat_bar->bar_x_offset > 0) { uint16_t x = neat_bar->bar_x_offset; neat_bar->bar_x_offset = 0; // force update - neat_bar_layer_set_bar_floating(neat_bar, x); + neat_bar_layer_set_rect_bar_floating(neat_bar, x); } else { layer_mark_dirty(neat_bar->main_layer); } @@ -275,15 +306,6 @@ void neat_bar_layer_set_bar_y_offset(NeatBarLayer *neat_bar, uint16_t y_offset) s_recenter_icons(neat_bar); } -// default: 0 -void neat_bar_layer_set_bar_corner_radius(NeatBarLayer *neat_bar, uint16_t corner_radius) { - if (corner_radius == neat_bar->bar_corner_radius) { - return; - } - neat_bar->bar_corner_radius = corner_radius; - layer_mark_dirty(neat_bar->main_layer); -} - // default: GColorBlack void neat_bar_layer_set_background_color(NeatBarLayer *neat_bar, GColor background_color) { if (gcolor_equal(background_color, neat_bar->background_color)) { @@ -358,7 +380,8 @@ NeatBarLayer *neat_bar_layer_create() { neat_bar->context = NULL; // neat_bar exclusives :D - neat_bar->bar_corner_radius = 0; + neat_bar->bar_use_round_style = false; + neat_bar->rect_bar_corner_radius = 0; neat_bar->bar_x_offset = 0; neat_bar->icons_spread = DEFAULT_SPREAD; neat_bar->animations_enabled = true; diff --git a/src/c/neat_bar.h b/src/c/neat_bar.h index eb44500..2b7a8d7 100644 --- a/src/c/neat_bar.h +++ b/src/c/neat_bar.h @@ -20,7 +20,8 @@ typedef struct { void *context; // neat_bar exclusives :D - uint16_t bar_corner_radius; + bool bar_use_round_style; + uint16_t rect_bar_corner_radius; uint16_t bar_x_offset; int8_t icons_spread; bool animations_enabled; @@ -40,11 +41,12 @@ void neat_bar_layer_set_animations_enabled(NeatBarLayer *neat_bar, bool enabled) void neat_bar_layer_set_animations_move_axis(NeatBarLayer *neat_bar, bool use_y_axis); void neat_bar_layer_set_animations_move_distance(NeatBarLayer *neat_bar, int8_t distance); void neat_bar_layer_set_animations_duration(NeatBarLayer *neat_bar, uint8_t duration_ms); -void neat_bar_layer_set_bar_floating(NeatBarLayer *neat_bar, uint16_t x_offset); +void neat_bar_layer_set_bar_style(NeatBarLayer *neat_bar, bool use_round_style); +void neat_bar_layer_set_rect_bar_floating(NeatBarLayer *neat_bar, uint16_t x_offset); +void neat_bar_layer_set_rect_bar_corner_radius(NeatBarLayer *neat_bar, uint16_t corner_radius); void neat_bar_layer_set_bar_width(NeatBarLayer *neat_bar, uint16_t width); void neat_bar_layer_set_bar_height(NeatBarLayer *neat_bar, uint16_t height); void neat_bar_layer_set_bar_y_offset(NeatBarLayer *neat_bar, uint16_t y_offset); -void neat_bar_layer_set_bar_corner_radius(NeatBarLayer *neat_bar, uint16_t corner_radius); void neat_bar_layer_set_background_color(NeatBarLayer *neat_bar, GColor background_color); void neat_bar_layer_set_icons_spread(NeatBarLayer *neat_bar, int8_t spread); void neat_bar_layer_set_icon(NeatBarLayer *layer, ButtonId button_id, GBitmap *icon);