Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tune up the apps real nice #79

Merged
merged 1 commit into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions components/homeThing/homeThingMenuBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,11 @@ bool HomeThingMenuBase::upMenu() {
}
if (menuTree.size() > 1) {
menuTree.pop_back();
if (menuTree.back() == rootMenu) {
reset_menu();
update_display();
return true;
}
menuIndex = 0;
reload_menu_items_ = true;
menu_titles.clear();
Expand Down
3 changes: 1 addition & 2 deletions components/homeThing/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@

namespace esphome {
namespace homething_menu_base {
static const std::string COMPONENTS_HOMETHING_VERSION =
"lando/refactor-now-playing/2023-09-25";
static const std::string COMPONENTS_HOMETHING_VERSION = "main/2023-09-25";
}
} // namespace esphome
#endif // COMPONENTS_HOMETHING_VERSION_H_
19 changes: 19 additions & 0 deletions components/homeThingAppBreakout/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.const import CONF_ID
from esphome.components import homeThingApp

AUTO_LOAD = ["homeThingApp"]
homething_app_snake_ns = cg.esphome_ns.namespace("homething_app_snake")

HomeThingAppSnake = homething_app_snake_ns.class_("HomeThingAppSnake", cg.Component)

CONFIG_SCHEMA = homeThingApp.BASE_SCHEMA.extend(
{
cv.GenerateID(CONF_ID): cv.declare_id(HomeThingAppSnake)
}
)

async def to_code(config):
var = await homeThingApp.new_app_base(config)
await cg.register_component(var, config)
188 changes: 188 additions & 0 deletions components/homeThingAppBreakout/homeThingAppSnake.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
#include "homeThingAppSnake.h"
#include "esphome/core/log.h"

namespace esphome {
namespace homething_app_snake {

void HomeThingAppSnake::reset() {
ESP_LOGI(TAG, "Resetting snake");
const auto bounds = get_display_bounds();
const auto newFruitPosition = get_random_coordinate();
const auto newSnakePosition = get_random_coordinate();
fruit_position_.x = newFruitPosition.x;
fruit_position_.y = newFruitPosition.y;
snake.clear();
snake.push_back(newSnakePosition);
}

Coordinate HomeThingAppSnake::get_random_coordinate() {
const auto bounds = get_display_bounds();
return Coordinate((rand() % (bounds.x)), (rand() % (bounds.y)));
}

Coordinate HomeThingAppSnake::get_display_bounds() {
int widthBounds =
(display_buffer_->get_width() - (margin * 2)) / displayScale;
int heightBounds = (display_buffer_->get_height() -
((margin * 2) + display_state_->get_header_height())) /
displayScale;
return Coordinate(widthBounds, heightBounds);
}

void HomeThingAppSnake::rootMenuTitles(
std::vector<homething_menu_base::MenuTitleBase*>* menu_titles) {
menu_titles->push_back(new homething_menu_base::MenuTitleBase(
"Snake", "", homething_menu_base::ArrowMenuTitleRightIcon));
}

void HomeThingAppSnake::app_menu_titles(
std::vector<homething_menu_base::MenuTitleBase*>* menu_titles) {}

// menu screens
homething_menu_app::NavigationCoordination HomeThingAppSnake::app_menu_select(
int index) {
return homething_menu_app::NavigationCoordination::NavigationCoordinationNone;
}

bool HomeThingAppSnake::should_draw_app() {
return true;
}

void HomeThingAppSnake::draw_resized_pixel(int coordinateX, int coordinateY,
Color color) {
int x = coordinateX * displayScale;
int y = coordinateY * displayScale;
for (int i = 0; i < displayScale; ++i) {
for (int j = 0; j < displayScale; ++j) {
display_buffer_->draw_pixel_at(
x + i + margin, y + j + margin + display_state_->get_header_height(),
color);
}
}
}

void HomeThingAppSnake::draw_app(
int menuIndex,
const std::vector<homething_menu_base::MenuTitleBase*>* active_menu) {
active_tick();
auto snakeColor = display_state_->get_color_palette()->get_green();
for (auto segment : snake) {
draw_resized_pixel(segment.x, segment.y, snakeColor);
}
auto fruitColor = display_state_->get_color_palette()->get_red();
draw_resized_pixel(fruit_position_.x, fruit_position_.y, fruitColor);

auto borderColor = display_state_->get_color_palette()->get_accent_primary();
display_buffer_->rectangle(
margin, margin + display_state_->get_header_height(),
get_display_bounds().x * displayScale,
get_display_bounds().y * displayScale, borderColor);
}

void HomeThingAppSnake::idleTick(int idleTime, int display_timeout) {}

void HomeThingAppSnake::active_tick() {
if (fruit_position_.x == -1) {
reset();
}
int newHeadY = snake[0].y + snake_direction_.x;
int newHeadX = snake[0].x + snake_direction_.y;
const auto bounds = get_display_bounds();
int widthBounds = bounds.x;
int heightBounds = bounds.y;
if (newHeadX == fruit_position_.x && newHeadY == fruit_position_.y) {
// Snake ate the fruit
snake.push_back(Coordinate(fruit_position_.x, fruit_position_.y));
auto newFruitPosition = get_random_coordinate();
fruit_position_.x = newFruitPosition.x;
fruit_position_.y = newFruitPosition.y;
ESP_LOGW(TAG, "Snake ate the fruit %d %d, %d %d", newHeadX, newHeadY,
widthBounds, heightBounds);
return;
} else {
// Move the snake
for (int i = snake.size() - 1; i > 0; --i) {
snake[i].x = snake[i - 1].x;
snake[i].y = snake[i - 1].y;
}
snake[0].x = newHeadX;
snake[0].y = newHeadY;
}

// Check for collisions with the snake's body
for (int i = 1; i < snake.size(); ++i) {
if (snake[i].x == newHeadX && snake[i].y == newHeadY) {
ESP_LOGW(TAG, "Snake hit itself %d %d, %d %d", newHeadX, newHeadY,
widthBounds, heightBounds);
reset();
}
}
// Check for collisions with the window boundaries
if (newHeadX < 0 || newHeadX >= bounds.x || newHeadY < 0 ||
newHeadY >= bounds.y) {
ESP_LOGW(TAG, "Snake hit the wall %d %d, %d %d", newHeadX, newHeadY,
bounds.x, bounds.y);
reset();
}
}

int HomeThingAppSnake::root_menu_size() {
return 1;
}
void HomeThingAppSnake::reset_menu() {}
void HomeThingAppSnake::set_app_menu_index(int app_menu_index) {}

// buttons
void HomeThingAppSnake::rotaryScrollClockwise(int rotary) {}
void HomeThingAppSnake::rotaryScrollCounterClockwise(int rotary) {}
homething_menu_app::NavigationCoordination HomeThingAppSnake::buttonPressUp() {
snake_direction_ = Coordinate(-1, 0);
return homething_menu_app::NavigationCoordination::
NavigationCoordinationReturn;
}
homething_menu_app::NavigationCoordination
HomeThingAppSnake::buttonPressDown() {
snake_direction_ = Coordinate(1, 0);
return homething_menu_app::NavigationCoordination::
NavigationCoordinationReturn;
} // namespace homething_app_snake
homething_menu_app::NavigationCoordination
HomeThingAppSnake::buttonPressLeft() {
snake_direction_ = Coordinate(0, -1);
return homething_menu_app::NavigationCoordination::
NavigationCoordinationReturn;
}
homething_menu_app::NavigationCoordination
HomeThingAppSnake::buttonPressRight() {
snake_direction_ = Coordinate(0, 1);
return homething_menu_app::NavigationCoordination::NavigationCoordinationNone;
}
homething_menu_app::NavigationCoordination HomeThingAppSnake::buttonPressSelect(
int menuIndex) {
reset();
if (displayScale < 20) {
displayScale = displayScale + 2;
} else {
displayScale = 2;
}
return homething_menu_app::NavigationCoordination::NavigationCoordinationNone;
}
homething_menu_app::NavigationCoordination
HomeThingAppSnake::buttonPressSelectHold() {
return homething_menu_app::NavigationCoordination::NavigationCoordinationNone;
}
homething_menu_app::NavigationCoordination
HomeThingAppSnake::buttonPressScreenLeft() {
return homething_menu_app::NavigationCoordination::NavigationCoordinationNone;
}
homething_menu_app::NavigationCoordination
HomeThingAppSnake::buttonReleaseScreenLeft() {
return homething_menu_app::NavigationCoordination::NavigationCoordinationNone;
}
homething_menu_app::NavigationCoordination
HomeThingAppSnake::buttonPressScreenRight() {
return homething_menu_app::NavigationCoordination::NavigationCoordinationNone;
}

} // namespace homething_app_snake
} // namespace esphome
111 changes: 111 additions & 0 deletions components/homeThingAppBreakout/homeThingAppSnake.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#pragma once

#include "esphome/components/homeThing/homeThingMenuHeader.h"
#include "esphome/components/homeThingApp/homeThingApp.h"

namespace esphome {
namespace homething_app_snake {

class HomeThingAppSnakeHeader
: public homething_menu_base::HomeThingMenuHeaderSource {
public:
// header
std::string get_header_title() { return "Snake"; }

int draw_header_details(
int xPos, int yPos, display::DisplayBuffer* display_buffer,
homething_display_state::HomeThingDisplayState* display_state,
homething_display_state::HomeThingMenuTextHelpers* text_helpers) {
return 0;
}

protected:
private:
const char* const TAG = "homething.app.snake.header";
};

struct Coordinate {
int x, y;
Coordinate(int newX, int newY) : x(newX), y(newY) {}
};

class HomeThingAppSnake : public homething_menu_app::HomeThingApp {
public:
void reset();
// menu titles
void rootMenuTitles(
std::vector<homething_menu_base::MenuTitleBase*>* menu_titles);

void app_menu_titles(
std::vector<homething_menu_base::MenuTitleBase*>* menu_titles);

// menu screens
homething_menu_app::NavigationCoordination app_menu_select(int index);
bool should_draw_app();
void draw_app(
int menuIndex,
const std::vector<homething_menu_base::MenuTitleBase*>* active_menu);

void idleTick(int idleTime, int display_timeout);
void active_tick();

int root_menu_size();
void reset_menu();
void set_app_menu_index(int app_menu_index);

// buttons
void rotaryScrollClockwise(int rotary);
void rotaryScrollCounterClockwise(int rotary);
homething_menu_app::NavigationCoordination buttonPressUp();
homething_menu_app::NavigationCoordination buttonPressDown();
homething_menu_app::NavigationCoordination buttonPressLeft();
homething_menu_app::NavigationCoordination buttonPressRight();
homething_menu_app::NavigationCoordination buttonPressSelect(int menuIndex);
homething_menu_app::NavigationCoordination buttonPressSelectHold();
homething_menu_app::NavigationCoordination buttonPressScreenLeft();
homething_menu_app::NavigationCoordination buttonReleaseScreenLeft();
homething_menu_app::NavigationCoordination buttonPressScreenRight();

homething_menu_base::HomeThingMenuHeaderSource* get_header_source() {
return header_source_;
}
HomeThingMenuHeaderSource* header_source_ = new HomeThingAppSnakeHeader();

void set_display_buffer(display::DisplayBuffer* display_buffer) {
display_buffer_ = display_buffer;
}

void set_display_state(
homething_display_state::HomeThingDisplayState* display_state) {
display_state_ = display_state;
}

bool is_animating() { return true; }

protected:
private:
const char* const TAG = "homething.app.snake";

// display
display::DisplayBuffer* display_buffer_{nullptr};
homething_display_state::HomeThingDisplayState* display_state_{nullptr};

// menu titles

void sourceMenuTitles(
std::vector<homething_menu_base::MenuTitleBase*>* menu_titles);
void media_player_menu_titles(
std::vector<homething_menu_base::MenuTitleBase*>* menu_titles);

void draw_resized_pixel(int coordinateX, int coordinateY, Color color);
Coordinate get_display_bounds();
void create_new_fruit();
Coordinate get_random_coordinate();
Coordinate fruit_position_ = Coordinate(-1, -1);
Coordinate snake_direction_ = Coordinate(1, 0);
std::vector<Coordinate> snake = {Coordinate(30, 30)};
double displayScale = 16;
int margin = 4;
};
} // namespace homething_app_snake
} // namespace esphome
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ void HomeThingMenuNowPlayingControl::rootMenuTitles(
title = media_player_group_->active_player_->get_name();
}
menu_titles->push_back(new homething_menu_base::MenuTitleBase(
title, "", homething_menu_base::NoMenuTitleRightIcon));
title, "", homething_menu_base::ArrowMenuTitleRightIcon));
menu_titles->push_back(new homething_menu_base::MenuTitleBase(
"Sources", "", homething_menu_base::NoMenuTitleRightIcon));
"Sources", "", homething_menu_base::ArrowMenuTitleRightIcon));
if (media_player_group_->totalPlayers() > 1) {
menu_titles->push_back(new homething_menu_base::MenuTitleBase(
"Media Players", "", homething_menu_base::NoMenuTitleRightIcon));
"Media Players", "", homething_menu_base::ArrowMenuTitleRightIcon));
}
}
}
Expand Down
Loading