/*
* displayclass.H
*
* Created on: 31 Oct 2020
* Author: mike
*/
#pragma once
#include <cstdint>
#include "libOLED/fontclass.H"
inline int constexpr dataSize(int const width, int const height)
{
return (width * height / 8);
}
enum colour_t
{
BLACK, /* and 0, invert 0 */
WHITE, /* and 0, invert 1 */
OVERLAY, /* and 1, invert 0 */
INVERT, /* and 1, invert 1 */
};
class display_t
{
public:
display_t(int const width, int const height, int const ramwidth,
uint8_t *const data);
virtual ~display_t();
/// \brief get the current rotation of the display : doesnt work too well.
uint8_t
getRotation();
/// @brief Get pixel width
/// @return width
int16_t
width();
/// @brief Get pixel height
/// @return height
int16_t
height();
/// @brief common hardware reset, resets ALL displays
void
reset();
void
init();
/// \brief Clear display to colour
void
clearDisplay(colour_t colour = colour_t::BLACK);
/// @brief Invert display
/// @param i true : invert display
void
invertDisplay(uint8_t i);
/// @brief Show the workspace on the screen
void
display();
void
startscrollright(uint8_t start, uint8_t stop);
void
startscrollleft(uint8_t start, uint8_t stop);
void
startscrolldiagright(uint8_t start, uint8_t stop);
void
startscrolldiagleft(uint8_t start, uint8_t stop);
void
stopscroll(void);
/// @brief Set display contrast
/// @param contrast 0..255 but theres really only two values worth bothering with, 0 and 255
void
dim(uint8_t contrast);
// set drawing mode
void
setPixelMode(colour_t colour)
{
m_colour = colour;
}
/// @brief Draw a single pixel
/// @param x
/// @param y
/// @param pixel
void
drawPixel(int16_t x, int16_t y, bool pixel);
/// @brief Draw a line according to Bressenham algorithm, with optional dash / dot patternign
/// @param x1 coordinate start
/// @param y1 coordinate start
/// @param x2 coordinate end
/// @param y2 coordinate end
/// @param color colour code
/// @param pattern a binary pattern with at least a single bit set - if least significant bit set, draw pixel
/// if bit zero dont draw pixel. After drawing a pixel, shift pattern right one bit. If pattern becomes all zeros, reset with function argument.
void
drawLine(int16_t x1, int16_t y1, int16_t x2, int16_t y2, colour_t color = WHITE, int8_t pattern = 1);
/// @brief Draw a solid rectangle using byte operations, rather than line draw
/// @param x1 top left
/// @param y1 top left
/// @param x2 bottom right
/// @param y2 bottom right
/// @param color colour code
void
drawRectangle(int16_t x1, int16_t y1, int16_t x2, int16_t y2,
colour_t color = WHITE);
/// @brief Position cursor for text drawing
/// @param x top left
/// @param y top left
void
gotoxy(int x, int y)
{
m_cursor_x = x;
m_cursor_y = y;
}
/// @brief Position cursor relative for text drawing
/// @param x relative
/// @param y relative
void
moveby(int x, int y)
{
m_cursor_x += x;
m_cursor_y += y;
}
// pixel to pixel plotting
/// \param font The font to use
/// \param string The characters to plot
/// \param length The length of the string (0 means use strlen(string))
/// \param colour colour code
void
printString(font_t &font, char const *string, uint16_t length,
colour_t colour = WHITE);
// scaled plotting
/// \param font The font to use
/// \param string The characters to plot
/// \param length The length of the string
/// \param scale The scale factor is 256/scale so 256 is 1:1, 128 is twice the size
/// \param colour colour code
void
printScaledString(font_t &font, char const *string, uint16_t length,
uint16_t scale, colour_t colour = WHITE);
static const uint8_t NO_DECIMAL = 255;
/// \brief Display signed integer value with expected field width, and optional
/// decimal point position
/// \param font Reference to font in use
/// \param digits Number of digits to display (not including decimal point)
/// \param dp_pos If less than 10, attempt to place decimal point in given position.
/// set to > 10 to not try to display decimal point
/// \param val value to display
/// \param colour Drawing colour for font.
void
fontDigits(font_t &font, uint8_t digits, uint8_t dp_pos, int val,
colour_t colour = WHITE);
/// \brief Calculate the length of the numeric string, and display it justified or padded
/// \return The formatted width : returned as signed so calculations which have negative results
/// can be performed using width without type casting.
int8_t
fontSigDigits(font_t &font, uint8_t x, uint8_t y, bool right_justify,
uint8_t dp_pos, int val, colour_t colour = WHITE);
int cursor_x()
{
return m_cursor_x;
};
int cursor_y()
{
return m_cursor_y;
};
private:
// set=1 means send data set=0 means send control
virtual void
oledSetCD(uint8_t set) = 0;
virtual void
oledWrite(uint8_t d) = 0;
virtual void
oledReset() = 0;
virtual void
oledWrite(uint8_t *buff, uint8_t len) = 0;
uint8_t
formatNum(char *buff, uint8_t siz, uint8_t digits, uint8_t dp_pos, int val);
int const m_width; // pixel width
int const m_height; // pixel height
int const m_ramwidth; // OLED controller ram pixel width
int m_cursor_x;
int m_cursor_y;
int m_rotation;
// currently selected colour mode
colour_t m_colour;
uint8_t *const m_data;
};