LCOV - code coverage report
Current view: top level - src/Display/MCU - LCDDisplay.hpp (source / functions) Hit Total Coverage
Test: 169c36a3797bc662d84b5726f34a3f37d3c58247 Lines: 27 30 90.0 %
Date: 2024-11-09 15:32:27 Functions: 5 6 83.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <Banks/Bank.hpp>
       4             : #include <Display/DisplayElement.hpp>
       5             : #include <Display/DisplayInterface.hpp>
       6             : #include <MIDI_Inputs/MCU/LCD.hpp>
       7             : 
       8             : BEGIN_CS_NAMESPACE
       9             : 
      10             : namespace MCU {
      11             : 
      12             : /**
      13             :  * @brief   Displays the text of the Mackie Control Universal LCD screen for a
      14             :  *          single track. Often used for track names.
      15             :  * 
      16             :  * @ingroup DisplayElements
      17             :  */
      18             : class LCDDisplay : public DisplayElement {
      19             :   public:
      20             :     /**
      21             :      * @brief   Constructor.
      22             :      * 
      23             :      * @param   display 
      24             :      *          A reference to the display that this element will be drawn to.
      25             :      * @param   lcd 
      26             :      *          A reference to the MCU LCD MIDI input element that listens for
      27             :      *          incoming MIDI display data.
      28             :      * @param   bank 
      29             :      *          The bank that determines the active track to be displayed.
      30             :      * @param   track 
      31             :      *          The track number to display [1, 8].
      32             :      * @param   loc 
      33             :      *          The location on the display where to start drawing the text.
      34             :      * @param   textSize 
      35             :      *          The font size to use for drawing the text.
      36             :      * @param   color 
      37             :      *          The color of the text to draw.
      38             :      */
      39             :     LCDDisplay(DisplayInterface &display, LCD<> &lcd, const OutputBank &bank,
      40             :                uint8_t track, PixelLocation loc, uint8_t textSize,
      41             :                uint16_t color)
      42             :         : DisplayElement(display), lcd(lcd), bank(&bank), track(track - 1),
      43             :           line(1), x(loc.x), y(loc.y), size(textSize), color(color) {
      44             :         lcd.addSubscriber();
      45             :     }
      46             : 
      47             :     /**
      48             :      * @brief   Constructor.
      49             :      * 
      50             :      * @param   display 
      51             :      *          A reference to the display that this element will be drawn to.
      52             :      * @param   lcd 
      53             :      *          A reference to the MCU LCD MIDI input element that listens for
      54             :      *          incoming MIDI display data.
      55             :      * @param   bank 
      56             :      *          The bank that determines the active track to be displayed.
      57             :      * @param   track 
      58             :      *          The track number to display [1, 8].
      59             :      * @param   line
      60             :      *          The line of the MCU display to display [1, 2].
      61             :      * @param   loc 
      62             :      *          The location on the display where to start drawing the text.
      63             :      * @param   textSize 
      64             :      *          The font size to use for drawing the text.
      65             :      * @param   color 
      66             :      *          The color of the text to draw.
      67             :      */
      68             :     LCDDisplay(DisplayInterface &display, LCD<> &lcd, const OutputBank &bank,
      69             :                uint8_t track, uint8_t line, PixelLocation loc, uint8_t textSize,
      70             :                uint16_t color)
      71             :         : DisplayElement(display), lcd(lcd), bank(&bank), track(track - 1),
      72             :           line(line - 1), x(loc.x), y(loc.y), size(textSize), color(color) {
      73             :         lcd.addSubscriber();
      74             :     }
      75             : 
      76             :     /**
      77             :      * @brief   Constructor.
      78             :      * 
      79             :      * @param   display 
      80             :      *          A reference to the display that this element will be drawn to.
      81             :      * @param   lcd 
      82             :      *          A reference to the MCU LCD MIDI input element that listens for
      83             :      *          incoming MIDI display data.
      84             :      * @param   track 
      85             :      *          The track number to display [1, 8].
      86             :      * @param   loc 
      87             :      *          The location on the display where to start drawing the text.
      88             :      * @param   textSize 
      89             :      *          The font size to use for drawing the text.
      90             :      * @param   color 
      91             :      *          The color of the text to draw.
      92             :      */
      93             :     LCDDisplay(DisplayInterface &display, LCD<> &lcd, uint8_t track,
      94             :                PixelLocation loc, uint8_t textSize, uint16_t color)
      95             :         : DisplayElement(display), lcd(lcd), track(track - 1), line(1),
      96             :           x(loc.x), y(loc.y), size(textSize), color(color) {
      97             :         lcd.addSubscriber();
      98             :     }
      99             : 
     100             :     /**
     101             :      * @brief   Constructor.
     102             :      * 
     103             :      * @param   display 
     104             :      *          A reference to the display that this element will be drawn to.
     105             :      * @param   lcd 
     106             :      *          A reference to the MCU LCD MIDI input element that listens for
     107             :      *          incoming MIDI display data.
     108             :      * @param   track 
     109             :      *          The track number to display [1, 8].
     110             :      * @param   line
     111             :      *          The line of the MCU display to display [1, 2].
     112             :      * @param   loc 
     113             :      *          The location on the display where to start drawing the text.
     114             :      * @param   textSize 
     115             :      *          The font size to use for drawing the text.
     116             :      * @param   color 
     117             :      *          The color of the text to draw.
     118             :      */
     119           2 :     LCDDisplay(DisplayInterface &display, LCD<> &lcd, uint8_t track,
     120             :                uint8_t line, PixelLocation loc, uint8_t textSize,
     121             :                uint16_t color)
     122           6 :         : DisplayElement(display), lcd(lcd), track(track - 1), line(line - 1),
     123           6 :           x(loc.x), y(loc.y), size(textSize), color(color) {
     124           2 :         lcd.addSubscriber();
     125           2 :     }
     126             : 
     127             :     LCDDisplay(const LCDDisplay &) = delete;
     128           2 :     ~LCDDisplay() { lcd.removeSubscriber(); }
     129             : 
     130           4 :     void draw() override {
     131             :         // If it's a message across all tracks, don't display anything.
     132           4 :         if (separateTracks()) {
     133             :             // Determine the track and line to display
     134           4 :             uint8_t offset = bank ? bank->getOffset() + track : track;
     135           4 :             if (offset > 7)
     136           0 :                 ERROR(F("Track out of bounds (") << offset << ')', 0xBA41);
     137           4 :             if (line > 1)
     138           0 :                 ERROR(F("Line out of bounds (") << line << ')', 0xBA42);
     139             : 
     140             :             // Extract the six-character substring for this track.
     141           4 :             const char *text = lcd.getText() + 7 * offset + 56 * line;
     142           4 :             char buffer[7];
     143           4 :             strncpy(buffer, text, 6);
     144           4 :             buffer[6] = '\0';
     145             :             // Print it to the display
     146           4 :             display.setCursor(x, y);
     147           4 :             display.setTextSize(size);
     148           4 :             display.setTextColor(color);
     149           4 :             display.print(buffer);
     150             :         }
     151           4 :         lcd.clearDirty();
     152           4 :     }
     153             : 
     154          10 :     bool getDirty() const override { return lcd.getDirty(); }
     155             : 
     156             :     /**
     157             :      * @brief   Check if the display contains a message for each track 
     158             :      *          separately.
     159             :      * 
     160             :      * On the original Mackie Control surfaces, the LCD display consists of two
     161             :      * 56-character lines, where each of the 8 channels has 7 characters.
     162             :      * If the LCD is used to display a message for each channel separately, the
     163             :      * seventh character of each channel is always a space, as separation 
     164             :      * between the channels.
     165             :      * 
     166             :      * @retval  true 
     167             :      *          The display contains a message for each track separately, and
     168             :      *          the messages are separated by spaces.
     169             :      * @retval  false
     170             :      *          The display contains a message that spans across multiple 
     171             :      *          tracks, without separating spaces between the tracks.
     172             :      */
     173           4 :     bool separateTracks() const {
     174          32 :         for (uint8_t i = 0; i < 7; ++i) {
     175          28 :             const char *text = lcd.getText() + 7 * i + 56 * line;
     176          28 :             if (text[6] != ' ')
     177           0 :                 return false;
     178             :         }
     179           4 :         return true;
     180             :     }
     181             : 
     182             :     /// Set the line number of the LCD to display.
     183             :     /// @param  line
     184             :     ///         Either 1 or 2.
     185             :     void setLine(uint8_t line) { this->line = line - 1; }
     186             : 
     187             :   private:
     188             :     LCD<> &lcd;
     189             :     const OutputBank *bank = nullptr;
     190             :     uint8_t track;
     191             :     uint8_t line;
     192             :     int16_t x, y;
     193             :     uint8_t size;
     194             :     uint16_t color;
     195             : };
     196             : 
     197             : } // namespace MCU
     198             : 
     199             : END_CS_NAMESPACE

Generated by: LCOV version 1.15