diff -r b5878197d017 -r 136e210fce82 qmsk/dmx/web.py --- a/qmsk/dmx/web.py Mon Apr 21 00:20:27 2014 +0300 +++ b/qmsk/dmx/web.py Thu May 01 23:34:20 2014 +0300 @@ -3,6 +3,39 @@ import logging; log = logging.getLogger('qmsk.dmx.web') +def colorize (x, red, green, blue, alpha=1.0) : + return x(style='background-color: rgba({red}, {green}, {blue}, {alpha:0.2f})'.format(red=red, green=green, blue=blue, alpha=alpha)) + +def input (head, name, value) : + return html.input( + type = 'text', + name = '-'.join([head, name]), + + id = '-'.join([head, name]), + class_ = 'form-control dmx-input dmx-input-{name}'.format(name=name), + + placeholder = name, + value = '{v:d}'.format(v=value) if value else None, + ) + +def color_input (head, c, value) : + color = dict(red=0, green=0, blue=0, alpha=0) + + color[c] = 255 + if value : + color[alpha] = value / 255.0 + + return colorize(input(head, c, value), **color) + +def slider (head, name) : + return html.div(id='-'.join([head, name, 'slider']), class_='dmx-slider dmx-slider-{name}'.format(name=name)) + +def color_slider (head, c) : + return slider(head, c) + +def head_color (head, value) : + return html.div(class_='dmx-color-background')(colorize(html.div(id='-'.join([head, 'color']), class_='dmx-color')(' '), **value)) + class Handler (pvl.web.Handler) : # Bootstrap DOCTYPE = 'html' @@ -11,6 +44,8 @@ CSS = ( '//code.jquery.com/ui/1.10.4/themes/ui-darkness/jquery-ui.css', '//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css', + + '/static/dmx.css', ) JS = ( '//code.jquery.com/jquery-2.1.0.js', @@ -18,125 +53,71 @@ '//netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js', '/static/color-slider.js', + '/static/dmx.js', ) - STYLE = """ -body { - padding-top: 2em; - text-align: center; -} - -.container { - padding: 2em 1em; - text-align: left; -} - -.panel { - width: 30em; - margin: 1em auto; -} - -input.color-control { - width: 5em; -} - -div#color { - width: 5em; - height: 5em; - - margin: 1em auto; -} - -div.color-slider { - margin: 1em; -} - -div.color-slider#slider-r .ui-slider-range { - background: #ff0000; -} - -div.color-slider#slider-g .ui-slider-range { - background: #00ff00; -} - -div.color-slider#slider-b .ui-slider-range { - background: #0000ff; -} - """ - # test TITLE = u"DMX Control" def process (self) : if self.request.method == 'POST' : - self.color = tuple((int(x, 16) if x else 0) for x in ( + # XXX + r, g, b = tuple((int(x, 16) if x else 0) for x in ( self.request.form.get('r'), self.request.form.get('g'), self.request.form.get('b'), )) - r, g, b = self.color - self.app.dmx_color(r, g, b, 255) - else : - self.color = None - - log.info("%s", self.color) - - def render (self) : - if self.color : - r, g, b = self.color + def render_head (self, name, head) : + if head.alpha() is None : + head_input = head_slider = None else : - r = g = b = None - - def color_swatch () : - return html.div(id='color', - style='background-color: rgb({r}, {g}, {b})'.format(r=r, g=g, b=b) - )(' '), - - def color_input (name, value) : - color = dict(r=0, g=0, b=0) - bgcolor = dict(r=0, g=0, b=0) - - if value : - color[name] = value - alpha = value / 255.0 - else : - alpha = 0 - - bgcolor[name] = 255 + head_input = input(name, 'alpha', head.alpha()['alpha']) + head_slider = slider(name, 'alpha') - return html.input(type='text', name=name, - class_ = 'form-control color-control', - placeholder = name, - id = name, + rowspan = 1 - value = '{v:02x}'.format(v=value) if value else None, - style = 'background-color: rgba({r}, {g}, {b}, {a:0.2f})'.format(a=alpha, **bgcolor), + if head.color() is None : + colors = { } + color = None + else : + colors = head.color() + color = head_color(name, colors) + rowspan += 3 + + yield html.tr( + html.th(rowspan=rowspan)(name), + html.td(head_input), + html.td(head_slider), + html.td(rowspan=rowspan)(color), + ) + + for c in colors : + yield html.tr( + html.td( + color_input(name, c, colors[c]), + ), + html.td( + color_slider(name, c), + ), ) - + + def render (self) : return html.div(class_='container')( - html.div(class_='panel')( - color_swatch(), - html.div(id='slider-r', class_='color-slider')(' '), - html.div(id='slider-g', class_='color-slider')(' '), - html.div(id='slider-b', class_='color-slider')(' '), - html.form(action='.', method='POST', class_='form-inline')( - #html.label(for_='color', class_='control-label')("Color"), - html.div(class_='form-group')( - color_input('r', r), + html.form(action='.', method='POST')( + html.table(class_='dmx')( + html.thead( + html.th(class_='dmx-head')(u"Head"), + html.th(class_='dmx-value')(u"DMX"), + html.th(class_='dmx-control')(u"Control"), + html.th(class_='dmx-head-control')(u"Head Control"), ), - html.div(class_='form-group')( - color_input('g', g), - ), - html.div(class_='form-group')( - color_input('b', b), - ), - html.div(class_='form-group')( - html.button(type='submit', class_='btn btn-primary')("Go"), - ), - ) + html.tbody(self.render_head(name, head) for name, head in sorted(self.app.heads.iteritems())), + ), + + html.button(type='submit', class_='btn btn-primary')("Go"), ) ) @@ -145,17 +126,8 @@ urls.rule('/', Handler), )) - def __init__ (self, dmx, **opts) : + def __init__ (self, dmx, heads, **opts) : super(DMXWebApplication, self).__init__(**opts) self.dmx = dmx - - def dmx_color (self, r, g, b, a=255) : - # Stairville LED Par56 - self.dmx[1] = (0, r, g, b, 0) - - # 4ch dimmer - self.dmx[5] = (a, a, a, a) - - # American DJ - Mega Tri 60 - Mode 2 - self.dmx[10] = (r, g, b, 0, a) + self.heads = heads