From b86a25755150cca0fd3901fe839a254ab1cddf8d Mon Sep 17 00:00:00 2001 From: Raptor Engineering Development Team Date: Fri, 26 Apr 2019 00:18:03 +0000 Subject: Add initial progress bar drawing support --- src/screen.cpp | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/screen.h | 6 +++ 2 files changed, 124 insertions(+) diff --git a/src/screen.cpp b/src/screen.cpp index e342889..1393b84 100644 --- a/src/screen.cpp +++ b/src/screen.cpp @@ -21,6 +21,10 @@ #include #include #include +#include +#include +#include +#include #include "screen.h" #include "font.h" #include "fbshellman.h" @@ -87,6 +91,34 @@ Screen *Screen::createInstance() if (!pScreen->mCols) pScreen->mCols = pScreen->mWidth / FW(1); if (!pScreen->mRows) pScreen->mRows = pScreen->mHeight / FH(1); + /* Set up progress bar pipes */ + if (mkfifo("/var/run/fbterm_progress_max", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)) { + if (errno != EEXIST) { + return 0; + } + } + if (mkfifo("/var/run/fbterm_progress_value", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)) { + if (errno != EEXIST) { + return 0; + } + } + + pScreen->mProgressBarMaxPipeFD = open("/var/run/fbterm_progress_max", O_RDONLY|O_NONBLOCK); + pScreen->mProgressBarValuePipeFD = open("/var/run/fbterm_progress_value", O_RDONLY|O_NONBLOCK); + + /* Disable progress bar by default */ + pScreen->mProgressBarMax = 0; + pScreen->mProgressBarValue = 0; + + /* Set up progress bar */ + u32 progressBarWidth = pScreen->mWidth / 3; + u32 progressBarHeight = 15; + u32 progressBarVOffset = 575; + pScreen->mProgressBarXStart = (pScreen->mWidth / 2) - (progressBarWidth / 2); + pScreen->mProgressBarXStop = (pScreen->mWidth / 2) + (progressBarWidth / 2); + pScreen->mProgressBarYStart = progressBarVOffset; + pScreen->mProgressBarYStop = pScreen->mProgressBarYStart + progressBarHeight; + if (!pScreen->mCols || !pScreen->mRows) { fprintf(stderr, "font size is too huge!\n"); delete pScreen; @@ -94,6 +126,10 @@ Screen *Screen::createInstance() } pScreen->initFillDraw(); + + /* Draw initial progress bar outline */ + pScreen->drawProgressBar(); + return pScreen; } @@ -119,6 +155,12 @@ Screen::Screen() Screen::~Screen() { + unlink("/var/run/fbterm_progress_max"); + unlink("/var/run/fbterm_progress_value"); + + close(mProgressBarMaxPipeFD); + close(mProgressBarValuePipeFD); + Font::uninstance(); endFillDraw(); } @@ -197,6 +239,63 @@ void Screen::eraseMargin(bool top, u16 h) } } +void Screen::drawProgressBar() +{ + /* Check FIFOs for new data*/ + char buf[1]; + int nread = 0; + int received_data = 0; + do { + nread = read(mProgressBarMaxPipeFD, buf, 1); + if (nread > 0) { + received_data = 1; + } + } while (nread > 0); + + if (received_data) { + mProgressBarMax = buf[0]; + } + + received_data = 0; + do { + nread = read(mProgressBarValuePipeFD, buf, 1); + if (nread > 0) { + received_data = 1; + } + } while (nread > 0); + + if (received_data) { + mProgressBarValue = buf[0]; + } + + /* Clamp */ + if (mProgressBarValue > mProgressBarMax) { + mProgressBarValue = mProgressBarMax; + } + + if (mProgressBarMax == 0) { + fillRectRaw(mProgressBarXStart, mProgressBarYStart, mProgressBarXStop - mProgressBarXStart, mProgressBarYStop - mProgressBarYStart, 7); + } + else { + fillRectRaw(mProgressBarXStart, mProgressBarYStart, mProgressBarXStop - mProgressBarXStart, 1, 0); + fillRectRaw(mProgressBarXStart, mProgressBarYStop - 1, mProgressBarXStop - mProgressBarXStart, 1, 0); + fillRectRaw(mProgressBarXStart, mProgressBarYStart, 1, mProgressBarYStop - mProgressBarYStart, 0); + fillRectRaw(mProgressBarXStop - 1, mProgressBarYStart, 1, mProgressBarYStop - mProgressBarYStart, 0); + + u32 progressWidth = mProgressBarXStop - mProgressBarXStart; + progressWidth -= 2; + int rightBarStop = (progressWidth * mProgressBarValue) / mProgressBarMax; + int rightBarWidth = progressWidth - rightBarStop; + + if ((rightBarStop - 1) > 0) { + fillRectRaw(mProgressBarXStart + 1, mProgressBarYStart + 1, rightBarStop - 1, (mProgressBarYStop - mProgressBarYStart) - 2, 0); + } + if (rightBarWidth > 2) { + fillRectRaw(rightBarStop + mProgressBarXStart + 1, mProgressBarYStart + 1, rightBarWidth - 2, (mProgressBarYStop - mProgressBarYStart) - 2, 7); + } + } +} + void Screen::drawText(u32 x, u32 y, u8 fc, u8 bc, u16 num, u16 *text, bool *dw) { u32 startx, fw = FW(1); @@ -238,6 +337,11 @@ void Screen::drawText(u32 x, u32 y, u8 fc, u8 bc, u16 num, u16 *text, bool *dw) } else if (draw_space) { fillRect(startx, y, x - startx, FH(1), bc); } + + /* HACK + * If text changed, maybe progress did too? + */ + drawProgressBar(); } void Screen::drawGlyphs(u32 x, u32 y, u8 fc, u8 bc, u16 num, u16 *text, bool *dw) @@ -269,6 +373,20 @@ void Screen::fillRect(u32 x, u32 y, u32 w, u32 h, u8 color) } } +void Screen::fillRectRaw(u32 x, u32 y, u32 w, u32 h, u8 color) +{ + if (x >= mWidth || y >= mHeight || !w || !h) return; + if (x + w > mWidth) w = mWidth - x; + if (y + h > mHeight) h = mHeight - y; + + rotateRect(x, y, w, h); + + for (; h--;) { + if (mScrollType == YWrap && y > mOffsetMax) y -= mOffsetMax + 1; + (this->*fill)(x, y++, w, color); + } +} + void Screen::drawGlyph(u32 x, u32 y, u8 fc, u8 bc, u16 code, bool dw) { if (x >= mWidth || y >= mHeight) return; diff --git a/src/screen.h b/src/screen.h index 136d1e2..57c646b 100644 --- a/src/screen.h +++ b/src/screen.h @@ -47,6 +47,8 @@ public : void drawText(u32 x, u32 y, u8 fc, u8 bc, u16 num, u16 *text, bool *dw); void fillRect(u32 x, u32 y, u32 w, u32 h, u8 color); + void fillRectRaw(u32 x, u32 y, u32 w, u32 h, u8 color); + void drawProgressBar(); bool move(u16 scol, u16 srow, u16 dcol, u16 drow, u16 w, u16 h); void setPalette(const Color *palette); @@ -60,6 +62,10 @@ protected: u32 mWidth, mHeight; u16 mCols, mRows; u32 mBitsPerPixel, mBytesPerLine; + u32 mProgressBarXStart, mProgressBarXStop; + u32 mProgressBarYStart, mProgressBarYStop; + u16 mProgressBarMax, mProgressBarValue; + int mProgressBarMaxPipeFD, mProgressBarValuePipeFD; RotateType mRotateType; -- cgit v1.2.1