v0.9.670
This commit is contained in:
@@ -1,8 +1,13 @@
|
||||
#include "../dspcore.h"
|
||||
#include "../../core/options.h"
|
||||
#if DSP_MODEL!=DSP_DUMMY
|
||||
|
||||
#include "../dspcore.h"
|
||||
#include "Arduino.h"
|
||||
#include "widgets.h"
|
||||
#include "../../core/player.h" // for VU widget
|
||||
#include "../../core/network.h" // for Clock widget
|
||||
#include "../../core/config.h"
|
||||
#include "../tools/l10n.h"
|
||||
#include "../tools/psframebuffer.h"
|
||||
|
||||
/************************
|
||||
FILL WIDGET
|
||||
@@ -31,6 +36,16 @@ TextWidget::~TextWidget() {
|
||||
free(_oldtext);
|
||||
}
|
||||
|
||||
void TextWidget::_charSize(uint8_t textsize, uint8_t& width, uint16_t& height){
|
||||
#ifndef DSP_LCD
|
||||
width = textsize * CHARWIDTH;
|
||||
height = textsize * CHARHEIGHT;
|
||||
#else
|
||||
width = 1;
|
||||
height = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void TextWidget::init(WidgetConfig wconf, uint16_t buffsize, bool uppercase, uint16_t fgcolor, uint16_t bgcolor) {
|
||||
Widget::init(wconf, fgcolor, bgcolor);
|
||||
_buffsize = buffsize;
|
||||
@@ -38,15 +53,13 @@ void TextWidget::init(WidgetConfig wconf, uint16_t buffsize, bool uppercase, uin
|
||||
memset(_text, 0, _buffsize);
|
||||
_oldtext = (char *) malloc(sizeof(char) * _buffsize);
|
||||
memset(_oldtext, 0, _buffsize);
|
||||
//_charWidth = wconf.textsize * CHARWIDTH; // default GFX font
|
||||
//_textheight = wconf.textsize * CHARHEIGHT; // default GFX font
|
||||
dsp.charSize(_config.textsize, _charWidth, _textheight);
|
||||
_charSize(_config.textsize, _charWidth, _textheight);
|
||||
_textwidth = _oldtextwidth = _oldleft = 0;
|
||||
_uppercase = uppercase;
|
||||
}
|
||||
|
||||
void TextWidget::setText(const char* txt) {
|
||||
strlcpy(_text, dsp.utf8Rus(txt, _uppercase), _buffsize);
|
||||
strlcpy(_text, utf8Rus(txt, _uppercase), _buffsize);
|
||||
_textwidth = strlen(_text) * _charWidth;
|
||||
if (strcmp(_oldtext, _text) == 0) return;
|
||||
if (_active) dsp.fillRect(_oldleft == 0 ? _realLeft() : min(_oldleft, _realLeft()), _config.top, max(_oldtextwidth, _textwidth), _textheight, _bgcolor);
|
||||
@@ -67,11 +80,12 @@ void TextWidget::setText(const char* txt, const char *format){
|
||||
setText(buf);
|
||||
}
|
||||
|
||||
uint16_t TextWidget::_realLeft() {
|
||||
uint16_t TextWidget::_realLeft(bool w_fb) {
|
||||
uint16_t realwidth = (_width>0 && w_fb)?_width:dsp.width();
|
||||
switch (_config.align) {
|
||||
case WA_CENTER: return (dsp.width() - _textwidth) / 2; break;
|
||||
case WA_RIGHT: return (dsp.width() - _textwidth - _config.left); break;
|
||||
default: return _config.left; break;
|
||||
case WA_CENTER: return (realwidth - _textwidth) / 2; break;
|
||||
case WA_RIGHT: return (realwidth - _textwidth - (!w_fb?_config.left:0)); break;
|
||||
default: return !w_fb?_config.left:0; break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +107,7 @@ ScrollWidget::ScrollWidget(const char* separator, ScrollConfig conf, uint16_t fg
|
||||
}
|
||||
|
||||
ScrollWidget::~ScrollWidget() {
|
||||
free(_fb);
|
||||
free(_sep);
|
||||
free(_window);
|
||||
}
|
||||
@@ -106,21 +121,31 @@ void ScrollWidget::init(const char* separator, ScrollConfig conf, uint16_t fgcol
|
||||
_startscrolldelay = conf.startscrolldelay;
|
||||
_scrolldelta = conf.scrolldelta;
|
||||
_scrolltime = conf.scrolltime;
|
||||
//_charWidth = CHARWIDTH * _config.textsize; // default GFX font
|
||||
//_textheight = CHARHEIGHT * _config.textsize; // default GFX font
|
||||
dsp.charSize(_config.textsize, _charWidth, _textheight);
|
||||
_charSize(_config.textsize, _charWidth, _textheight);
|
||||
_sepwidth = strlen(_sep) * _charWidth;
|
||||
_width = conf.width;
|
||||
_backMove.width = _width;
|
||||
_window = (char *) malloc(sizeof(char) * (MAX_WIDTH / _charWidth + 1));
|
||||
memset(_window, 0, (MAX_WIDTH / _charWidth + 1)); // +1?
|
||||
_doscroll = false;
|
||||
#ifdef PSFBUFFER
|
||||
_fb = new psFrameBuffer(dsp.width(), dsp.height());
|
||||
uint16_t _rl = (_config.align==WA_CENTER)?(dsp.width()-_width)/2:_config.left;
|
||||
_fb->begin(&dsp, _rl, _config.top, _width, _textheight, _bgcolor);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ScrollWidget::_setTextParams() {
|
||||
if (_config.textsize == 0) return;
|
||||
dsp.setTextSize(_config.textsize);
|
||||
dsp.setTextColor(_fgcolor, _bgcolor);
|
||||
if(_fb->ready()){
|
||||
#ifdef PSFBUFFER
|
||||
_fb->setTextSize(_config.textsize);
|
||||
_fb->setTextColor(_fgcolor, _bgcolor);
|
||||
#endif
|
||||
}else{
|
||||
dsp.setTextSize(_config.textsize);
|
||||
dsp.setTextColor(_fgcolor, _bgcolor);
|
||||
}
|
||||
}
|
||||
|
||||
bool ScrollWidget::_checkIsScrollNeeded() {
|
||||
@@ -128,28 +153,47 @@ bool ScrollWidget::_checkIsScrollNeeded() {
|
||||
}
|
||||
|
||||
void ScrollWidget::setText(const char* txt) {
|
||||
strlcpy(_text, dsp.utf8Rus(txt, _uppercase), _buffsize - 1);
|
||||
strlcpy(_text, utf8Rus(txt, _uppercase), _buffsize - 1);
|
||||
if (strcmp(_oldtext, _text) == 0) return;
|
||||
_textwidth = strlen(_text) * _charWidth;
|
||||
_x = _config.left;
|
||||
_x = _fb->ready()?0:_config.left;
|
||||
_doscroll = _checkIsScrollNeeded();
|
||||
if (dsp.getScrollId() == this) dsp.setScrollId(NULL);
|
||||
_scrolldelay = millis();
|
||||
if (_active) {
|
||||
_setTextParams();
|
||||
if (_doscroll) {
|
||||
if(_fb->ready()){
|
||||
#ifdef PSFBUFFER
|
||||
_fb->fillRect(0, 0, _width, _textheight, _bgcolor);
|
||||
_fb->setCursor(0, 0);
|
||||
snprintf(_window, _width / _charWidth + 1, "%s", _text); //TODO
|
||||
_fb->print(_window);
|
||||
_fb->display();
|
||||
#endif
|
||||
} else {
|
||||
dsp.fillRect(_config.left, _config.top, _width, _textheight, _bgcolor);
|
||||
dsp.setCursor(_config.left, _config.top);
|
||||
snprintf(_window, _width / _charWidth + 1, "%s", _text); //TODO
|
||||
dsp.setClipping({_config.left, _config.top, _width, _textheight});
|
||||
dsp.print(_window);
|
||||
dsp.clearClipping();
|
||||
}
|
||||
} else {
|
||||
dsp.fillRect(_config.left, _config.top, _width, _textheight, _bgcolor);
|
||||
dsp.setCursor(_realLeft(), _config.top);
|
||||
//dsp.setClipping({_config.left, _config.top, _width, _textheight});
|
||||
dsp.print(_text);
|
||||
//dsp.clearClipping();
|
||||
if(_fb->ready()){
|
||||
#ifdef PSFBUFFER
|
||||
_fb->fillRect(0, 0, _width, _textheight, _bgcolor);
|
||||
_fb->setCursor(_realLeft(true), 0);
|
||||
_fb->print(_text);
|
||||
_fb->display();
|
||||
#endif
|
||||
} else {
|
||||
dsp.fillRect(_config.left, _config.top, _width, _textheight, _bgcolor);
|
||||
dsp.setCursor(_realLeft(), _config.top);
|
||||
//dsp.setClipping({_config.left, _config.top, _width, _textheight});
|
||||
dsp.print(_text);
|
||||
//dsp.clearClipping();
|
||||
}
|
||||
}
|
||||
strlcpy(_oldtext, _text, _buffsize);
|
||||
}
|
||||
@@ -164,21 +208,30 @@ void ScrollWidget::setText(const char* txt, const char *format){
|
||||
void ScrollWidget::loop() {
|
||||
if(_locked) return;
|
||||
if (!_doscroll || _config.textsize == 0 || (dsp.getScrollId() != NULL && dsp.getScrollId() != this)) return;
|
||||
if (_checkDelay(_x == _config.left ? _startscrolldelay : _scrolltime, _scrolldelay)) {
|
||||
uint16_t fbl = _fb->ready()?0:_config.left;
|
||||
if (_checkDelay(_x == fbl ? _startscrolldelay : _scrolltime, _scrolldelay)) {
|
||||
_calcX();
|
||||
if (_active) _draw();
|
||||
}
|
||||
}
|
||||
|
||||
void ScrollWidget::_clear(){
|
||||
dsp.fillRect(_config.left, _config.top, _width, _textheight, _bgcolor);
|
||||
if(_fb->ready()){
|
||||
#ifdef PSFBUFFER
|
||||
_fb->fillRect(0, 0, _width, _textheight, _bgcolor);
|
||||
_fb->display();
|
||||
#endif
|
||||
} else {
|
||||
dsp.fillRect(_config.left, _config.top, _width, _textheight, _bgcolor);
|
||||
}
|
||||
}
|
||||
|
||||
void ScrollWidget::_draw() {
|
||||
if(!_active || _locked) return;
|
||||
_setTextParams();
|
||||
if (_doscroll) {
|
||||
uint16_t _newx = _config.left - _x;
|
||||
uint16_t fbl = _fb->ready()?0:_config.left;
|
||||
uint16_t _newx = fbl - _x;
|
||||
const char* _cursor = _text + _newx / _charWidth;
|
||||
uint16_t hiddenChars = _cursor - _text;
|
||||
if (hiddenChars < strlen(_text)) {
|
||||
@@ -187,27 +240,45 @@ void ScrollWidget::_draw() {
|
||||
const char* _scursor = _sep + (_cursor - (_text + strlen(_text)));
|
||||
snprintf(_window, _width / _charWidth + 1, "%s%s", _scursor, _text);
|
||||
}
|
||||
dsp.setCursor(_x + hiddenChars * _charWidth, _config.top);
|
||||
dsp.setClipping({_config.left, _config.top, _width, _textheight});
|
||||
dsp.print(_window);
|
||||
#ifndef DSP_LCD
|
||||
dsp.print(" ");
|
||||
if(_fb->ready()){
|
||||
#ifdef PSFBUFFER
|
||||
_fb->setCursor(_x + hiddenChars * _charWidth, 0);
|
||||
_fb->print(_window);
|
||||
_fb->display();
|
||||
#endif
|
||||
dsp.clearClipping();
|
||||
} else {
|
||||
dsp.setCursor(_x + hiddenChars * _charWidth, _config.top);
|
||||
dsp.setClipping({_config.left, _config.top, _width, _textheight});
|
||||
dsp.print(_window);
|
||||
#ifndef DSP_LCD
|
||||
dsp.print(" ");
|
||||
#endif
|
||||
dsp.clearClipping();
|
||||
}
|
||||
} else {
|
||||
dsp.fillRect(_config.left, _config.top, _width, _textheight, _bgcolor);
|
||||
dsp.setCursor(_realLeft(), _config.top);
|
||||
dsp.setClipping({_realLeft(), _config.top, _width, _textheight});
|
||||
dsp.print(_text);
|
||||
dsp.clearClipping();
|
||||
if(_fb->ready()){
|
||||
#ifdef PSFBUFFER
|
||||
_fb->fillRect(0, 0, _width, _textheight, _bgcolor);
|
||||
_fb->setCursor(_realLeft(true), 0);
|
||||
_fb->print(_text);
|
||||
_fb->display();
|
||||
#endif
|
||||
} else {
|
||||
dsp.fillRect(_config.left, _config.top, _width, _textheight, _bgcolor);
|
||||
dsp.setCursor(_realLeft(), _config.top);
|
||||
dsp.setClipping({_realLeft(), _config.top, _width, _textheight});
|
||||
dsp.print(_text);
|
||||
dsp.clearClipping();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScrollWidget::_calcX() {
|
||||
if (!_doscroll || _config.textsize == 0) return;
|
||||
_x -= _scrolldelta;
|
||||
if (-_x > _textwidth + _sepwidth - _config.left) {
|
||||
_x = _config.left;
|
||||
uint16_t fbl = _fb->ready()?0:_config.left;
|
||||
if (-_x > _textwidth + _sepwidth - fbl) {
|
||||
_x = fbl;
|
||||
dsp.setScrollId(NULL);
|
||||
} else {
|
||||
dsp.setScrollId(this);
|
||||
@@ -225,9 +296,14 @@ bool ScrollWidget::_checkDelay(int m, uint32_t &tstamp) {
|
||||
|
||||
void ScrollWidget::_reset(){
|
||||
dsp.setScrollId(NULL);
|
||||
_x = _config.left;
|
||||
_x = _fb->ready()?0:_config.left;
|
||||
_scrolldelay = millis();
|
||||
_doscroll = _checkIsScrollNeeded();
|
||||
#ifdef PSFBUFFER
|
||||
_fb->freeBuffer();
|
||||
uint16_t _rl = (_config.align==WA_CENTER)?(dsp.width()-_width)/2:_config.left;
|
||||
_fb->begin(&dsp, _rl, _config.top, _width, _textheight, _bgcolor);
|
||||
#endif
|
||||
}
|
||||
|
||||
/************************
|
||||
@@ -343,12 +419,26 @@ void VuWidget::_draw(){
|
||||
#else
|
||||
_canvas->fillRect(0, 0, _bands.width-(_bands.width-measL), _bands.width, _bgcolor);
|
||||
_canvas->fillRect(_bands.width * 2 + _bands.space - measR, 0, measR, _bands.width, _bgcolor);
|
||||
#if DSP_MODEL!=DSP_ILI9225
|
||||
dsp.startWrite();
|
||||
dsp.setAddrWindow(_config.left, _config.top, _bands.width * 2 + _bands.space, _bands.height);
|
||||
dsp.writePixels((uint16_t*)_canvas->getBuffer(), (_bands.width * 2 + _bands.space)*_bands.height);
|
||||
dsp.endWrite();
|
||||
#else
|
||||
dsp.drawRGBBitmap(_config.left, _config.top, _canvas->getBuffer(), _bands.width * 2 + _bands.space, _bands.height);
|
||||
#endif
|
||||
#endif
|
||||
}else{
|
||||
_canvas->fillRect(0, 0, _bands.width, measL, _bgcolor);
|
||||
_canvas->fillRect(_bands.width + _bands.space, 0, _bands.width, measR, _bgcolor);
|
||||
#if DSP_MODEL!=DSP_ILI9225
|
||||
dsp.startWrite();
|
||||
dsp.setAddrWindow(_config.left, _config.top, _bands.width * 2 + _bands.space, _bands.height);
|
||||
dsp.writePixels((uint16_t*)_canvas->getBuffer(), (_bands.width * 2 + _bands.space)*_bands.height);
|
||||
dsp.endWrite();
|
||||
#else
|
||||
dsp.drawRGBBitmap(_config.left, _config.top, _canvas->getBuffer(), _bands.width * 2 + _bands.space, _bands.height);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,6 +458,53 @@ void VuWidget::_draw(){ }
|
||||
void VuWidget::loop(){ }
|
||||
void VuWidget::_clear(){ }
|
||||
#endif
|
||||
|
||||
/************************
|
||||
NUM & CLOCK
|
||||
************************/
|
||||
#if !defined(DSP_LCD)
|
||||
#if TIME_SIZE<19 //19->NOKIA
|
||||
const GFXfont* Clock_GFXfontPtr = nullptr;
|
||||
#define CLOCKFONT5x7
|
||||
#else
|
||||
const GFXfont* Clock_GFXfontPtr = &Clock_GFXfont;
|
||||
#endif
|
||||
#endif //!defined(DSP_LCD)
|
||||
|
||||
#if !defined(CLOCKFONT5x7) && !defined(DSP_LCD)
|
||||
inline GFXglyph *pgm_read_glyph_ptr(const GFXfont *gfxFont, uint8_t c) {
|
||||
return gfxFont->glyph + c;
|
||||
}
|
||||
uint8_t _charWidth(unsigned char c){
|
||||
GFXglyph *glyph = pgm_read_glyph_ptr(&Clock_GFXfont, c - 0x20);
|
||||
return pgm_read_byte(&glyph->xAdvance);
|
||||
}
|
||||
uint16_t _textHeight(){
|
||||
GFXglyph *glyph = pgm_read_glyph_ptr(&Clock_GFXfont, '8' - 0x20);
|
||||
return pgm_read_byte(&glyph->height);
|
||||
}
|
||||
#else //!defined(CLOCKFONT5x7) && !defined(DSP_LCD)
|
||||
uint8_t _charWidth(unsigned char c){
|
||||
#ifndef DSP_LCD
|
||||
return CHARWIDTH * TIME_SIZE;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
uint16_t _textHeight(){
|
||||
return CHARHEIGHT * TIME_SIZE;
|
||||
}
|
||||
#endif
|
||||
uint16_t _textWidth(const char *txt){
|
||||
uint16_t w = 0, l=strlen(txt);
|
||||
for(uint16_t c=0;c<l;c++) w+=_charWidth(txt[c]);
|
||||
#if DSP_MODEL==DSP_ILI9225
|
||||
return w+l;
|
||||
#else
|
||||
return w;
|
||||
#endif
|
||||
}
|
||||
|
||||
/************************
|
||||
NUM WIDGET
|
||||
************************/
|
||||
@@ -380,7 +517,7 @@ void NumWidget::init(WidgetConfig wconf, uint16_t buffsize, bool uppercase, uint
|
||||
memset(_oldtext, 0, _buffsize);
|
||||
_textwidth = _oldtextwidth = _oldleft = 0;
|
||||
_uppercase = uppercase;
|
||||
_textheight = wconf.textsize;
|
||||
_textheight = TIME_SIZE/*wconf.textsize*/;
|
||||
}
|
||||
|
||||
void NumWidget::setText(const char* txt) {
|
||||
@@ -389,9 +526,15 @@ void NumWidget::setText(const char* txt) {
|
||||
if (strcmp(_oldtext, _text) == 0) return;
|
||||
uint16_t realth = _textheight;
|
||||
#if defined(DSP_OLED) && DSP_MODEL!=DSP_SSD1322
|
||||
realth = _textheight*CHARHEIGHT;
|
||||
if(Clock_GFXfontPtr==nullptr) realth = _textheight * 8; //CHARHEIGHT
|
||||
#endif
|
||||
if (_active) dsp.fillRect(_oldleft == 0 ? _realLeft() : min(_oldleft, _realLeft()), _config.top-_textheight+1, max(_oldtextwidth, _textwidth), realth, _bgcolor);
|
||||
if (_active)
|
||||
#ifndef CLOCKFONT5x7
|
||||
dsp.fillRect(_oldleft == 0 ? _realLeft() : min(_oldleft, _realLeft()), _config.top-_textheight+1, max(_oldtextwidth, _textwidth), realth, _bgcolor);
|
||||
#else
|
||||
dsp.fillRect(_oldleft == 0 ? _realLeft() : min(_oldleft, _realLeft()), _config.top, max(_oldtextwidth, _textwidth), realth, _bgcolor);
|
||||
#endif
|
||||
|
||||
_oldtextwidth = _textwidth;
|
||||
_oldleft = _realLeft();
|
||||
if (_active) _draw();
|
||||
@@ -404,14 +547,17 @@ void NumWidget::setText(int val, const char *format){
|
||||
}
|
||||
|
||||
void NumWidget::_getBounds() {
|
||||
_textwidth= dsp.textWidth(_text);
|
||||
_textwidth= _textWidth(_text);
|
||||
}
|
||||
|
||||
void NumWidget::_draw() {
|
||||
if(!_active) return;
|
||||
dsp.setNumFont(); // --------------SetBigFont
|
||||
//dsp.setTextSize(1);
|
||||
#ifndef DSP_LCD
|
||||
if(!_active || TIME_SIZE<2) return;
|
||||
dsp.setTextSize(Clock_GFXfontPtr==nullptr?TIME_SIZE:1);
|
||||
dsp.setFont(Clock_GFXfontPtr);
|
||||
dsp.setTextColor(_fgcolor, _bgcolor);
|
||||
#endif
|
||||
if(!_active) return;
|
||||
dsp.setCursor(_realLeft(), _config.top);
|
||||
dsp.print(_text);
|
||||
strlcpy(_oldtext, _text, _buffsize);
|
||||
@@ -446,26 +592,235 @@ void ProgressWidget::loop() {
|
||||
/**************************
|
||||
CLOCK WIDGET
|
||||
**************************/
|
||||
void ClockWidget::init(WidgetConfig wconf, uint16_t fgcolor, uint16_t bgcolor){
|
||||
Widget::init(wconf, fgcolor, bgcolor);
|
||||
_timeheight = _textHeight();
|
||||
_fullclock = TIME_SIZE>35 || DSP_MODEL==DSP_ILI9225;
|
||||
if(_fullclock) _superfont = TIME_SIZE / 17; //magick
|
||||
else if(TIME_SIZE==19 || TIME_SIZE==2) _superfont=1;
|
||||
else _superfont=0;
|
||||
_space = (5*_superfont)/2; //magick
|
||||
if(_fullclock){
|
||||
_dateheight = _superfont<4?1:2;
|
||||
_clockheight = _timeheight + _space + CHARHEIGHT * _dateheight;
|
||||
} else {
|
||||
_clockheight = _timeheight;
|
||||
}
|
||||
_getTimeBounds();
|
||||
#ifdef PSFBUFFER
|
||||
_fb = new psFrameBuffer(dsp.width(), dsp.height());
|
||||
_begin();
|
||||
#endif
|
||||
}
|
||||
|
||||
void ClockWidget::_begin(){
|
||||
#ifdef PSFBUFFER
|
||||
_fb->begin(&dsp, _clockleft, _config.top-_timeheight, _clockwidth, _clockheight+1, config.theme.background);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ClockWidget::_getTime(){
|
||||
strftime(_timebuffer, sizeof(_timebuffer), "%H:%M", &network.timeinfo);
|
||||
bool ret = network.timeinfo.tm_sec==0 || _forceflag!=network.timeinfo.tm_year;
|
||||
_forceflag = network.timeinfo.tm_year;
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint16_t ClockWidget::_left(){
|
||||
if(_fb->ready()) return 0; else return _clockleft;
|
||||
}
|
||||
uint16_t ClockWidget::_top(){
|
||||
if(_fb->ready()) return _timeheight; else return _config.top;
|
||||
}
|
||||
|
||||
void ClockWidget::_getTimeBounds() {
|
||||
_timewidth = _textWidth(_timebuffer);
|
||||
uint8_t fs = _superfont>0?_superfont:TIME_SIZE;
|
||||
uint16_t rightside = CHARWIDTH * fs * 2; // seconds
|
||||
if(_fullclock){
|
||||
rightside += _space*2+1; //2space+vline
|
||||
_clockwidth = _timewidth+rightside;
|
||||
} else {
|
||||
if(_superfont==0)
|
||||
_clockwidth = _timewidth;
|
||||
else
|
||||
_clockwidth = _timewidth + rightside;
|
||||
}
|
||||
switch(_config.align){
|
||||
case WA_LEFT: _clockleft = _config.left; break;
|
||||
case WA_RIGHT: _clockleft = dsp.width()-_clockwidth-_config.left; break;
|
||||
default:
|
||||
_clockleft = (dsp.width()/2 - _clockwidth/2)+_config.left;
|
||||
break;
|
||||
}
|
||||
char buf[4];
|
||||
strftime(buf, 4, "%H", &network.timeinfo);
|
||||
_dotsleft=_textWidth(buf);
|
||||
}
|
||||
|
||||
#ifndef DSP_LCD
|
||||
#if DSP_MODEL==DSP_ILI9225
|
||||
auto& ClockWidget::getRealDsp(){
|
||||
return dsp;
|
||||
}
|
||||
#else
|
||||
Adafruit_GFX& ClockWidget::getRealDsp(){
|
||||
#ifdef PSFBUFFER
|
||||
if (_fb && _fb->ready()) return *_fb;
|
||||
#endif
|
||||
return dsp;
|
||||
}
|
||||
#endif
|
||||
void ClockWidget::_printClock(bool force){
|
||||
auto& gfx = getRealDsp();
|
||||
gfx.setTextSize(Clock_GFXfontPtr==nullptr?TIME_SIZE:1);
|
||||
gfx.setFont(Clock_GFXfontPtr);
|
||||
bool clockInTitle=!config.isScreensaver && _config.top<_timeheight; //DSP_SSD1306x32
|
||||
if(force){
|
||||
_clearClock();
|
||||
_getTimeBounds();
|
||||
#ifndef DSP_OLED
|
||||
if(CLOCKFONT_MONO) {
|
||||
gfx.setTextColor(config.theme.clockbg, config.theme.background);
|
||||
gfx.setCursor(_left(), _top());
|
||||
gfx.print("88:88");
|
||||
}
|
||||
#endif
|
||||
if(clockInTitle)
|
||||
gfx.setTextColor(config.theme.meta, config.theme.metabg);
|
||||
else
|
||||
gfx.setTextColor(config.theme.clock, config.theme.background);
|
||||
gfx.setCursor(_left(), _top());
|
||||
gfx.print(_timebuffer);
|
||||
if(_fullclock){
|
||||
// lines, date & dow
|
||||
bool fullClockOnScreensaver = (!config.isScreensaver || (_fb->ready() && FULL_SCR_CLOCK));
|
||||
_linesleft = _left()+_timewidth+_space;
|
||||
if(fullClockOnScreensaver){
|
||||
gfx.drawFastVLine(_linesleft, _top()-_timeheight, _timeheight, config.theme.div);
|
||||
gfx.drawFastHLine(_linesleft, _top()-(_timeheight)/2, CHARWIDTH * _superfont * 2 + _space, config.theme.div);
|
||||
gfx.setFont();
|
||||
gfx.setTextSize(_superfont);
|
||||
gfx.setCursor(_linesleft+_space+1, _top()-CHARHEIGHT * _superfont);
|
||||
gfx.setTextColor(config.theme.dow, config.theme.background);
|
||||
gfx.print(utf8Rus(LANG::dow[network.timeinfo.tm_wday], false));
|
||||
sprintf(_tmp, "%2d %s %d", network.timeinfo.tm_mday,LANG::mnths[network.timeinfo.tm_mon], network.timeinfo.tm_year+1900);
|
||||
strlcpy(_datebuf, utf8Rus(_tmp, true), sizeof(_datebuf));
|
||||
uint16_t _datewidth = strlen(_datebuf) * CHARWIDTH*_dateheight;
|
||||
gfx.setTextSize(_dateheight);
|
||||
#if DSP_MODEL==DSP_GC9A01A
|
||||
gfx.setCursor((dsp.width()-_datewidth)/2, _top() + _space);
|
||||
#else
|
||||
gfx.setCursor(_left()+_clockwidth-_datewidth, _top() + _space);
|
||||
#endif
|
||||
gfx.setTextColor(config.theme.date, config.theme.background);
|
||||
gfx.print(_datebuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(_fullclock || _superfont>0){
|
||||
gfx.setFont();
|
||||
gfx.setTextSize(_superfont);
|
||||
if(!_fullclock){
|
||||
#ifndef CLOCKFONT5x7
|
||||
gfx.setCursor(_left()+_timewidth+_space, _top()-_timeheight+_space);
|
||||
#else
|
||||
gfx.setCursor(_left()+_timewidth+_space, _top());
|
||||
#endif
|
||||
}else{
|
||||
gfx.setCursor(_linesleft+_space+1, _top()-_timeheight);
|
||||
}
|
||||
gfx.setTextColor(config.theme.seconds, config.theme.background);
|
||||
sprintf(_tmp, "%02d", network.timeinfo.tm_sec);
|
||||
gfx.print(_tmp);
|
||||
}
|
||||
gfx.setTextSize(Clock_GFXfontPtr==nullptr?TIME_SIZE:1);
|
||||
gfx.setFont(Clock_GFXfontPtr);
|
||||
#ifndef DSP_OLED
|
||||
gfx.setTextColor(dots ? config.theme.clock : (CLOCKFONT_MONO?config.theme.clockbg:config.theme.background), config.theme.background);
|
||||
#else
|
||||
if(clockInTitle)
|
||||
gfx.setTextColor(dots ? config.theme.meta:config.theme.metabg, config.theme.metabg);
|
||||
else
|
||||
gfx.setTextColor(dots ? config.theme.clock:config.theme.background, config.theme.background);
|
||||
#endif
|
||||
dots=!dots;
|
||||
gfx.setCursor(_left()+_dotsleft, _top());
|
||||
gfx.print(":");
|
||||
gfx.setFont();
|
||||
if(_fb->ready()) _fb->display();
|
||||
}
|
||||
|
||||
void ClockWidget::_clearClock(){
|
||||
#ifdef PSFBUFFER
|
||||
if(_fb->ready()) _fb->clear();
|
||||
else
|
||||
#endif
|
||||
#ifndef CLOCKFONT5x7
|
||||
dsp.fillRect(_left(), _top()-_timeheight, _clockwidth, _clockheight+1, config.theme.background);
|
||||
#else
|
||||
dsp.fillRect(_left(), _top(), _clockwidth+1, _clockheight+1, config.theme.background);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ClockWidget::draw(){
|
||||
if(!_active) return;
|
||||
dsp.printClock(_config.top, _config.left, _config.textsize, false);
|
||||
_printClock(_getTime());
|
||||
}
|
||||
|
||||
void ClockWidget::_draw(){
|
||||
if(!_active) return;
|
||||
dsp.printClock(_config.top, _config.left, _config.textsize, true);
|
||||
_printClock(true);
|
||||
}
|
||||
|
||||
void ClockWidget::_reset(){
|
||||
#ifdef PSFBUFFER
|
||||
if(_fb->ready()) {
|
||||
_fb->freeBuffer();
|
||||
_getTimeBounds();
|
||||
_begin();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ClockWidget::_clear(){
|
||||
dsp.clearClock();
|
||||
_clearClock();
|
||||
}
|
||||
#else //#ifndef DSP_LCD
|
||||
|
||||
void ClockWidget::_printClock(bool force){
|
||||
strftime(_timebuffer, sizeof(_timebuffer), "%H:%M", &network.timeinfo);
|
||||
if(force){
|
||||
dsp.setCursor(dsp.width()-5, 0);
|
||||
dsp.print(_timebuffer);
|
||||
}
|
||||
dsp.setCursor(dsp.width()-5+2, 0);
|
||||
dsp.print((network.timeinfo.tm_sec % 2 == 0)?":":" ");
|
||||
}
|
||||
|
||||
void ClockWidget::_clearClock(){}
|
||||
|
||||
void ClockWidget::draw(){
|
||||
if(!_active) return;
|
||||
_printClock(true);
|
||||
}
|
||||
void ClockWidget::_draw(){
|
||||
if(!_active) return;
|
||||
_printClock(true);
|
||||
}
|
||||
void ClockWidget::_reset(){}
|
||||
void ClockWidget::_clear(){}
|
||||
#endif //#ifndef DSP_LCD
|
||||
|
||||
/**************************
|
||||
BITRATE WIDGET
|
||||
**************************/
|
||||
void BitrateWidget::init(BitrateConfig bconf, uint16_t fgcolor, uint16_t bgcolor){
|
||||
Widget::init(bconf.widget, fgcolor, bgcolor);
|
||||
_dimension = bconf.dimension;
|
||||
_bitrate = 0;
|
||||
_format = BF_UNCNOWN;
|
||||
dsp.charSize(bconf.widget.textsize, _charWidth, _textheight);
|
||||
_format = BF_UNKNOWN;
|
||||
_charSize(bconf.widget.textsize, _charWidth, _textheight);
|
||||
memset(_buf, 0, 6);
|
||||
}
|
||||
|
||||
@@ -480,9 +835,20 @@ void BitrateWidget::setFormat(BitrateFormat format){
|
||||
_draw();
|
||||
}
|
||||
|
||||
//TODO move to parent
|
||||
void BitrateWidget::_charSize(uint8_t textsize, uint8_t& width, uint16_t& height){
|
||||
#ifndef DSP_LCD
|
||||
width = textsize * CHARWIDTH;
|
||||
height = textsize * CHARHEIGHT;
|
||||
#else
|
||||
width = 1;
|
||||
height = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void BitrateWidget::_draw(){
|
||||
_clear();
|
||||
if(!_active || _format == BF_UNCNOWN || _bitrate==0) return;
|
||||
if(!_active || _format == BF_UNKNOWN || _bitrate==0) return;
|
||||
dsp.drawRect(_config.left, _config.top, _dimension, _dimension, _fgcolor);
|
||||
dsp.fillRect(_config.left, _config.top + _dimension/2, _dimension, _dimension/2, _fgcolor);
|
||||
dsp.setFont();
|
||||
@@ -507,4 +873,104 @@ void BitrateWidget::_clear() {
|
||||
dsp.fillRect(_config.left, _config.top, _dimension, _dimension, _bgcolor);
|
||||
}
|
||||
|
||||
|
||||
/**************************
|
||||
PLAYLIST WIDGET
|
||||
**************************/
|
||||
void PlayListWidget::init(ScrollWidget* current){
|
||||
Widget::init({0, 0, 0, WA_LEFT}, 0, 0);
|
||||
_current = current;
|
||||
#ifndef DSP_LCD
|
||||
_plItemHeight = playlistConf.widget.textsize*(CHARHEIGHT-1)+playlistConf.widget.textsize*4;
|
||||
_plTtemsCount = round((float)dsp.height()/_plItemHeight);
|
||||
if(_plTtemsCount%2==0) _plTtemsCount++;
|
||||
_plCurrentPos = _plTtemsCount/2;
|
||||
_plYStart = (dsp.height() / 2 - _plItemHeight / 2) - _plItemHeight * (_plTtemsCount - 1) / 2 + playlistConf.widget.textsize*2;
|
||||
#else
|
||||
_plTtemsCount = PLMITEMS;
|
||||
_plCurrentPos = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t PlayListWidget::_fillPlMenu(int from, uint8_t count) {
|
||||
int ls = from;
|
||||
uint8_t c = 0;
|
||||
bool finded = false;
|
||||
if (config.playlistLength() == 0) {
|
||||
return 0;
|
||||
}
|
||||
File playlist = config.SDPLFS()->open(REAL_PLAYL, "r");
|
||||
File index = config.SDPLFS()->open(REAL_INDEX, "r");
|
||||
while (true) {
|
||||
if (ls < 1) {
|
||||
ls++;
|
||||
_printPLitem(c, "");
|
||||
c++;
|
||||
continue;
|
||||
}
|
||||
if (!finded) {
|
||||
index.seek((ls - 1) * 4, SeekSet);
|
||||
uint32_t pos;
|
||||
index.readBytes((char *) &pos, 4);
|
||||
finded = true;
|
||||
index.close();
|
||||
playlist.seek(pos, SeekSet);
|
||||
}
|
||||
bool pla = true;
|
||||
while (pla) {
|
||||
pla = playlist.available();
|
||||
String stationName = playlist.readStringUntil('\n');
|
||||
stationName = stationName.substring(0, stationName.indexOf('\t'));
|
||||
if(config.store.numplaylist && stationName.length()>0) stationName = String(from+c)+" "+stationName;
|
||||
_printPLitem(c, stationName.c_str());
|
||||
c++;
|
||||
if (c >= count) break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
playlist.close();
|
||||
return c;
|
||||
}
|
||||
#ifndef DSP_LCD
|
||||
void PlayListWidget::drawPlaylist(uint16_t currentItem) {
|
||||
uint8_t lastPos = _fillPlMenu(currentItem - _plCurrentPos, _plTtemsCount);
|
||||
if(lastPos<_plTtemsCount){
|
||||
dsp.fillRect(0, lastPos*_plItemHeight+_plYStart, dsp.width(), dsp.height()/2, config.theme.background);
|
||||
}
|
||||
}
|
||||
|
||||
void PlayListWidget::_printPLitem(uint8_t pos, const char* item){
|
||||
dsp.setTextSize(playlistConf.widget.textsize);
|
||||
if (pos == _plCurrentPos) {
|
||||
_current->setText(item);
|
||||
} else {
|
||||
uint8_t plColor = (abs(pos - _plCurrentPos)-1)>4?4:abs(pos - _plCurrentPos)-1;
|
||||
dsp.setTextColor(config.theme.playlist[plColor], config.theme.background);
|
||||
dsp.setCursor(TFT_FRAMEWDT, _plYStart + pos * _plItemHeight);
|
||||
dsp.fillRect(0, _plYStart + pos * _plItemHeight - 1, dsp.width(), _plItemHeight - 2, config.theme.background);
|
||||
Serial.println(item);
|
||||
dsp.print(utf8Rus(item, true));
|
||||
}
|
||||
}
|
||||
#else
|
||||
void PlayListWidget::_printPLitem(uint8_t pos, const char* item){
|
||||
if (pos == _plCurrentPos) {
|
||||
_current->setText(item);
|
||||
} else {
|
||||
dsp.setCursor(1, pos);
|
||||
char tmp[dsp.width()] = {0};
|
||||
strlcpy(tmp, utf8Rus(item, true), dsp.width());
|
||||
dsp.print(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
void PlayListWidget::drawPlaylist(uint16_t currentItem) {
|
||||
dsp.clear();
|
||||
_fillPlMenu(currentItem - _plCurrentPos, _plTtemsCount);
|
||||
dsp.setCursor(0,1);
|
||||
dsp.write(uint8_t(126));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif // #if DSP_MODEL!=DSP_DUMMY
|
||||
|
||||
Reference in New Issue
Block a user