class ParamGroup(object): def __init__(self, container, kind, parent=None, level=0, draw=True, title=None): self.container = container self.kind = kind self.parent = parent self.level = level self.title = title self.panel = SimplePanel(StyleName='aur-search-advanced-group') if level % 2 == 0: self.panel.addStyleName('aur-search-advanced-group-nested') self.childPanel = VerticalPanel(StyleName='aur-search-advanced-group-list', Width='100%') self.paramPanel = VerticalPanel(StyleName='aur-search-advanced-param-list', Width='100%') self.listPanel = VerticalPanel(StyleName='aur-search-advanced-list-boundary', Width='100%', Visible=False) self.paramChooser = ListBox() self.children = [] self.parameters = [] self.isInverted = False self.operator = 'and' # assigned by parent, visual use only self.op = None if parent else Label('and') if draw: self.draw() def draw(self): cont = VerticalPanel(Width='100%') header = HorizontalPanel(Width='100%', VerticalAlignment='middle', StyleName='aur-search-advanced-group-header') params = self.paramChooser addParam = Image(url='/ico/tick.png', Title='Add parameter to this group') addGroup = Image(url='/ico/table_add.png', Title='Nest group within this group') addGroupFull = Image(url='/ico/table_lightning.png', Title='Nest group within this group; all parameters') invertSelf = Image(url='/ico/exclamation.png', Title='Invert this parameter group') self.container.add(self.panel) self.panel.setWidget(cont) cont.add(header) if self.parent: d = Image(url='/ico/cross.png', Title='Delete this parameter group') d.addStyleName('aur-search-advanced-delete') header.add(d) header.setCellWidth(d, '1px') d.addClickListener(getattr(self, 'delSelf')) if self.title: t = Label(self.title, StyleName='aur-search-advanced-group-header-title') header.add(t) header.setCellWidth(t, '1px') header.add(params) header.add(addParam) header.add(addGroup) header.add(addGroupFull) header.add(invertSelf) header.setCellWidth(params, '1px') header.setCellWidth(addGroup, '1px') header.setCellWidth(addGroupFull, '1px') header.setCellWidth(invertSelf, '1px') for x in self.kind: params.addItem(x['item'], x['index']) cont.add(self.listPanel) self.listPanel.add(self.paramPanel) self.listPanel.add(self.childPanel) addParam.addClickListener(getattr(self, 'addParam')) addGroup.addClickListener(getattr(self, 'addGroup')) addGroupFull.addClickListener(getattr(self, 'addGroupFull')) invertSelf.addClickListener(getattr(self, 'invertSelf')) def addGroup(self, sender): self.listPanel.setVisible(True) op = Label(self.operator, Title='Invert group operator', StyleName='aur-search-advanced-group-op', Visible=False) op.addClickListener(getattr(self, 'invertOperator')) if len(self.children) > 0 or len(self.parameters) > 0: op.setVisible(True) self.childPanel.add(op) self.childPanel.setCellHorizontalAlignment(op, 'right') g = ParamGroup(self.childPanel, self.kind, self, self.level+1) g.op = op self.children.append(g) def addGroupFull(self, sender): # this is a little hacky, but it's so fast you don't see it self.addGroup(None) group = self.children[len(self.children)-1] for x in range(group.paramChooser.getItemCount()): group.paramChooser.setSelectedIndex(x) group.addParam(None) group.paramChooser.setSelectedIndex(0) def addParam(self, sender): self.listPanel.setVisible(True) op = Label(self.operator, Title='Invert group operator', StyleName='aur-search-advanced-param-op', Visible=False) op.addClickListener(getattr(self, 'invertOperator')) if len(self.parameters) > 0: op.setVisible(True) self.paramPanel.add(op) self.paramPanel.setCellHorizontalAlignment(op, 'right') k = self.kind[self.paramChooser.getSelectedValues()[0]] p = Param(self.paramPanel, k, self) p.op = op self.parameters.append(p) if len(self.children) > 0: self.children[0].op.setVisible(True) def addParamFull(self, sender): # this is a little hacky, but it's so fast you don't see it old = self.paramChooser.getSelectedIndex() for x in range(self.paramChooser.getItemCount()): self.paramChooser.setSelectedIndex(x) self.addParam(None) self.paramChooser.setSelectedIndex(old) def delGroup(self, child): self.children.remove(child) self.childPanel.remove(child.op) self.childPanel.remove(child.panel) lp = len(self.parameters) lc = len(self.children) if lp == 0 and lc > 0: self.children[0].op.setVisible(False) if lp == 0 and lc == 0: self.listPanel.setVisible(False) def delParam(self, param): self.parameters.remove(param) self.paramPanel.remove(param.op) self.paramPanel.remove(param.panel) lp = len(self.parameters) lc = len(self.children) if lp > 0: self.parameters[0].op.setVisible(False) if lp == 0 and lc > 0: self.children[0].op.setVisible(False) if lp == 0 and lc == 0: self.listPanel.setVisible(False) def delSelf(self, sender): self.parent.delGroup(self) def invertSelf(self, sender): if self.isInverted: self.isInverted = False self.panel.removeStyleName('aur-search-advanced-group-inverted') self.op.setText(self.operator) else: self.isInverted = True self.panel.addStyleName('aur-search-advanced-group-inverted') self.op.setText(self.operator + ' not') def invertOperator(self, sender): self.operator = 'or' if self.operator == 'and' else 'and' for x in self.parameters: suffix = ' not' if x.isInverted else '' x.op.setText(self.operator + suffix) for x in self.children: suffix = ' not' if x.isInverted else '' x.op.setText(self.operator + suffix)
class Application: def __init__(self): #set some vars self.title = "last.fm" #this is where we build the ui self.statusPanel = VerticalPanel() self.statusPanel.setID('status_panel') #make a few Labels to hold station, artist, track, album info self.stationLabel = Label() self.artistLabel = Label() self.trackLabel = Label() self.albumLabel = Label() self.timeLabel = Label() self.infoTable = FlexTable() i=0 self.stationLabel = Label() self.infoTable.setWidget(i,0,Label("Station:") ) self.infoTable.setWidget(i,1,self.stationLabel) i+=1 self.infoTable.setWidget(i,0,Label("Artist:") ) self.infoTable.setWidget(i,1,self.artistLabel) i+=1 self.infoTable.setWidget(i,0,Label("Track:") ) self.infoTable.setWidget(i,1,self.trackLabel) i+=1 self.infoTable.setWidget(i,0,Label("Album:") ) self.infoTable.setWidget(i,1,self.albumLabel) self.statusPanel.add(self.infoTable) self.statusPanel.add(self.timeLabel) #make the time bar timebarWrapperPanel = SimplePanel() timebarWrapperPanel.setID("timebar_wrapper") #timebarWrapperPanel.setStyleName('timebar_wrapper') self.timebarPanel = SimplePanel() self.timebarPanel.setID("timebar") #self.timebarPanel.setStyleName('timebar') timebarWrapperPanel.add(self.timebarPanel) self.statusPanel.add(timebarWrapperPanel) #make some shit for buttons self.buttonHPanel = HorizontalPanel() self.skipButton = Button("Skip", self.clicked_skip ) self.buttonHPanel.add(self.skipButton) loveButton = Button("Love", self.clicked_love ) self.buttonHPanel.add(loveButton) pauseButton = Button("Pause", self.clicked_pause ) self.buttonHPanel.add(pauseButton) banButton = Button("Ban", self.clicked_ban ) self.buttonHPanel.add(banButton) #control the volume self.volumePanel = HorizontalPanel() self.volumeLabel = Label("Volume:") self.volumePanel.add(self.volumeLabel) volupButton = Button("+", self.clicked_volume_up, 5) self.volumePanel.add(volupButton) voldownButton = Button("-", self.clicked_volume_down, 5) self.volumePanel.add(voldownButton) #make buttons and shit to create a new station self.setStationHPanel = HorizontalPanel() self.setStationTypeListBox = ListBox() self.setStationTypeListBox.setVisibleItemCount(0) self.setStationTypeListBox.addItem("Similar Artists", "artist/%s/similarartists") self.setStationTypeListBox.addItem("Top Fans", "artist/%s/fans") self.setStationTypeListBox.addItem("Library", "user/%s/library") self.setStationTypeListBox.addItem("Mix", "user/%s/mix") self.setStationTypeListBox.addItem("Recommended", "user/%s/recommended") self.setStationTypeListBox.addItem("Neighbours", "user/%s/neighbours") self.setStationTypeListBox.addItem("Global Tag", "globaltags/%s") self.setStationHPanel.add(self.setStationTypeListBox) self.setStationTextBox = TextBox() self.setStationTextBox.setVisibleLength(10) self.setStationTextBox.setMaxLength(50) self.setStationHPanel.add(self.setStationTextBox) self.setStationButton = Button("Play", self.clicked_set_station) self.setStationHPanel.add(self.setStationButton) #make an error place to display data self.infoHTML = HTML() RootPanel().add(self.statusPanel) RootPanel().add(self.buttonHPanel) RootPanel().add(self.volumePanel) RootPanel().add(self.setStationHPanel) RootPanel().add(self.infoHTML) def run(self): self.get_track_info() def get_track_info(self): HTTPRequest().asyncGet("/track_info", TrackInfoHandler(self)) Timer(5000,self.get_track_info) def clicked_skip(self): self.skipButton.setEnabled(False) HTTPRequest().asyncGet("/skip",ButtonInfoHandler(self,self.skipButton) ) def clicked_volume_down(self): HTTPRequest().asyncGet("/volume/down",NullInfoHandler(self) ) def clicked_volume_up(self): HTTPRequest().asyncGet("/volume/up",NullInfoHandler(self) ) def clicked_love(self): HTTPRequest().asyncGet("/love",NullInfoHandler(self) ) def clicked_ban(self): result = Window.confirm("Really ban this song?") if result: HTTPRequest().asyncGet("/ban",NullInfoHandler(self) ) def clicked_pause(self): HTTPRequest().asyncGet("/pause",NullInfoHandler(self) ) def clicked_set_station(self): type = self.setStationTypeListBox.getSelectedValues()[0] text = self.setStationTextBox.getText().strip() if len(text) > 0 : #clear the text self.setStationTextBox.setText("") station = type % text HTTPRequest().asyncGet("/station/%s" % station,NullInfoHandler(self) ) def set_error(self, content): self.infoHTML.setHTML("<pre>%s</pre>" % content) def onTimeout(self,text): self.infoHTML.setHTML("timeout: "+text) def onError(self, text, code): self.infoHTML.setHTML(text + "<br />" + str(code)) def process_track_info(self,text): #explode the text at :: #%a::%t::%l::%d::%R::%s::%v::%r data = text.split("::") artist = data[0] track = data[1] album = data[2] duration = data[3] played = int(duration)-int(data[4]) percent = int( played/int(duration)*100 ) self.artistLabel.setText( artist ) self.trackLabel.setText( track ) self.albumLabel.setText( album ) #format time t = "%s : %d %d" % (duration,played,percent) self.timeLabel.setText(data[7]) #update the timebarwidth self.timebarPanel.setWidth("%d%" % (percent) ) #set the station self.stationLabel.setText(data[5]) #display the volume self.volumeLabel.setText("Volume: "+data[6]) Window.setTitle(self.title+": "+artist+" - "+track)