mirror of
https://github.com/Klipper3d/klipper.git
synced 2025-08-09 23:05:05 -06:00
display: Move glyph definition to printer config
This commit allows to modify the icons (or glyphs) in the displays that support it. Existing icons can be modified and new icons can be added via a [display_glyph] section in the config. Signed-off-by: Florian Heilmann <Florian.Heilmann@gmx.net>
This commit is contained in:
parent
722770f62f
commit
3dcac1308e
7 changed files with 196 additions and 173 deletions
|
@ -13,7 +13,8 @@ text:
|
|||
# Show glyph
|
||||
{% if param_heater_name == "heater_bed" %}
|
||||
{% if heater.target %}
|
||||
~animated_bed~
|
||||
{% set frame = (printer.toolhead.estimated_print_time|int % 2) + 1 %}
|
||||
~bed_heat{frame}~
|
||||
{% else %}
|
||||
~bed~
|
||||
{% endif %}
|
||||
|
@ -35,9 +36,10 @@ text:
|
|||
{% if 'fan' in printer %}
|
||||
{% set speed = printer.fan.speed %}
|
||||
{% if speed %}
|
||||
~animated_fan~
|
||||
{% set frame = (printer.toolhead.estimated_print_time|int % 2) + 1 %}
|
||||
~fan{frame}~
|
||||
{% else %}
|
||||
~fan~
|
||||
~fan1~
|
||||
{% endif %}
|
||||
{ "{:>4.0%}".format(speed) }
|
||||
{% endif %}
|
||||
|
@ -183,3 +185,140 @@ text:
|
|||
[display_data _default_20x4 print_status]
|
||||
position: 3, 0
|
||||
text: { render("_print_status") }
|
||||
|
||||
######################################################################
|
||||
# Default display glyphs
|
||||
######################################################################
|
||||
|
||||
[display_glyph extruder]
|
||||
data:
|
||||
0000000000000000
|
||||
0000000000000000
|
||||
0011111111111100
|
||||
0000011111100000
|
||||
0011111111111100
|
||||
0000011111100000
|
||||
0011111111111100
|
||||
0000000000000000
|
||||
0000111111110000
|
||||
0000111111010000
|
||||
0000111111110000
|
||||
0000000000000000
|
||||
0000001111000000
|
||||
0000000110000000
|
||||
0000000000000000
|
||||
0000000000000000
|
||||
|
||||
[display_glyph bed]
|
||||
data:
|
||||
0000000000000000
|
||||
0000000000000000
|
||||
0000000000000000
|
||||
0000000000000000
|
||||
0000000000000000
|
||||
0000000000000000
|
||||
0000000000000000
|
||||
0000000000000000
|
||||
0000000000000000
|
||||
0000000000000000
|
||||
0000000000000000
|
||||
0001111111110000
|
||||
0010000000001000
|
||||
0111111111111100
|
||||
0000000000000000
|
||||
0000000000000000
|
||||
|
||||
[display_glyph bed_heat1]
|
||||
data:
|
||||
0000000000000000
|
||||
0000000000000000
|
||||
0010000100001000
|
||||
0100001000010000
|
||||
0010000100001000
|
||||
0001000010000100
|
||||
0010000100001000
|
||||
0100001000010000
|
||||
0010000100001000
|
||||
0000000000000000
|
||||
0000000000000000
|
||||
0001111111110000
|
||||
0010000000001000
|
||||
0111111111111100
|
||||
0000000000000000
|
||||
0000000000000000
|
||||
|
||||
[display_glyph bed_heat2]
|
||||
data:
|
||||
0000000000000000
|
||||
0000000000000000
|
||||
0010000100001000
|
||||
0001000010000100
|
||||
0010000100001000
|
||||
0100001000010000
|
||||
0010000100001000
|
||||
0001000010000100
|
||||
0010000100001000
|
||||
0000000000000000
|
||||
0000000000000000
|
||||
0001111111110000
|
||||
0010000000001000
|
||||
0111111111111100
|
||||
0000000000000000
|
||||
0000000000000000
|
||||
|
||||
[display_glyph fan1]
|
||||
data:
|
||||
0000000000000000
|
||||
0000000000000000
|
||||
0000111000000000
|
||||
0001111000011000
|
||||
0001111000111100
|
||||
0000111001111100
|
||||
0000010000111100
|
||||
0000000110000000
|
||||
0000000110000000
|
||||
0011110000100000
|
||||
0011111001110000
|
||||
0011110001111000
|
||||
0001100001111000
|
||||
0000000001110000
|
||||
0000000000000000
|
||||
0000000000000000
|
||||
|
||||
[display_glyph fan2]
|
||||
data:
|
||||
0000000000000000
|
||||
0000000000000000
|
||||
0000000111100000
|
||||
0000000111100000
|
||||
0000000111000000
|
||||
0011000110000000
|
||||
0011100000000000
|
||||
0011110110111100
|
||||
0011110110111100
|
||||
0000000000011100
|
||||
0000000110001100
|
||||
0000001110000000
|
||||
0000011110000000
|
||||
0000011110000000
|
||||
0000000000000000
|
||||
0000000000000000
|
||||
|
||||
[display_glyph feedrate]
|
||||
data:
|
||||
0000000000000000
|
||||
0000000000000000
|
||||
1110111011101100
|
||||
1000100010001010
|
||||
1100110011001010
|
||||
1000100010001010
|
||||
1000111011101100
|
||||
0000000000000000
|
||||
1100010011101110
|
||||
1010101001001000
|
||||
1100111001001100
|
||||
1010101001001000
|
||||
1010101001001110
|
||||
0000000000000000
|
||||
0000000000000000
|
||||
0000000000000000
|
||||
|
|
|
@ -100,9 +100,6 @@ class PrinterLCD:
|
|||
self.show_data_group = self.display_data_groups.get(dgroup)
|
||||
if self.show_data_group is None:
|
||||
raise config.error("Unknown display_data group '%s'" % (dgroup,))
|
||||
# Screen updating
|
||||
self.glyph_helpers = { 'animated_bed': self.animate_bed,
|
||||
'animated_fan': self.animate_fan }
|
||||
self.printer.register_event_handler("klippy:ready", self.handle_ready)
|
||||
self.screen_update_timer = self.reactor.register_timer(
|
||||
self.screen_update_event)
|
||||
|
@ -139,6 +136,28 @@ class PrinterLCD:
|
|||
for group_name, data_configs in groups.items():
|
||||
dg = DisplayGroup(config, group_name, data_configs)
|
||||
self.display_data_groups[group_name] = dg
|
||||
# Load display glyphs
|
||||
dg_prefix = 'display_glyph '
|
||||
icons = {}
|
||||
dg_main = config.get_prefix_sections(dg_prefix)
|
||||
dg_main_names = {c.get_name(): 1 for c in dg_main}
|
||||
dg_def = [c for c in dconfig.get_prefix_sections(dg_prefix)
|
||||
if c.get_name() not in dg_main_names]
|
||||
for dg in dg_main + dg_def:
|
||||
glyph_name = dg.get_name()[len(dg_prefix):]
|
||||
glyph_data = []
|
||||
for line in dg.get('data').split('\n'):
|
||||
if line:
|
||||
line_val = int(line, 2)
|
||||
if line_val > 65535:
|
||||
raise config.error("Glyph line out of range for " + \
|
||||
"glyph %s maximum is 65535" % (glyph_name,))
|
||||
glyph_data.append(line_val)
|
||||
if len(glyph_data) < 16:
|
||||
raise config.error("Not enough lines for" + \
|
||||
"glyph %s, 16 lines are needed" % (glyph_name,))
|
||||
icons[dg.get_name()[len(dg_prefix):]] = glyph_data
|
||||
self.lcd_chip.set_glyphs(icons)
|
||||
# Initialization
|
||||
def handle_ready(self):
|
||||
self.lcd_chip.init()
|
||||
|
@ -159,13 +178,6 @@ class PrinterLCD:
|
|||
logging.exception("Error during display screen update")
|
||||
self.lcd_chip.flush()
|
||||
return eventtime + .500
|
||||
# Rendering helpers
|
||||
def animate_bed(self, row, col, eventtime):
|
||||
frame = int(eventtime) & 1
|
||||
return self.lcd_chip.write_glyph(col, row, 'bed_heat%d' % (frame + 1,))
|
||||
def animate_fan(self, row, col, eventtime):
|
||||
frame = int(eventtime) & 1
|
||||
return self.lcd_chip.write_glyph(col, row, 'fan%d' % (frame + 1,))
|
||||
def draw_text(self, row, col, mixed_text, eventtime):
|
||||
pos = col
|
||||
for i, text in enumerate(mixed_text.split('~')):
|
||||
|
@ -173,8 +185,6 @@ class PrinterLCD:
|
|||
# write text
|
||||
self.lcd_chip.write_text(pos, row, text)
|
||||
pos += len(text)
|
||||
elif text in self.glyph_helpers:
|
||||
pos += self.glyph_helpers[text](row, pos, eventtime)
|
||||
else:
|
||||
# write glyph
|
||||
pos += self.lcd_chip.write_glyph(pos, row, text)
|
||||
|
|
|
@ -95,6 +95,8 @@ class HD44780:
|
|||
data = data[:20 - min(x, 20)]
|
||||
pos = x + ((y & 0x02) >> 1) * 20
|
||||
self.text_framebuffers[y & 1][pos:pos+len(data)] = data
|
||||
def set_glyphs(self, glyphs):
|
||||
pass
|
||||
def write_glyph(self, x, y, glyph_name):
|
||||
char = TextGlyphs.get(glyph_name)
|
||||
if char is not None:
|
||||
|
|
|
@ -1,146 +0,0 @@
|
|||
# Common LCD icons
|
||||
#
|
||||
# Copyright (C) 2018 Aleph Objects, Inc <marcio@alephobjects.com>
|
||||
# Copyright (C) 2018 Alexander Fadeev <alfsoft@gmail.com>
|
||||
#
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
|
||||
extruder_icon = [
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0011111111111100,
|
||||
0b0000011111100000,
|
||||
0b0011111111111100,
|
||||
0b0000011111100000,
|
||||
0b0011111111111100,
|
||||
0b0000000000000000,
|
||||
0b0000111111110000,
|
||||
0b0000111111010000,
|
||||
0b0000111111110000,
|
||||
0b0000000000000000,
|
||||
0b0000001111000000,
|
||||
0b0000000110000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000
|
||||
]
|
||||
|
||||
bed_icon = [
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0001111111110000,
|
||||
0b0010000000001000,
|
||||
0b0111111111111100,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000
|
||||
]
|
||||
|
||||
bed_heat1_icon = [
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0010000100001000,
|
||||
0b0100001000010000,
|
||||
0b0010000100001000,
|
||||
0b0001000010000100,
|
||||
0b0010000100001000,
|
||||
0b0100001000010000,
|
||||
0b0010000100001000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0001111111110000,
|
||||
0b0010000000001000,
|
||||
0b0111111111111100,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000
|
||||
]
|
||||
|
||||
bed_heat2_icon = [
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0010000100001000,
|
||||
0b0001000010000100,
|
||||
0b0010000100001000,
|
||||
0b0100001000010000,
|
||||
0b0010000100001000,
|
||||
0b0001000010000100,
|
||||
0b0010000100001000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0001111111110000,
|
||||
0b0010000000001000,
|
||||
0b0111111111111100,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000
|
||||
]
|
||||
|
||||
fan1_icon = [
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000111000000000,
|
||||
0b0001111000011000,
|
||||
0b0001111000111100,
|
||||
0b0000111001111100,
|
||||
0b0000010000111100,
|
||||
0b0000000110000000,
|
||||
0b0000000110000000,
|
||||
0b0011110000100000,
|
||||
0b0011111001110000,
|
||||
0b0011110001111000,
|
||||
0b0001100001111000,
|
||||
0b0000000001110000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000
|
||||
]
|
||||
|
||||
fan2_icon = [
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000000111100000,
|
||||
0b0000000111100000,
|
||||
0b0000000111000000,
|
||||
0b0011000110000000,
|
||||
0b0011100000000000,
|
||||
0b0011110110111100,
|
||||
0b0011110110111100,
|
||||
0b0000000000011100,
|
||||
0b0000000110001100,
|
||||
0b0000001110000000,
|
||||
0b0000011110000000,
|
||||
0b0000011110000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000
|
||||
]
|
||||
|
||||
feedrate_icon = [
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b1110111011101100,
|
||||
0b1000100010001010,
|
||||
0b1100110011001010,
|
||||
0b1000100010001010,
|
||||
0b1000111011101100,
|
||||
0b0000000000000000,
|
||||
0b1100010011101110,
|
||||
0b1010101001001000,
|
||||
0b1100111001001100,
|
||||
0b1010101001001000,
|
||||
0b1010101001001110,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000,
|
||||
0b0000000000000000
|
||||
]
|
||||
|
||||
Icons16x16 = {
|
||||
'extruder': extruder_icon,
|
||||
'bed': bed_icon, 'bed_heat1': bed_heat1_icon, 'bed_heat2': bed_heat2_icon,
|
||||
'fan': fan1_icon, 'fan1': fan1_icon, 'fan2': fan2_icon,
|
||||
'feedrate': feedrate_icon,
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
#
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
import logging
|
||||
import icons, font8x14
|
||||
import font8x14
|
||||
|
||||
BACKGROUND_PRIORITY_CLOCK = 0x7fffffff00000000
|
||||
|
||||
|
@ -46,6 +46,7 @@ class ST7920:
|
|||
] + [(self.graphics_framebuffers[i], bytearray('~'*32), i)
|
||||
for i in range(32)]
|
||||
self.cached_glyphs = {}
|
||||
self.icons = {}
|
||||
def build_config(self):
|
||||
self.mcu.add_config_cmd(
|
||||
"config_st7920 oid=%u cs_pin=%s sclk_pin=%s sid_pin=%s"
|
||||
|
@ -108,13 +109,12 @@ class ST7920:
|
|||
0x06, # Set positive update direction
|
||||
0x0c] # Enable display and hide cursor
|
||||
self.send(cmds)
|
||||
# Setup animated glyphs
|
||||
self.cache_glyph('fan2', 'fan1', 0)
|
||||
self.cache_glyph('bed_heat2', 'bed_heat1', 1)
|
||||
self.flush()
|
||||
def cache_glyph(self, glyph_name, base_glyph_name, glyph_id):
|
||||
icon = icons.Icons16x16[glyph_name]
|
||||
base_icon = icons.Icons16x16[base_glyph_name]
|
||||
icon = self.icons.get(glyph_name)
|
||||
base_icon = self.icons.get(base_glyph_name)
|
||||
if icon is None or base_icon is None:
|
||||
return
|
||||
for i, (bits, base_bits) in enumerate(zip(icon, base_icon)):
|
||||
pos = glyph_id*32 + i*2
|
||||
b1, b2 = (bits >> 8) & 0xff, bits & 0xff
|
||||
|
@ -135,13 +135,19 @@ class ST7920:
|
|||
gfx_fb -= 32
|
||||
x += 16
|
||||
self.graphics_framebuffers[gfx_fb][x:x+len(data)] = data
|
||||
def set_glyphs(self, glyphs):
|
||||
for glyph_name, glyph_data in glyphs.items():
|
||||
self.icons[glyph_name] = glyph_data
|
||||
# Setup animated glyphs
|
||||
self.cache_glyph('fan2', 'fan1', 0)
|
||||
self.cache_glyph('bed_heat2', 'bed_heat1', 1)
|
||||
def write_glyph(self, x, y, glyph_name):
|
||||
glyph_id = self.cached_glyphs.get(glyph_name)
|
||||
if glyph_id is not None and x & 1 == 0:
|
||||
# Render cached icon using character generator
|
||||
glyph_name = glyph_id[0]
|
||||
self.write_text(x, y, glyph_id[1])
|
||||
icon = icons.Icons16x16.get(glyph_name)
|
||||
icon = self.icons.get(glyph_name)
|
||||
if icon is not None:
|
||||
# Draw icon in graphics mode
|
||||
for i, bits in enumerate(icon):
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
import logging
|
||||
import icons, font8x14, extras.bus
|
||||
import font8x14, extras.bus
|
||||
|
||||
BACKGROUND_PRIORITY_CLOCK = 0x7fffffff00000000
|
||||
|
||||
|
@ -23,10 +23,6 @@ class DisplayBase:
|
|||
self.font = [self._swizzle_bits(bytearray(c))
|
||||
for c in font8x14.VGA_FONT]
|
||||
self.icons = {}
|
||||
for name, icon in icons.Icons16x16.items():
|
||||
top1, bot1 = self._swizzle_bits([d >> 8 for d in icon])
|
||||
top2, bot2 = self._swizzle_bits(icon)
|
||||
self.icons[name] = (top1 + top2, bot1 + bot2)
|
||||
def flush(self):
|
||||
# Find all differences in the framebuffers and send them to the chip
|
||||
for new_data, old_data, page in self.all_framebuffers:
|
||||
|
@ -83,6 +79,11 @@ class DisplayBase:
|
|||
if (bits << col) & 0x80:
|
||||
page[pix_x] ^= bit
|
||||
pix_x += 1
|
||||
def set_glyphs(self, glyphs):
|
||||
for glyph_name, glyph_data in glyphs.items():
|
||||
top1, bot1 = self._swizzle_bits([d >> 8 for d in glyph_data])
|
||||
top2, bot2 = self._swizzle_bits(glyph_data)
|
||||
self.icons[glyph_name] = (top1 + top2, bot1 + bot2)
|
||||
def write_glyph(self, x, y, glyph_name):
|
||||
icon = self.icons.get(glyph_name)
|
||||
if icon is not None and x < 15:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue