From 3dcac1308e6fe132487c45824d142609f2571df6 Mon Sep 17 00:00:00 2001 From: Florian Heilmann Date: Sun, 7 Jun 2020 16:25:19 +0000 Subject: [PATCH] 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 --- config/example-extras.cfg | 11 +++ klippy/extras/display/display.cfg | 145 ++++++++++++++++++++++++++++- klippy/extras/display/display.py | 34 ++++--- klippy/extras/display/hd44780.py | 2 + klippy/extras/display/icons.py | 146 ------------------------------ klippy/extras/display/st7920.py | 20 ++-- klippy/extras/display/uc1701.py | 11 ++- 7 files changed, 196 insertions(+), 173 deletions(-) delete mode 100644 klippy/extras/display/icons.py diff --git a/config/example-extras.cfg b/config/example-extras.cfg index ca36c969..59c2c82a 100644 --- a/config/example-extras.cfg +++ b/config/example-extras.cfg @@ -1903,6 +1903,17 @@ # template. This field is evaluated using command templates (see # docs/Command_Templates.md). This parameter must be provided. +# Display a custom glyph on displays that support it. The given name +# will be assigned the given display data which can then be referenced +# in the display templates by their name surrounded by two "tilde" symbols +# i.e. ~my_display_glyph~ +#[display_glyph my_display_glyph] +#data: +# The display data, stored as 16 lines consisting of 16 bits (1 per pixel) +# e.g. 1111111111111111 to display a solid horizontal line. Put each display +# line into a separate config line. The glyph must consist of exactly 16 +# lines with 16 bits each. + # If a primary [display] section has been defined in printer.cfg as shown # above it is possible to define multiple auxilary displays. Note that # auxilary displays do not currently support menu functionality, thus they diff --git a/klippy/extras/display/display.cfg b/klippy/extras/display/display.cfg index e6b46c8c..bb395cc4 100644 --- a/klippy/extras/display/display.cfg +++ b/klippy/extras/display/display.cfg @@ -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 diff --git a/klippy/extras/display/display.py b/klippy/extras/display/display.py index 0433c432..880e0a32 100644 --- a/klippy/extras/display/display.py +++ b/klippy/extras/display/display.py @@ -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) diff --git a/klippy/extras/display/hd44780.py b/klippy/extras/display/hd44780.py index 49cf0572..b1faef45 100644 --- a/klippy/extras/display/hd44780.py +++ b/klippy/extras/display/hd44780.py @@ -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: diff --git a/klippy/extras/display/icons.py b/klippy/extras/display/icons.py deleted file mode 100644 index 8f91a2b1..00000000 --- a/klippy/extras/display/icons.py +++ /dev/null @@ -1,146 +0,0 @@ -# Common LCD icons -# -# Copyright (C) 2018 Aleph Objects, Inc -# Copyright (C) 2018 Alexander Fadeev -# -# 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, -} diff --git a/klippy/extras/display/st7920.py b/klippy/extras/display/st7920.py index 9cfcdb16..30c3dfb1 100644 --- a/klippy/extras/display/st7920.py +++ b/klippy/extras/display/st7920.py @@ -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): diff --git a/klippy/extras/display/uc1701.py b/klippy/extras/display/uc1701.py index f19d9f97..690ea0bc 100644 --- a/klippy/extras/display/uc1701.py +++ b/klippy/extras/display/uc1701.py @@ -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: