Skip to content

Commit e5e939b

Browse files
authored
📺 Assorted small FTDI Eve Touch UI fixes (#22273)
1 parent 3c74664 commit e5e939b

File tree

19 files changed

+396
-61
lines changed

19 files changed

+396
-61
lines changed

Marlin/src/lcd/extui/ftdi_eve_touch_ui/archim2-flash/media_file_reader.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,7 @@
3232
class MediaFileReader {
3333
private:
3434
#if ENABLED(SDSUPPORT)
35-
DiskIODriver_SPI_SD card;
36-
SdVolume volume;
37-
SdFile root, file;
35+
SdFile root, file;
3836
#endif
3937

4038
public:

Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/screens.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,6 @@ enum {
118118
#include "../generic/files_screen.h"
119119
#include "../generic/move_axis_screen.h"
120120
#include "../generic/flow_percent_screen.h"
121-
#include "../generic/tune_menu.h"
122121
#if HAS_JUNCTION_DEVIATION
123122
#include "../generic/junction_deviation_screen.h"
124123
#else

Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/status_screen.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,4 +294,14 @@ void StatusScreen::onIdle() {
294294
}
295295
}
296296

297+
void StatusScreen::onMediaInserted() {
298+
if (AT_SCREEN(StatusScreen))
299+
setStatusMessage(GET_TEXT_F(MSG_MEDIA_INSERTED));
300+
}
301+
302+
void StatusScreen::onMediaRemoved() {
303+
if (AT_SCREEN(StatusScreen) || ExtUI::isPrintingFromMedia())
304+
setStatusMessage(GET_TEXT_F(MSG_MEDIA_REMOVED));
305+
}
306+
297307
#endif // COCOA_STATUS_SCREEN

Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/status_screen.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,6 @@ class StatusScreen : public BaseScreen, public CachedScreen<STATUS_SCREEN_CACHE>
5252
static bool onTouchHeld(uint8_t tag);
5353
static bool onTouchEnd(uint8_t tag);
5454
static void onIdle();
55+
static void onMediaInserted();
56+
static void onMediaRemoved();
5557
};

Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/poly_ui.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -239,9 +239,11 @@ class DeduplicatedPolyReader : public POLY_READER {
239239
*/
240240
template<class POLY_READER=DeduplicatedPolyReader<TransformedPolyReader>>
241241
class GenericPolyUI {
242-
private:
242+
protected:
243243
CommandProcessor &cmd;
244+
draw_mode_t mode;
244245

246+
private:
245247
// Attributes used to paint buttons
246248

247249
uint32_t btn_fill_color = 0x000000;
@@ -250,8 +252,6 @@ class GenericPolyUI {
250252
uint32_t btn_stroke_color = 0x000000;
251253
uint8_t btn_stroke_width = 28;
252254

253-
draw_mode_t mode;
254-
255255
public:
256256
enum ButtonStyle : uint8_t {
257257
FILL = 1,
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#!/usr/bin/python
2+
3+
# Written By Marcio Teixeira 2021 - SynDaver Labs, Inc.
4+
#
5+
# This program is free software: you can redistribute it and/or modify
6+
# it under the terms of the GNU General Public License as published by
7+
# the Free Software Foundation, either version 3 of the License, or
8+
# (at your option) any later version.
9+
#
10+
# This program is distributed in the hope that it will be useful,
11+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
# GNU General Public License for more details.
14+
#
15+
# To view a copy of the GNU General Public License, go to the following
16+
# location: <https://www.gnu.org/licenses/>.
17+
18+
from __future__ import print_function
19+
import argparse
20+
import textwrap
21+
import os
22+
import zlib
23+
24+
def deflate(data):
25+
return zlib.compress(data)
26+
27+
if __name__ == "__main__":
28+
parser = argparse.ArgumentParser(description='Converts a file into a packed C array for use as data')
29+
parser.add_argument("input")
30+
parser.add_argument("-d", "--deflate", action="store_true", help="Packs the data using the deflate algorithm")
31+
args = parser.parse_args()
32+
33+
varname = os.path.splitext(os.path.basename(args.input))[0];
34+
35+
with open(args.input, "rb") as in_file:
36+
data = in_file.read()
37+
if args.deflate:
38+
data = deflate(data)
39+
data = bytearray(data)
40+
data = list(map(lambda a: "0x" + format(a, '02x'), data))
41+
nElements = len(data)
42+
data = ', '.join(data)
43+
data = textwrap.fill(data, 75, initial_indent = ' ', subsequent_indent = ' ')
44+
45+
print("const unsigned char " + varname + "[" + format(nElements) + "] PROGMEM = {")
46+
print(data)
47+
print("};")
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
#!/usr/bin/python
2+
3+
# Written By Marcio Teixeira 2019 - Aleph Objects, Inc.
4+
#
5+
# This program is free software: you can redistribute it and/or modify
6+
# it under the terms of the GNU General Public License as published by
7+
# the Free Software Foundation, either version 3 of the License, or
8+
# (at your option) any later version.
9+
#
10+
# This program is distributed in the hope that it will be useful,
11+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
# GNU General Public License for more details.
14+
#
15+
# To view a copy of the GNU General Public License, go to the following
16+
# location: <https://www.gnu.org/licenses/>.
17+
18+
from __future__ import print_function
19+
from PIL import Image
20+
import argparse
21+
import textwrap
22+
23+
def pack_rle(data):
24+
"""Use run-length encoding to pack the bytes"""
25+
rle = []
26+
value = data[0]
27+
count = 0
28+
for i in data:
29+
if i != value or count == 255:
30+
rle.append(count)
31+
rle.append(value)
32+
value = i
33+
count = 1
34+
else:
35+
count += 1
36+
rle.append(count)
37+
rle.append(value)
38+
return rle
39+
40+
class WriteSource:
41+
def __init__(self, lines_in_blocks):
42+
self.blocks = []
43+
self.values = []
44+
self.block_size = lines_in_blocks
45+
self.rows = 0
46+
47+
def add_pixel(self, value):
48+
self.values.append(value)
49+
50+
def convert_to_4bpp(self, data, chunk_size = 0):
51+
# Invert the image
52+
data = list(map(lambda i: 255 - i, data))
53+
# Quanitize 8-bit values into 4-bits
54+
data = list(map(lambda i: i >> 4, data))
55+
# Make sure there is an even number of elements
56+
if (len(data) & 1) == 1:
57+
data.append(0)
58+
# Combine each two adjacent values into one
59+
i = iter(data)
60+
data = list(map(lambda a, b: a << 4 | b, i ,i))
61+
# Pack the data
62+
data = pack_rle(data)
63+
# Convert values into hex strings
64+
return list(map(lambda a: "0x" + format(a, '02x'), data))
65+
66+
def end_row(self, y):
67+
# Pad each row into even number of values
68+
if len(self.values) & 1:
69+
self.values.append(0)
70+
71+
self.rows += 1
72+
if self.block_size and (self.rows % self.block_size) == 0:
73+
self.blocks.append(self.values)
74+
self.values = []
75+
76+
def write(self):
77+
if len(self.values):
78+
self.blocks.append(self.values)
79+
80+
block_strs = [];
81+
for b in self.blocks:
82+
data = self.convert_to_4bpp(b)
83+
data = ', '.join(data)
84+
data = textwrap.fill(data, 75, initial_indent = ' ', subsequent_indent = ' ')
85+
block_strs.append(data)
86+
87+
print("const unsigned char font[] PROGMEM = {")
88+
for i, b in enumerate(block_strs):
89+
if i:
90+
print(',')
91+
print('\n /* {} */'.format(i))
92+
print(b, end='')
93+
print("\n};")
94+
95+
if __name__ == "__main__":
96+
parser = argparse.ArgumentParser(description='Converts a grayscale bitmap into a 16-level RLE packed C array for use as font data')
97+
parser.add_argument("input")
98+
parser.add_argument('--char_height', help='Adds a separator every so many lines', type=int)
99+
args = parser.parse_args()
100+
101+
writer = WriteSource(args.char_height)
102+
103+
img = Image.open(args.input).convert('L')
104+
for y in range(img.height):
105+
for x in range(img.width):
106+
writer.add_pixel(img.getpixel((x,y)))
107+
writer.end_row(y)
108+
writer.write()
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#!/usr/bin/python
2+
3+
# Written By Marcio Teixeira 2021 - SynDaver Labs, Inc.
4+
#
5+
# This program is free software: you can redistribute it and/or modify
6+
# it under the terms of the GNU General Public License as published by
7+
# the Free Software Foundation, either version 3 of the License, or
8+
# (at your option) any later version.
9+
#
10+
# This program is distributed in the hope that it will be useful,
11+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
# GNU General Public License for more details.
14+
#
15+
# To view a copy of the GNU General Public License, go to the following
16+
# location: <https://www.gnu.org/licenses/>.
17+
18+
from __future__ import print_function
19+
from PIL import Image
20+
import argparse
21+
import textwrap
22+
import os
23+
import sys
24+
import zlib
25+
26+
class WriteSource:
27+
def __init__(self, mode):
28+
self.values = []
29+
self.mode = mode
30+
self.offset = 8
31+
self.byte = 0
32+
33+
def finish_byte(self):
34+
if self.offset != 8:
35+
self.values.append(self.byte)
36+
self.offset = 8
37+
self.byte = 0
38+
39+
def add_bits_to_byte(self, value, size = 1):
40+
self.offset -= size
41+
self.byte = self.byte | value << self.offset
42+
if self.offset == 0:
43+
self.finish_byte()
44+
45+
def append_rgb565(self, color):
46+
value = ((color[0] & 0xF8) << 8) + ((color[1] & 0xFC) << 3) + ((color[2] & 0xF8) >> 3)
47+
self.values.append((value & 0x00FF) >> 0);
48+
self.values.append((value & 0xFF00) >> 8);
49+
50+
def append_rgb332(self, color):
51+
value = (color[0] & 0xE0) + ((color[1] & 0xE0) >> 3) + ((color[2] & 0xC0) >> 6)
52+
self.values.append(value);
53+
54+
def append_grayscale(self, color, bits):
55+
luminance = int(0.2126 * color[0] + 0.7152 * color[1] + 0.0722 * color[2])
56+
self.add_bits_to_byte(luminance >> (8 - bits), bits)
57+
58+
def deflate(self, data):
59+
return zlib.compress(data)
60+
61+
def add_pixel(self, color):
62+
if self.mode == "l1":
63+
self.append_grayscale(color, 1)
64+
elif self.mode == "l2":
65+
self.append_grayscale(color, 2)
66+
elif self.mode == "l4":
67+
self.append_grayscale(color, 4)
68+
elif self.mode == "l8":
69+
self.append_grayscale(color, 8)
70+
elif self.mode == "rgb565":
71+
self.append_rgb565(color)
72+
elif self.mode == "rgb332":
73+
self.append_rgb332(color)
74+
75+
def end_row(self, y):
76+
if self.mode in ["l1", "l2", "l3"]:
77+
self.finish_byte()
78+
79+
def write(self, varname, deflate):
80+
print("Length of uncompressed data: ", len(self.values), file=sys.stderr)
81+
data = bytes(bytearray(self.values))
82+
if deflate:
83+
data = self.deflate(data)
84+
print("Length of data after compression: ", len(data), file=sys.stderr)
85+
data = bytearray(data)
86+
data = list(map(lambda a: "0x" + format(a, '02x'), data))
87+
nElements = len(data)
88+
data = ', '.join(data)
89+
data = textwrap.fill(data, 75, initial_indent = ' ', subsequent_indent = ' ')
90+
91+
print("const unsigned char " + varname + "[" + format(nElements) + "] PROGMEM = {")
92+
print(data)
93+
print("};")
94+
95+
if __name__ == "__main__":
96+
parser = argparse.ArgumentParser(description='Converts a bitmap into a C array')
97+
parser.add_argument("input")
98+
parser.add_argument("-d", "--deflate", action="store_true", help="Packs the data using the deflate algorithm")
99+
parser.add_argument("-m", "--mode", default="l1", help="Mode, can be l1, l2, l4, l8, rgb332 or rgb565")
100+
args = parser.parse_args()
101+
102+
varname = os.path.splitext(os.path.basename(args.input))[0];
103+
104+
writer = WriteSource(args.mode)
105+
106+
img = Image.open(args.input)
107+
print("Image height: ", img.height, file=sys.stderr)
108+
print("Image width: ", img.width, file=sys.stderr)
109+
for y in range(img.height):
110+
for x in range(img.width):
111+
writer.add_pixel(img.getpixel((x,y)))
112+
writer.end_row(y)
113+
writer.write(varname, args.deflate)

Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/bed_mesh_edit_screen.cpp

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -190,17 +190,11 @@ bool BedMeshEditScreen::onTouchEnd(uint8_t tag) {
190190
}
191191

192192
void BedMeshEditScreen::show() {
193-
// On entry, home if needed and save current mesh
194-
if (!ExtUI::isMachineHomed()) {
195-
SpinnerDialogBox::enqueueAndWait_P(F("G28\nG29 S1"));
196-
// After the spinner, go to this screen.
197-
current_screen.forget();
198-
PUSH_SCREEN(BedMeshEditScreen);
199-
}
200-
else {
201-
injectCommands_P(PSTR("G29 S1"));
202-
GOTO_SCREEN(BedMeshEditScreen);
203-
}
193+
// On entry, always home (to account for possible Z offset changes) and save current mesh
194+
SpinnerDialogBox::enqueueAndWait_P(F("G28\nG29 S1"));
195+
// After the spinner, go to this screen.
196+
current_screen.forget();
197+
PUSH_SCREEN(BedMeshEditScreen);
204198
}
205199

206200
#endif // FTDI_BED_MESH_EDIT_SCREEN

Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/bed_mesh_view_screen.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,6 @@ void BedMeshViewScreen::onMeshUpdate(const int8_t x, const int8_t y, const ExtUI
132132
mydata.count = GRID_MAX_POINTS;
133133
break;
134134
case ExtUI::G26_START:
135-
GOTO_SCREEN(BedMeshViewScreen);
136135
mydata.message = nullptr;
137136
mydata.count = 0;
138137
break;
@@ -161,7 +160,7 @@ void BedMeshViewScreen::doProbe() {
161160
void BedMeshViewScreen::doMeshValidation() {
162161
mydata.count = 0;
163162
GOTO_SCREEN(StatusScreen);
164-
injectCommands_P(PSTR("M75\nG28 O\nM117 Heating...\nG26 R X0 Y0\nG27\nM77"));
163+
injectCommands_P(PSTR("G28\nM117 Heating...\nG26 R X0 Y0\nG27"));
165164
}
166165

167166
void BedMeshViewScreen::show() {

0 commit comments

Comments
 (0)