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
|