We're back after a server migration that caused effbot.org to fall over a bit harder than expected. Expect some glitches.

Implementing A Simple Text Display Widget

Fredrik Lundh | September 2004 | Originally posted to online.effbot.org

Time for some WCK programming. The following snippet implements a simple text widget, which can display a single paragraph of text:

from WCK import Widget, FONT, FOREGROUND

class SimpleTextView(Widget):

    ui_option_text = ""

    ui_option_width = 200
    ui_option_height = 100

    ui_option_font = FONT

    ui_option_foreground = FOREGROUND

    def ui_handle_config(self):
        self.font = self.ui_font(
            self.ui_option_foreground, self.ui_option_font
        return int(self.ui_option_width), int(self.ui_option_height)

    def ui_handle_repair(self, draw, x0, y0, x1, y1):
        space = draw.textsize(" ", self.font)[0]
        words = self.ui_option_text.split()
        x = y = 0
        for word in words:
            # check size of this word
            w, h = draw.textsize(word, self.font)
            # figure out where to draw it
            if x:
                x += space
                if x + w > x1:
                    # new line
                    x = 0
                    y += h
            draw.text((x, y), word, self.font)
            x += w

The repair code treats the text as a single paragraph, consisting of one long list of words. Note that the code always draws words that start at the left margin, even if they won’t fit on the line. For all other words (where x is not zero), the code checks if there’s room for a space character and the word on the current line. If not (that is, if x+w>x1 where x1 is the right margin), it moves on to the next line.

Also note the use of a precomputed font object, and the use of FONT and FOREGROUND constants from the WCK module.

Here’s a usage example:

TEXT = """
I tell you I have been in the editorial business going on fourteen
years, and it is the first time I ever heard of a man's having to know
anything in order to edit a newspaper. You turnip!

w = SimpleTextView(None, text=TEXT)
w.pack(expand=1, fill="both")

In upcoming articles, we’ll look at how this can be extended to support multiple paragraphs, different text styles, etc. Stay tuned.