Skip to content

Instantly share code, notes, and snippets.

@JF002
Created May 1, 2024 09:55
Show Gist options
  • Save JF002/7ecb65cc105a4ec0cd49959a409fb46d to your computer and use it in GitHub Desktop.
Save JF002/7ecb65cc105a4ec0cd49959a409fb46d to your computer and use it in GitHub Desktop.
Drawing arbitrary buffer to the display of the PineTime by hacking the InfiniPaint application
#include "displayapp/screens/InfiniPaint.h"
#include "displayapp/DisplayApp.h"
#include "displayapp/LittleVgl.h"
#include "displayapp/InfiniTimeTheme.h"
#include <algorithm> // std::fill
using namespace Pinetime::Applications::Screens;
InfiniPaint::InfiniPaint(Pinetime::Components::LittleVgl& lvgl, Pinetime::Controllers::MotorController& motor)
: lvgl {lvgl}, motor {motor} {
}
InfiniPaint::~InfiniPaint() {
lv_obj_clean(lv_scr_act());
}
bool InfiniPaint::OnTouchEvent(Pinetime::Applications::TouchEvents /*event*/) {
return true;
}
lv_color_t InfiniPaint::GetNextColor() {
color = (color + 1) % 8;
switch (color) {
case 0:
selectColor = LV_COLOR_MAGENTA;
break;
case 1:
selectColor = Colors::green;
break;
case 2:
selectColor = LV_COLOR_WHITE;
break;
case 3:
selectColor = LV_COLOR_RED;
break;
case 4:
selectColor = LV_COLOR_CYAN;
break;
case 5:
selectColor = LV_COLOR_YELLOW;
break;
case 6:
selectColor = LV_COLOR_BLUE;
break;
case 7:
selectColor = LV_COLOR_BLACK;
break;
default:
color = 0;
break;
}
return selectColor;
}
bool InfiniPaint::OnTouchEvent(uint16_t /*x*/, uint16_t /*y*/) {
lv_area_t area;
lvgl.SetFullRefresh(Components::LittleVgl::FullRefreshDirections::None);
bool toggle = false;
lv_color_t* lineBuffer;
for(int row = 0; row < 239;) {
lv_color_t lineColor;
if(toggle) {
lineColor = GetNextColor();
std::fill(oneLineBufferA.begin(), oneLineBufferA.end(), lineColor);
lineBuffer = oneLineBufferA.data();
}
else {
lineColor = GetNextColor();
std::fill(oneLineBufferB.begin(), oneLineBufferB.end(), lineColor);
lineBuffer = oneLineBufferB.data();
}
toggle = !toggle;
for(int i = 0; i < 24; i++) {
area.x1 = 0;
area.y1 = row;
area.x2 = 239;
area.y2 = row;
lvgl.FlushDisplay(&area, lineBuffer);
row++;
}
}
return true;
}
#pragma once
#include <lvgl/lvgl.h>
#include <cstdint>
#include <algorithm> // std::fill
#include "displayapp/screens/Screen.h"
#include "components/motor/MotorController.h"
#include "Symbols.h"
#include "displayapp/apps/Apps.h"
#include <displayapp/Controllers.h>
namespace Pinetime {
namespace Components {
class LittleVgl;
}
namespace Applications {
namespace Screens {
class InfiniPaint : public Screen {
public:
InfiniPaint(Pinetime::Components::LittleVgl& lvgl, Controllers::MotorController& motor);
~InfiniPaint() override;
bool OnTouchEvent(TouchEvents event) override;
bool OnTouchEvent(uint16_t x, uint16_t y) override;
private:
Pinetime::Components::LittleVgl& lvgl;
Controllers::MotorController& motor;
std::array<lv_color_t, 240> oneLineBufferA;
std::array<lv_color_t, 240> oneLineBufferB;
lv_color_t selectColor = LV_COLOR_WHITE;
uint8_t color = 2;
lv_color_t GetNextColor();
};
}
template <>
struct AppTraits<Apps::Paint> {
static constexpr Apps app = Apps::Paint;
static constexpr const char* icon = Screens::Symbols::paintbrush;
static Screens::Screen* Create(AppControllers& controllers) {
return new Screens::InfiniPaint(controllers.lvgl, controllers.motorController);
};
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment