#!/usr/bin/env python # vim: set expandtab ts=4: from gi.repository import GLib, Gtk import cairo, pango, pangocairo ml = GLib.MainLoop() import pttarget, ptlayout from ptlayout import PTLText import time import usb.core class MainWindow(object): def __init__(self): builder = Gtk.Builder() builder.add_from_file('ptgui.glade') builder.connect_signals(self) self.tape = None self.tgtwidth = 192 self.wnd = builder.get_object('mainwnd') self.wnd.connect("delete-event", Gtk.main_quit) for name in ['statuslabel', 'tabviewport', 'img', 'printbtn', 'color_fg', 'color_bg', 'numcopies', 'cuttoggle', 'devbox']: self.__dict__[name] = builder.get_object(name) self.ctlgrid = Gtk.Table() self.tabviewport.add(self.ctlgrid) self.layout = ptlayout.PTLHSeq() self.layout.spacing = 0 # vs1 = ptlayout.PTLVStack() # vs1.add(PTLText()) # vs1.add(PTLText()) # vs2 = ptlayout.PTLVStack() # vs2.add(PTLText()) # vs2.add(PTLText()) t = PTLText() t.font = 'FrutigerNextLT Medium 20' t.mode = 'left' self.layout.add(t) t = PTLText() t.font = 'FrutigerNextLT Heavy 60' t.mode = 'left' self.layout.add(t) self.layout.add(PTLText()) t = PTLText() t.font = 'FrutigerNextLT Heavy 60' t.mode = 'right' self.layout.add(t) t = PTLText() t.font = 'FrutigerNextLT Medium 20' t.mode = 'right' self.layout.add(t) self.layout.add(PTLText()) self.layout_put_controls() self.sizing_apply() self.img.connect('draw', self.draw) # help(self.img) self.devlist = Gtk.ListStore(str, object) self.devbox.set_model(self.devlist) self.scan() self.dev_select() self.display_refresh() self.wnd.show_all() GLib.timeout_add(100, self.status_update) def scan(self): pttarget.PTUSB.scan() for dev in pttarget.PTUSB.printers: print str(dev) self.devlist.append([str(dev), dev]) if len(self.devlist) == 0: for dummy_width in [9,12,24]: dummy_printer = pttarget.PTPrinter(dummy_width) self.devlist.append([str(dummy_printer), dummy_printer]) itr = self.devlist.get_iter((0, )) self.devbox.set_active_iter(itr) def dev_select(self): itr = self.devbox.get_active_iter() if itr is None: return dev = self.devlist[itr][1] dev.setup() self.status_update() def status_update(self): itr = self.devbox.get_active_iter() if itr is None: return dev = self.devlist[itr][1] try: if dev.last_status is None or time.time() - dev.last_status >= 1: dev.refresh_status() else: dev.check_status() except usb.core.USBError, e: print 'problem while status refresh:', str(e) if dev.err1 == 0 and dev.err2 == 0: self.printbtn.set_sensitive(True) if dev.find_tape() != self.tape: self.tape = dev.find_tape() self.sizing_apply() self.layout_update() else: self.printbtn.set_sensitive(False) mtype = pttarget.media_types.get(dev.media_type, 'unknown (%02x)' % (dev.media_type)) msize = '%dx%dmm' % (dev.media_width, dev.media_length) if dev.media_length != 0 else \ '%dmm continuous tape' % (dev.media_width) self.statuslabel.set_text('Status: %s, %s %s' % (dev.get_errstr(), mtype, msize)) return True def sizing_apply(self): if self.tape is None: self.label_surface = None tapeh = 16 else: self.label_surface = cairo.ImageSurface(cairo.FORMAT_A1, self.tgtwidth, self.tape.pixels) tapeh = self.tape.pixels self.display_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, self.tgtwidth + 40, tapeh + 40) self.img.set_size_request(self.display_surface.get_width(), self.display_surface.get_height()) #ctx = cairo.Context(self.label_surface) # for i in range(0, 128 / 16): # x = 16 * (i & 1) # ctx.rectangle(x, i * 16, 12, 12) # ctx.fill() # for i in range(0, 128 / 16): # x = 32 + 16 * (i & 1) # ctx.rectangle(x, i * 16, 12, 12) # ctx.fill() # pctx = pangocairo.CairoContext(ctx) # font = pango.FontDescription('Delicious 24') # layout = pctx.create_layout() # layout.set_font_description(font) # layout.set_text(u'Hello') # pctx.update_layout(layout) # pctx.show_layout(layout) # self.display_refresh() def display_refresh(self, *args): ctx = cairo.Context(self.display_surface) w = self.display_surface.get_width() h = self.display_surface.get_height() for x in range(0, w, 16): for y in range(0, h, 16): col = 0.3 + 0.1 * (((x + y) / 16) & 1) ctx.rectangle(x, y, 16, 16) ctx.set_source_rgb(col, col, col) ctx.fill() if self.label_surface is None: return pw = self.label_surface.get_width() ph = self.label_surface.get_height() px, py = (w - pw) / 2, (h - ph) / 2 ctx.rectangle(px, py, pw, ph) bg = self.color_bg.get_rgba() ctx.set_source_rgb(bg.red, bg.green, bg.blue) ctx.fill() fg = self.color_fg.get_rgba() ctx.set_source_rgb(fg.red, fg.green, fg.blue) ctx.mask_surface(self.label_surface, px, py) self.img.queue_draw() def draw(self, widget, ctx): ctx.set_source_surface(self.display_surface) w = self.display_surface.get_width() h = self.display_surface.get_height() ctx.rectangle(0, 0, w, h) ctx.fill() def layout_update(self): if self.label_surface is None: return w, h = self.layout.prep_size(self.label_surface.get_height()) if w < 32: w = 32 if w != self.tgtwidth: self.tgtwidth = w self.sizing_apply() if self.label_surface is None: return self.label_surface = cairo.ImageSurface(cairo.FORMAT_A1, self.tgtwidth, self.tape.pixels) ctx = cairo.Context(self.label_surface) ctx.set_operator(cairo.OPERATOR_SOURCE) finw = self.layout.render(ctx, self.label_surface.get_height()) self.display_refresh() def layout_control(self, node, name, spec): elem = Gtk.Entry() buf = elem.get_buffer() def update(buf, *args): node.__dict__[name] = buf.get_text() self.layout_update() buf.set_text(node.__dict__[name], -1) buf.connect('deleted-text', update) buf.connect('inserted-text', update) return elem def layout_put_controls(self): nodes = [self.layout] rows = -1 while len(nodes) > 0: rows += 1 # separator node = nodes.pop(0) nodes.extend(node.children()) for p in node.properties(): rows += 1 self.ctlgrid.resize(rows, 2) nodes = [self.layout] row = 0 first = True while len(nodes) > 0: if not first: hs = Gtk.HSeparator() self.ctlgrid.attach(hs, 0, 2, row, row + 1, ypadding = 3.0, xoptions = Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, yoptions = 0) row += 1 first = False node = nodes.pop(0) nodes.extend(node.children()) for p in node.properties(): elem = self.layout_control(node, p[0], p[1]) lbl = Gtk.Label(p[0]) lbl.set_alignment(0.0, 0.5) self.ctlgrid.attach(lbl, 0, 1, row, row + 1, xoptions = Gtk.AttachOptions.FILL, yoptions = 0) self.ctlgrid.attach(elem, 1, 2, row, row + 1, xoptions = Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, yoptions = 0) row += 1 def on_print(self, *args): if self.label_surface is None: return copies = self.numcopies.get_buffer().get_text() if copies.strip() == '': copies = 1 else: copies = int(copies) feedlast = self.cuttoggle.get_active() data = pttarget.PTLabelData() data.addcairo(self.label_surface, offset = self.tape.offset) itr = self.devbox.get_active_iter() dev = self.devlist[itr][1] for i in range(0, copies): dev.send(data.get(feedlast and i == copies - 1)) mw = MainWindow() Gtk.main() # ml.run()