-
Notifications
You must be signed in to change notification settings - Fork 71
/
DMD2_TextBox.cpp
127 lines (106 loc) · 3.82 KB
/
DMD2_TextBox.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
DMD TextBox implementation
Allows a simple scrolling text box that implements the Arduino Print
interface, so you can write to it like a serial port or character
LCD display.
Copyright (C) 2014 Freetronics, Inc. (info <at> freetronics <dot> com)
Updated by Angus Gratton, based on DMD by Marc Alexander.
---
This program is free software: you can redistribute it and/or modify it under the terms
of the version 3 GNU General Public License as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program.
If not, see <http://www.gnu.org/licenses/>.
*/
#include "DMD2.h"
DMD_TextBox::DMD_TextBox(DMDFrame &dmd, int left, int top, int width, int height) :
dmd(dmd),
inverted(false),
left(left),
top(top),
width(width),
height(height),
cur_x(0),
cur_y(0),
pending_newline(false)
{
}
size_t DMD_TextBox::write(uint8_t character) {
struct FontHeader header;
memcpy_P(&header, (void *)this->dmd.font, sizeof(FontHeader));
uint8_t rowHeight = header.height+1;
if(width == 0)
width = dmd.width - left;
if(height == 0)
height = dmd.height - top;
uint8_t char_width = dmd.charWidth(character) + 1;
while((cur_x > 0 && cur_x + char_width >= this->width) || pending_newline) { // Need to wrap to new line
if (height >= rowHeight*2) { // Can scroll
cur_y += rowHeight;
cur_x = 0;
if(cur_y + rowHeight > height) { // Scroll
// int delta = cur_y + rowHeight - height; // the amount that it's over by
}
} else if(pending_newline) { // No room, so just clear display
clear();
} else { // Scroll characters horizontally
int scroll_by = char_width - (this->width - cur_x - 1);
scrollX(-scroll_by);
}
pending_newline = false;
}
if(character == '\n') {
pending_newline = true;
// clear the rest of the line after the current cursor position,
// this allows you to then use reset() and do a flicker-free redraw
dmd.drawFilledBox(cur_x+left,cur_y+top,left+width,cur_y+top+rowHeight, inverted ? GRAPHICS_ON : GRAPHICS_OFF);
}
dmd.drawChar(cur_x+left,cur_y+top,character, inverted ? GRAPHICS_OFF : GRAPHICS_ON);
cur_x += char_width;
return 1;
}
void DMD_TextBox::scrollY(int scrollBy) {
if(abs(scrollBy) >= height) { // scrolling over the whole display
// scrolling will erase everything
dmd.drawFilledBox(left, top, left+width-1, top+height-1, inverted ? GRAPHICS_ON : GRAPHICS_OFF);
}
else if(scrollBy < 0) { // Scroll up
dmd.movePixels(left, top - scrollBy, left, top, width, height + scrollBy);
}
else if(scrollBy > 0) { // Scroll down
dmd.movePixels(left, top, left, top + scrollBy, width, height - scrollBy);
}
cur_y += scrollBy;
while(cur_y < 0)
cur_y += height;
while(cur_y > height)
cur_y -= height;
}
void DMD_TextBox::scrollX(int scrollBy) {
if(abs(scrollBy) >= width) { // scrolling over the whole display!
// scrolling will erase everything
dmd.drawFilledBox(left, top, left+width-1, top+height-1, inverted ? GRAPHICS_ON : GRAPHICS_OFF);
}
else if(scrollBy < 0) { // Scroll left
dmd.movePixels(left-scrollBy, top, left, top, width + scrollBy, height);
}
else { // Scroll right
dmd.movePixels(left, top, left+scrollBy, top, width - scrollBy, height);
}
cur_x += scrollBy;
while(cur_x < 0)
cur_x += width;
while(cur_x > width)
cur_x -= width;
}
void DMD_TextBox::clear() {
this->reset();
dmd.drawFilledBox(left,top,left+width,top+height,inverted ? GRAPHICS_ON : GRAPHICS_OFF);
}
void DMD_TextBox::reset() {
cur_x = 0;
cur_y = 0;
pending_newline = false;
}