Live slider updating (gtk help)

------------------------ MDE: the Matplotlib Desktop

    > Environment

Thanks for the hard work there Dr Perez! You might also want to
mention that MDE supports TeX rendering for all GUI widgets and text
boxes :slight_smile: In support of the MDE, I offer an enhanced text box. This
one actually works decently, but still has a few lingering problems

  * Trailing spaces are ignored in the calculation of the text size so
    the cursor isn't always in the right position. This is relatively
    easy to fix or approximate

  * This example reveals a limitation in how mpl lays out text. The
    vertical positions 'top', 'center', or 'bottom' apply to the text
    bounding box. This can cause the whole text field to be raised or
    lowered depending on what is typed. Very disconcerting. We'll
    need a new flag, something like "baseline" to indicate that the y
    position is the text baseline

  * How to make the cursor blink? I tried writing a timer based on
    the python threading module, but I don't think this plays nicely
    with the mainloop. It might be work exposing the underlying gui
    timers in the matplotlib gui abstraction layer.

For kicks, attached below is the screenshot I captured with this
examples enabling usetex in which I typed \alpha_i = \beta_j into the
textbox... It *worked* but caused some errors to be generated in
transit because the TeX was continuously compiled before the string
was complete..... Still a little work to be done..

from pylab import *
from matplotlib.transforms import lbwh_to_bbox, identity_transform
    
class TextBox(Widget):
    def __init__(self, ax, s=''):
        self.canvas = ax.figure.canvas
        self.text = ax.text(0.025, 0.2, s,
                            fontsize=14,
                            verticalalignment='bottom',
                            horizontalalignment='left',
                            transform=ax.transAxes)
        self.ax = ax
        ax.set_yticks()
        ax.set_xticks()
        
        ax.set_navigate(False)
        self.canvas.draw()
        self.canvas.mpl_connect('key_press_event', self.keypress)

        self.region = self.canvas.copy_from_bbox(ax.bbox)
        
        r = self._get_text_right()
        self.cursor, = ax.plot([r,r], [0.2, 0.8], transform=ax.transAxes)
        self.redraw()

    def redraw(self):
        self.ax.redraw_in_frame()
        self.canvas.blit(self.ax.bbox)

    def keypress(self, event):
        if event.key is not None and len(event.key)>1: return

        t = self.text.get_text()
        if event.key is None: # simulate backspace
            if len(t): newt = t[:-1]
            else: newt = ''
        else:
            newt = t + event.key
            
        self.text.set_text(newt)

        r = self._get_text_right()
        self.cursor.set_xdata([r,r])
        self.redraw()

    def _get_text_right(self):
        l,b,w,h = self.text.get_window_extent().get_bounds()
        r = l+w+2
        t = b+h
        l,b = self.ax.transAxes.inverse_xy_tup((l,b))
        r,t = self.ax.transAxes.inverse_xy_tup((r,t))
        return r
        
ion()
f = figure()
ax = axes([0.1, 0.1, 0.8, 0.7])
plot([1,2,3])

#rc('text', usetex=1)
f.text(0.39, 0.875, 'My label: ',
       horizontalalignment='right', verticalalignment='center')
axtext = axes([0.4, 0.85, 0.2, 0.05])
box = TextBox(axtext)

show()