scrolled = true;
}
} else {
- if (last != 0 && !scrolled)
+ if (last != 0 && !scrolled) {
Sharp::sendInput(touchToCoord(last));
+ delay(100);
+ }
last = 0;
Sharp::setScroll();
}
delay(10);
}
+static void addNewNote(const char *buf)
+{
+ unsigned int count = (buf[1] - '0') * 10 + (buf[2] - '0');
+ Sharp::addWidget<NoteWidget>(buf + 3, count);
+}
+
void handlePacket(void)
{
char buf[64];
Sharp::addWidget<NotificationWidget>("Time updated");
RTC::setTicks(std::atoi(buf + 1) * 60);
break;
+ case 'N':
+ Vibrate::pulse();
+ addNewNote(buf);
default:
break;
}
#include <bluefruit.h>
nrf_drv_rtc_t RTC::rtc = NRF_DRV_RTC_INSTANCE(2);
-unsigned int RTC::rtcCount = 0;
+uint32_t RTC::rtcCount = 0;
void RTC::begin(void)
{
nrf_drv_rtc_enable(&rtc);
}
+const char *RTC::getDate(char *buf)
+{
+
+}
+
void RTC::handler([[maybe_unused]] nrf_drv_rtc_int_type_t int_type)
{
static unsigned char counter = 0;
if (int_type == NRF_DRV_RTC_INT_TICK) {
if (++counter == 8) {
counter = 0;
- rtcCount++;
+ if (++rtcCount == 86400)
+ rtcCount = 0;
}
}
}
#define RTC_HPP_
#include <rtc/nrf_drv_rtc.h>
+#include <stdint.h>
+
#include "sharp.hpp"
class RTC {
private:
static nrf_drv_rtc_t rtc;
- static unsigned int rtcCount;
+ static uint32_t rtcCount;
public:
static void begin(void);
rtcCount = t;
}
+ static const char *getDate(char *buf);
+
private:
static void handler(nrf_drv_rtc_int_type_t type);
};
TaskHandle_t Sharp::taskHandle;
std::vector<Widget *> Sharp::widgets;
+int Sharp::fullscreenWidget = -1;
int Sharp::topY = 0;
+int Sharp::lowestY = 0;
+
+static int oldTopY = 0;
void Sharp::begin(void)
{
for (unsigned int i = 0; i < widgets.size(); i++) {
y += widgets[i]->getHeight();
if (ypos < y) {
- if (widgets[i]->onPress()) {
+ switch (widgets[i]->onPress()) {
+ case PressAction::Destroy:
delete widgets[i];
widgets.erase(widgets.begin() + i);
display.clearDisplay();
+ break;
+ case PressAction::Fullscreen:
+ if (fullscreenWidget == -1)
+ fullscreenWidget = i;
+ else
+ fullscreenWidget = -1;
+ oldTopY = 1;
+ break;
+ default:
+ break;
}
break;
}
void Sharp::updateTask([[maybe_unused]] void *arg)
{
- static int oldTopY = 0;
-
while (1) {
if (oldTopY != topY) {
oldTopY = topY;
display.clearDisplay();
}
- auto y = topY;
- for (auto& w : widgets) {
- w->render(display, y);
- y += w->getHeight();
- display.drawFastHLine(0, y + 1, SHARP_WIDTH, BLACK);
- y += 3;
- if (y >= SHARP_HEIGHT)
- break;
+ if (fullscreenWidget == -1) {
+ auto y = topY;
+ for (auto& w : widgets) {
+ w->render(display, y);
+ y += w->getHeight();
+ display.drawFastHLine(0, y + 1, SHARP_WIDTH,
+ BLACK);
+ y += 3;
+ if (y >= SHARP_HEIGHT)
+ break;
+ }
+ } else {
+ widgets[fullscreenWidget]->renderFullscreen(display,
+ topY);
}
display.refresh();
static TaskHandle_t taskHandle;
static std::vector<Widget *> widgets;
+ static int fullscreenWidget;
static int topY;
+ static int lowestY;
public:
static void begin(void);
template<class T, typename... Args>
inline static void addWidget(Args... args) {
widgets.emplace_back(new T(args...));
+ lowestY = 0;
+ for (unsigned int i = 0; i < widgets.size() - 1; i++)
+ lowestY -= widgets[i]->getHeight() + 3;
+ if (lowestY != 0)
+ lowestY++;
}
inline static void setScroll(int scr = 0) {
oldTopY = topY;
} else {
topY = minof(0, oldTopY + scr);
+ topY = maxof(lowestY, topY);
}
}
#include "rtc.hpp"
#include "widget.hpp"
+PressAction TimeWidget::onPress(void)
+{
+ if (getHeight() == 30)
+ setHeight(SHARP_HEIGHT);
+ else
+ setHeight(30);
+
+ return PressAction::Fullscreen;
+}
+
void TimeWidget::render(Adafruit_GFX& display, int ypos)
{
if (auto t = RTC::ticks(); t != prevTicks) {
prevTicks = t;
display.setTextSize(3);
display.setCursor(0, ypos + 4);
- display.printf("%2d:%02d:%02d", t / 3600, (t % 3600) /
- 60, t % 60);
+ display.printf("%2d:%02d:%02d", t / 3600, (t % 3600) / 60,
+ t % 60);
}
}
+void TimeWidget::renderFullscreen(Adafruit_GFX& display, int ypos)
+{
+ if (auto t = RTC::ticks(); t != prevTicks) {
+ prevTicks = t;
+ display.setTextSize(4);
+ display.setCursor(12, SHARP_HEIGHT / 3);
+ display.printf("%2d:%02d", t / 3600, (t % 3600) / 60);
+ }
+
+}
+
void NotificationWidget::render(Adafruit_GFX& display, int ypos)
{
display.setTextSize(2);
display.setCursor(0, ypos);
display.printf("%-36s", message);
}
+
+void NoteWidget::render(Adafruit_GFX& display, int ypos)
+{
+ display.setTextSize(2);
+ display.setCursor(0, ypos);
+ display.printf("NOTE:\n%9s...", text);
+}
+
+void NoteWidget::renderFullscreen(Adafruit_GFX& display, int ypos)
+{
+ display.setTextSize(2);
+ display.setCursor(0, ypos);
+ display.print(text);
+}
+
+PressAction NoteWidget::onPress(void)
+{
+ if (getHeight() == 24)
+ setHeight(SHARP_HEIGHT);
+ else
+ setHeight(24);
+
+ return PressAction::Fullscreen;
+}
+
#include <bluefruit.h>
#include <cstring>
+enum class PressAction {
+ Nothing = 0,
+ Destroy,
+ Fullscreen
+};
+
class Widget {
private:
unsigned int height;
return height;
}
+ virtual void renderFullscreen([[maybe_unused]] Adafruit_GFX& display,
+ [[maybe_unused]] int ypos) {}
virtual void render(Adafruit_GFX& display, int ypos) = 0;
- virtual bool onPress(void) = 0;
+ virtual PressAction onPress(void) = 0;
protected:
inline void setHeight(unsigned int _height) {
: Widget(30), prevTicks(0) {}
void render(Adafruit_GFX& display, int ypos) final;
- bool onPress(void) final {
- return false;
- }
+ void renderFullscreen(Adafruit_GFX& display, int ypos) final;
+ PressAction onPress(void) final;
};
class NotificationWidget : public Widget {
}
void render(Adafruit_GFX& display, int ypos) final;
- bool onPress(void) final {
- return true;
+ PressAction onPress(void) final {
+ return PressAction::Destroy;
+ }
+};
+
+class NoteWidget : public Widget {
+private:
+ char *text;
+
+public:
+ NoteWidget(const char *t, unsigned int size)
+ : Widget(24) {
+ text = new char[size];
+ for (unsigned int i = 0; i < size; i++)
+ text[i] = t[i];
}
+ ~NoteWidget(void) {
+ delete[] text;
+ }
+
+ void render(Adafruit_GFX& display, int ypos) final;
+ void renderFullscreen(Adafruit_GFX& display, int ypos) final;
+ PressAction onPress(void) final;
};
#endif // WIDGET_HPP_