def taskMenu_inner(_=None): self.clear_widgets() taskMenuLayout = GridLayout(cols=1, spacing=10, size_hint_y=None) taskMenuLayout.bind(minimum_height=taskMenuLayout.setter('height')) self.scroll_y = 1 self.add_widget(taskMenuLayout) backButton = Button(text=getTaskName(tid), size_hint_y=None, height=100) statusLabel = Label(font_size='12sp', valign = 'top', halign='left') if isRunning(tid, True): backButton.background_color = (0.8,1,0.8,1) statusLabel.text = localisation.get(language, "end") + " " + getDateString(getLastDeadline(tid)) elif isComplete(tid): backButton.background_color = (1,0.8,0.8,1) statusLabel.text = localisation.get(language, "cooldown") + " " + getDateString(getCompletionExpirationDate(tid)) else: statusLabel.text = localisation.get(language, "limbo") + " " + getDateString(getCompletionExpirationDate(tid)) backButton.bind(on_press=self.buildMainScreen) taskMenuLayout.add_widget(backButton) taskMenuLayout.add_widget(statusLabel) for milestone in getMilestones(tid): taskMenuLayout.add_widget(self.makeMilestoneLayout(tid, milestone, oldScore if milestone == getNextMilestone(tid) else None)) newMilestoneButton = Button(text=localisation.get(language,"newdate"), bold=True, size_hint_y=None, height=100) taskMenuLayout.add_widget(newMilestoneButton) newMilestoneButton.bind(on_press=self.mileStonePopup(tid)) delConfirmSwitch = Switch() delConfirmPopup = Popup(title=localisation.get(language, "sure"), content=delConfirmSwitch, size_hint=(None, None), size=(200, 200)) delConfirmPopup.bind(on_dismiss=self.deleteTask(tid, delConfirmSwitch)) delButton = Button(text=localisation.get(language,"deltask"), bold=True, size_hint_y=None, height=100) delButton.bind(on_press=delConfirmPopup.open) taskMenuLayout.add_widget(delButton)
def _create_popup(self, instance): # create the popup content = BoxLayout(orientation='vertical', spacing='5dp') box = GridLayout(cols=1, spacing="5dp") box.bind(minimum_height=box.setter('height')) self.popup = popup = Popup(content=content, title=self.title, size_hint=(None, 1), width='400dp') #popup.height = len(self.options) * dp(55) + dp(150) # add all the options content.add_widget(Widget(size_hint_y=None, height=1)) uid = str(self.uid) for option in self.options: state = 'down' if option == self.value else 'normal' btn = ToggleButton(text=option, state=state, group=uid) btn.bind(on_release=self._set_option) box.add_widget(btn) #box.height = metrics.dp(35) * len(self.options) scroll = ScrollView(pos_hint={'center_x': .5, 'center_y': .5}, do_scroll_x=False, size_hint=(1, 1)) scroll.add_widget(box) content.add_widget(scroll) # 2 buttons are created for accept or cancel the current value btnlayout = BoxLayout(size_hint_y=None, height='50dp', spacing='5dp') btn = Button(text='OK') btn.bind(on_release=self._validate) btnlayout.add_widget(btn) btn = Button(text='Cancel') btn.bind(on_release=self.popup.dismiss) btnlayout.add_widget(btn) content.add_widget(btnlayout) # and open the popup ! popup.open()
def build(self): topic = 'Python' layout = GridLayout(cols=2, size_hint_y=None, spacing=10, padding=(10,10,10,10)) layout.bind(minimum_height=layout.setter('height')) message = fetch(topic) for data in message: l = Button(text=data, text_size=(300, None), size_hint_y=None, padding=(5, 5), bold=True) # calculating height here before = l._label.render() l.text_size=(300, None) after = l._label.render() l.height = 60 + (after[1]/before[1])*before[1] # ammount of rows * single row height # end layout.add_widget(l) sub = ScrollView() sub.add_widget(layout) root = GridLayout(cols=1) title = Label(text='Facebook Mining Topic: ' + topic, font_size=30, size_hint_y=None, height=100) root.add_widget(title) textinput = TextInput(hint_text='Search ...', multiline=False, size_hint_y=None, height=40) textinput.bind(on_text_validate=on_enter) root.add_widget(textinput) root.add_widget(sub) return root
def subscroll(self): """ opens scroll list of substitute characters in a popup """ for btn in SMApp.teamlist: if btn.state == 'down': SMApp.nameOff = btn btn.state = 'normal' curs.execute('SELECT * FROM Subs') layout2 = GridLayout(cols=2, spacing=10, size_hint_y=None) layout2.bind(minimum_height=layout2.setter('height')) for row in curs: btn = ToggleButton(text=str(row[0]), size_hint_y=None, height=40) if row[1] == 1: btn.background_color = (0.5, 1, 0.9, 1) layout2.add_widget(btn) btn.bind(on_press=subChar) SMApp.sublist.append(btn) lbl = Label(text=str(row[2]), size_hinty=None, height=40) layout2.add_widget(lbl) root = ScrollView(size_hint=(None, None), size=(400, 400)) root.add_widget(layout2) SMApp.popup2 = Popup(content=root, size=(7, 10), size_hint=(0.55, 0.8), title="list of subs") SMApp.popup2.open()
def build(self): box = BoxLayout(orientation='vertical') # create a default grid layout with custom width/height layout = GridLayout(cols=1, padding=10, spacing=10, size_hint=(None, None), width=500) # when we add children to the grid layout, its size doesn't change at # all. we need to ensure that the height will be the minimum required to # contain all the childs. (otherwise, we'll child outside the bounding # box of the childs) layout.bind(minimum_height=layout.setter('height')) # add button into that grid for i in range(30): btn = Button(text=str(i), size=(480, 40), size_hint=(None, None)) layout.add_widget(btn) # create a scroll view, with a size < size of the grid root = ScrollView( pos_hint={'top': 1.0, 'left': 1.0}) root.add_widget(layout) b = Button(text='gyumkiu', size=(480, 40), size_hint=(None, None) ) box.add_widget(b) box.add_widget(root) return box
def build(self): # create a default grid layout with custom width/height layout = GridLayout(cols=1, spacing=10, size_hint=(None, None), width=500) # when we add children to the grid layout, its size doesn't change at # all. we need to ensure that the height will be the minimum required to # contain all the childs. (otherwise, we'll child outside the bounding # box of the childs) layout.bind(minimum_height=layout.setter('height')) # add button into that grid for i in range(30): btn = Button(text=str(i), size=(480, 40), size_hint=(None, None)) layout.add_widget(btn) # create a scroll view, with a size < size of the grid root = ScrollView(size_hint=(None, None)) root.size = (480, 320) root.center = Window.center root.add_widget(layout) return root
class StationList(ScrollView): layout = None collection = None def __init__(self, **kwargs): super(StationList, self).__init__(**kwargs) self.layout = GridLayout(cols=1, size_hint=(None, None)) self.layout.bind(minimum_height=self.layout.setter('height')) self.add_widget(self.layout) def update_list(self, collection): if collection == self.collection: return self.collection = collection self.layout.clear_widgets() for station in collection: item = StationListingItem(station, self.layout, self.on_station_select, size=(self.width, 225), text_size=(self.width*.9, 255)) self.layout.add_widget(item) def add_station_selection_listener(self, callback): self.callback = callback def on_station_select(self, station): self.callback(station)
def __init__(self, **kwargs): super(IntroPanelView, self).__init__(**kwargs) self.name='introscreen' # create a default grid layout with custom width/height layout = GridLayout(cols=1, padding=10, spacing=10, size_hint=(None, None),pos_hint={'center_x': .5, 'center_y': .5}, width=500) layout.bind(minimum_height=layout.setter('height')) # create a scroll view, with a size < size of the grid scrl = ScrollView(size_hint=(None, None), size=(500, 320), pos_hint={'center_x': .5, 'center_y': .5}, do_scroll_x=False) label = Label( text=self.introtext, size=(480, 900), text_size=(480,900), size_hint_y=None, markup=True) scrl.add_widget(label) layout.add_widget(scrl) btn = Button(text='Okay', size=(480, 40), size_hint=(None, None), on_press=self.close) layout.add_widget(btn) self.add_widget(layout)
class NotificationDemo(BoxLayout): def __init__(self, **kwargs): super(BoxLayout, self).__init__( **kwargs) self.scroller = self.children[-1] self.grid = GridLayout(cols=1, spacing=1, size_hint_y=None) self.scroller.add_widget(self.grid) self.grid.bind(minimum_height=self.grid.setter('height')) osc.init() oscid = osc.listen(ipAddr='127.0.0.1', port=3002) osc.bind(oscid, self.add_more, '/some_api') Clock.schedule_interval(lambda *x: osc.readQueue(oscid), 0.3) def add_more(self,message,*args): Label = MultiLineLabel(text=message[2]) self.grid.add_widget(Label) def play(self): osc.sendMsg('/some_api', ['Play'], port=3001) def pause(self): osc.sendMsg('/some_api', ['Pause'], port=3001) def quit(self): global service service.stop()
class MessageBox(BoxLayout): def __init__(self, userid, *args, **kwargs): self.userid = userid super(MessageBox, self).__init__(*args, **kwargs) # create a grid for the scroll view to contain things self.layout = GridLayout(cols=1, padding=(10, 15), spacing=8, size_hint=(1, None)) self.layout.bind(minimum_height=self.layout.setter('height')) self.ids.scroller.add_widget(self.layout) self.ids.message_input.bind(on_enter=self.send_message) def send_message(self, instance): text = self.ids.message_input.text.rstrip('\r\n') if text: app = App.get_running_app() app.root_box.chat_client.send_chat(self.userid, text) self.add_message(text) self.ids.message_input.text = '' def add_message(self, text, msg_from=None): if not msg_from: msg_from = 'me' from_color = 'ff0000' else: from_color = '0000ff' text = '[color=%s]%s: [/color]%s' % (from_color, msg_from, text) label = TextBoxLabel(text=text) self.layout.add_widget(label) self.ids.scroller.scroll_y = 0
def build(self): # carousel = Carousel(anim_type='out_expo') gallery = ImageCollector() # for image in gallery.get_images_from_folder(0): # carousel.add_widget(PhotoFrame(image_path=image)) img = gallery.get_random_img() l = Scatter(do_rotation=False) l.add_widget(FramedImage(source=img)) ############### layout = GridLayout(orientation='horizontal', rows=1, size_hint_x=None) # Make sure the height is such that there is something to scroll. layout.bind(minimum_width=layout.setter('width')) for i in gallery.get_images_from_folder(0): im = CustomImage(source=i, size_hint_x=None) layout.add_widget(im) root = ScrollView() root.add_widget(layout) box = BoxLayout() box.add_widget(root) ################ return box
def ShowList(self): ''' Shows the discover results ''' # create the popup oContent = GridLayout(cols=1, spacing='5dp') oScrollview = ScrollView( do_scroll_x=False) self.oScrollContent = StackLayout(size_hint=(None, None)) self.oPopup = oPopup = Popup(content=oContent, title=ReplaceVars('$lvar(5028)'), size_hint=(0.9, 0.9), auto_dismiss=False) #we need to open the popup first to get the metrics oPopup.open() #Add some space on top oContent.add_widget(Widget(size_hint_y=None, height=dp(2))) aDiscoverScripts=oORCA.oScripts.GetScriptListForScriptType("DEVICE_DISCOVER") aScrollContent=[] for uDiscoverScriptName in aDiscoverScripts: oScrollContentSingle = GridLayout(size_hint=(None, None)) aScrollContent.append(oScrollContentSingle) oScrollContentSingle.bind(minimum_height=oScrollContentSingle.setter('height')) oORCA.oScripts.RunScript(uDiscoverScriptName,{'createlist':1,'oGrid':oScrollContentSingle}) self.oScrollContent.add_widget(cLabel(text=oORCA.oScripts.aScripts[uDiscoverScriptName].uSubType, background_color=[0.2, 0.2, 0.2, 1.0], color=[0.9, 0.9, 0.9, 1.0], size=(oPopup.width, dp(30)),size_hint=(None, None), halign='center')) self.oScrollContent.add_widget(oScrollContentSingle) self.oScrollContent.add_widget(SettingSpacer()) # finally, add a cancel button to return on the previous panel oScrollview.add_widget(self.oScrollContent) oContent.add_widget(oScrollview) oContent.add_widget(SettingSpacer()) oBtn = Button(text=ReplaceVars('$lvar(5000)'), size=(oPopup.width, dp(50)),size_hint=(1, None)) oBtn.bind(on_release=self.On_Cancel) oContent.add_widget(oBtn) #resize the Scrollcontent to fit to all Childs. Needs to be done, after the popup has been shown Clock.schedule_once(self.SetScrollSize, 0)
def start_brew(self, unfilled_profile, profile_name): self.unfilled_profile = unfilled_profile self.profile_name = profile_name self.profile = self.fill_profile(unfilled_profile) print self.profile self.paused = False self.start_time = datetime.datetime.now() self.brew_df = pd.DataFrame(columns=['time', 'temperature 1', 'temperature 2', 'state', 'target temperature']) monitor_gridlayout = GridLayout(id='monitor_gridlayout', cols=1, spacing=1, size_hint_y=None) monitor_gridlayout.bind(minimum_height=monitor_gridlayout.setter('height')) monitor_gridlayout.add_widget(Label(text='Temp 1: ', size_hint_y=None, height=30, id='temp_1_label')) monitor_gridlayout.add_widget(Label(text='Temp 2: ', size_hint_y=None, height=30, id='temp_2_label')) monitor_gridlayout.add_widget(Label(text='Target temp: ', size_hint_y=None, height=30, id='target_temp_label')) monitor_gridlayout.add_widget(Label(text='Arduino State: ', size_hint_y=None, height=30, id='arduino_state')) box = BoxLayout(id='box', size_hint_y=None, height=300) monitor_graph = Graph(xlabel='Time (days)', ylabel='Temperature', x_ticks_minor=1, x_ticks_major=7, y_ticks_major=10, y_grid_label=True, x_grid_label=True, padding=5, x_grid=True, y_grid=True, xmin=0, xmax=int(unfilled_profile.iloc[-1]['time']+1), ymin=0, ymax=30, id='monitor_graph', _with_stencilbuffer=False) box.add_widget(monitor_graph) monitor_gridlayout.add_widget(box) pause_button = Button(text='pause', size_hint_y=None, height=30, id='pause_button') pause_button.bind(on_release=self.pause) monitor_gridlayout.add_widget(Button(text='Pause', size_hint_y=None, height=30)) monitor_scrollview = ScrollView(size_hint=(1, None), size=(Window.width, Window.height), id='monitor_scrollview') monitor_scrollview.add_widget(monitor_gridlayout) self.add_widget(monitor_scrollview) Clock.schedule_interval(self.update_brew, self.update_interval)
def getPropertyEditors(self, skin): """ get all the controls for editing the extra properties of this control. The list of controls that is returned, our bound to this object (changes will be stored in the skin object) :param skin: json object :return: a list of kivy controls that can be used for editing the properties for the skin. """ items = [] grd = GridLayout(cols=2) grd.bind(minimum_height = grd.setter('height')) grd.size_hint = (1, None) chk = CheckBox(active=sm.getVar(skin, self.asset, "show_label", False), height='28dp', size_hint=(1, None)) chk.bind(active=self.on_show_labelChanged) lbl = Label(text='show label', height='28dp', size_hint=(1, None), halign='right') lbl.bind(size = lbl.setter('text_size')) grd.add_widget(lbl) grd.add_widget(chk) chk = CheckBox(active=sm.getVar(skin, self.asset, "show_marker", False), height='28dp', size_hint=(1, None)) chk.bind(active=self.on_show_markerChanged) lbl = Label(text='show marker', height='28dp', size_hint=(1, None), halign='right') lbl.bind(size = lbl.setter('text_size')) grd.add_widget(lbl) grd.add_widget(chk) chk = CheckBox(active=sm.getVar(skin, self.asset, "send_on_release", False), height='28dp', size_hint=(1, None)) chk.bind(active=self.on_send_on_release_Changed) lbl = Label(text='send on release', height='28dp', size_hint=(1, None), halign='right') lbl.bind(size = lbl.setter('text_size')) grd.add_widget(lbl) grd.add_widget(chk) items.append(grd) return items
def buildAboutUs(self, dismiss): box = BoxLayout(orientation="vertical") scrollViewLayout = ScrollView(do_scroll_x=False, scroll_y=1) childLayout = GridLayout(cols=1, size_hint_x=1, size_hint_y=None) childLayout.bind(minimum_height=childLayout.setter('height')) def longTextLabel(): _long_text = """\n\n[b]Programmers[/b]\nCarmen Bruni ([email protected]), Jia Gou ([email protected]), Christina Koch ([email protected]), Bernhard Konrad ([email protected]) and Jerome Lefebvre ([email protected])\n [b]Art[/b]\nIsabell Graf ([email protected]) \n [b]Music[/b]\nCarmen Bruni\n [b]Contact & Feedback[/b]\[email protected]""" reallyLongText = _long_text myLabel = Label(text=reallyLongText, text_size=(700,None), line_height=1.5, markup=True) myLabel.size_hint_y = None myLabel.height = 650 return myLabel childLayout.add_widget(longTextLabel()) scrollViewLayout.add_widget(childLayout) box.add_widget(scrollViewLayout) close_button = Button(text="Close", size_hint_y=0.1, on_press=dismiss) box.add_widget(close_button) return box
def Start(self,uTitle,aOptions,fktCallBack): ''' starts selection ''' self.fktCallBack=fktCallBack # create the popup content = GridLayout(cols=1, spacing='5dp') scrollview = ScrollView( do_scroll_x=False, bar_width='10dp',scroll_type=['bars'] ) scrollcontent = GridLayout(cols=1, spacing='5dp', size_hint=(None, None)) scrollcontent.bind(minimum_height=scrollcontent.setter('height')) self.oPopup = popup = Popup(content=content, title=ReplaceVars(uTitle), size_hint=(0.5, 0.9), auto_dismiss=False) #we need to open the popup first to get the metrics popup.open() #Add some space on top content.add_widget(Widget(size_hint_y=None, height=dp(2))) # add all the options for option in aOptions: if hasattr(option,"Name"): name=option.Name else: name=option.Type btn = Button(text=name, size=(popup.width, dp(30)), size_hint=(None, None)) btn.bind(on_release=self.On_Value) btn.oDBRef=option scrollcontent.add_widget(btn) # finally, add a cancel button scrollview.add_widget(scrollcontent) content.add_widget(scrollview) content.add_widget(SettingSpacer()) btn = Button(text=ReplaceVars('$lvar(5009)'), size=(popup.width, dp(50)),size_hint=(0.9, None)) btn.bind(on_release=popup.dismiss) content.add_widget(btn)
def build(self): layout1 = GridLayout(cols=4, spacing=10, size_hint=(None, None)) layout1.bind(minimum_height=layout1.setter('height'), minimum_width=layout1.setter('width')) for i in range(40): btn = Button(text=str(i), size_hint=(None, None), size=(200, 100)) layout1.add_widget(btn) scrollview1 = ScrollView(bar_width='2dp') scrollview1.add_widget(layout1) layout2 = GridLayout(cols=4, spacing=10, size_hint=(None, None)) layout2.bind(minimum_height=layout2.setter('height'), minimum_width=layout2.setter('width')) for i in range(40): btn = Button(text=str(i), size_hint=(None, None), size=(200, 100)) layout2.add_widget(btn) scrollview2 = ScrollView(scroll_type=['bars'], bar_width='9dp', scroll_wheel_distance=100) scrollview2.add_widget(layout2) root = GridLayout(cols=2) root.add_widget(scrollview1) root.add_widget(scrollview2) return root
def device_select(self): Box = BoxLayout(orientation="vertical", spacing=10) msg = GridLayout(cols=2, padding=15, spacing=10, size_hint_y=None) btn_layout = GridLayout(cols=1) done = Button(text="Cancel") btn_layout.add_widget(done) msg.bind(minimum_height=msg.setter('height')) popup = Popup(background='atlas://images/eds/pop', title='Device Select',content=Box, auto_dismiss=True, size_hint=(None, None), size=(700, 500)) try: for name in devices: if name in devices: btnname = (CustomButton(text='%s' % name, font_size=10, size_hint_y=None, height=40)) msg.add_widget(btnname) btnname.bind(on_release=set_device) btnname.bind(on_release=popup.dismiss) root = ScrollView(size_hint=(None, None), size=(675, 390), do_scroll_x=False) root.add_widget(msg) Box.add_widget(root) Box.add_widget(btn_layout) done.bind(on_release=popup.dismiss) popup.open() except: EdsNotify().run("'system/app Directory Not Found", 'Cant Find:\n' + SystemApp)
def library(self,instance): print "Show library" k = instance.parent.parent.parent.children[0] k.clear_widgets() s = GridLayout(cols = 1, spacing = 3, size_hint_y = None) s.bind(minimum_height = s.setter('height')) os.chdir(self.music_path) for i in os.listdir(u'.'): if '.mp3' in i: i = i.encode('utf-8') print type(i), i s.add_widget(Button( text = i[:-4], color = (1,1,1,1), size_hint_y = None, height = 70, on_press = self.playSong, background_color = self.song_color, background_normal = '' )) g = ScrollView(size_hint = (1,0.5), pos_hint = {'x': 0, 'y': 0}) g.add_widget(s) d = StackLayout(size_hint = (1,0.3),pos_hint = {'center_x': 0.5, 'y': 0.5}, orientation = 'lr-tb') d.add_widget(Button(text = self.current_song,color = (0,0,0,1),size_hint = (1,0.5),pos_hint = {'x': 0,'y':0.5}, background_normal = '', background_color = (1,1,1,1))) d.add_widget(Button(text = "STOP",size_hint = (0.5,0.5), on_press = self.playSong, background_normal = '', background_color = (0.9,0.1,0.1,1))) d.add_widget(Button(text = "PAUSE",size_hint = (0.5,0.5), on_press = self.playSong, background_normal = '', background_color = (0.9,0.7,0.1,1))) k.add_widget(g) k.add_widget(d)
class AppList(StackLayout): def __init__(self, app): super(AppList, self).__init__(spacing=2, size_hint=(None, None)) self.app = app self.title = Label(text="No title yet", height=30) self.add_widget(self.title) self.add_buttons() scroll = ScrollView(size_hint_y=None, height=600 - self.height) self.add_widget(scroll) self.layout = GridLayout(cols=1, size_hint_y=None) self.layout.bind(minimum_height=self.layout.setter('height')) scroll.add_widget(self.layout) def add_buttons(self): pass def clear_list(self): self.layout.clear_widgets() def add_item(self, item): item.size_hint_y = None item.height = 40 self.layout.add_widget(item) return item
def _create_subpopup(self, instance): ''' shows the sub popup ''' # create the popup content = GridLayout(cols=1, spacing='5dp') scrollview = ScrollView( do_scroll_x=False) scrollcontent = GridLayout(cols=1, spacing='5dp', size_hint=(None, None)) scrollcontent.bind(minimum_height=scrollcontent.setter('height')) self.subpopup = popup = Popup(content=content, title=self.uOption, size_hint=(0.5, 0.9), auto_dismiss=False) #we need to open the popup first to get the metrics popup.open() #Add some space on top content.add_widget(Widget(size_hint_y=None, height=dp(2))) # add all the options uid = str(self.uid) for option in self.aSubOption: state = 'down' if option == self.value else 'normal' oTbtn = ToggleButton(text=option, state=state, group=uid, size=(popup.width, dp(55)), size_hint=(None, None)) oTbtn.bind(on_release=self._set_suboption) scrollcontent.add_widget(oTbtn) # finally, add a cancel button to return on the previous panel scrollview.add_widget(scrollcontent) content.add_widget(scrollview) content.add_widget(SettingSpacer()) oMbtn = cMultiLineButton(text=ReplaceVars('$lvar(5009)'), size=(popup.width, dp(50)),size_hint=(0.9, None), halign='center', valign='middle') oMbtn.bind(on_release=popup.dismiss) content.add_widget(oMbtn)
def show_view_list_path(self, *args, **kwargs): self.clear_widgets() color = ColorLayout() boxl = BoxLayout(orientation= 'vertical',anchor_y= "top") grid = GridLayout(cols=1, size_hint_y=None) grid.bind(minimum_height=grid.setter('height')) scroll = ScrollView(size_hint=(None, None)) scroll.size = (Window.width, Window.height) scroll.center = Window.center #2 Space added but button go back ocuppies space and first value hidden. l_space = MultiLineLabel(text='',font_size="16dp", background_color=(255,255,255,255), markup=True) grid.add_widget(l_space) l_space = MultiLineLabel(text='',font_size="16dp", background_color=(255,255,255,255), markup=True) grid.add_widget(l_space) for i in args[0]: text = '[color=333333]'+' '+i['text'] + '[/color]'+' ' #~ l = MultiLineLabel(text=text,font_size="16dp",markup=True) l = MultiLineLabel(text=text,font_size="16dp", background_color=(255,255,255,255), markup=True) i['stations'] and l.bind(on_press = partial(self.show_list_stations, i['stations'],args[0])) grid.add_widget(l) button_back = Button(text="Go Back", auto_dismiss=False, size_hint=(None, None), pos_hint= {'center_x':.5, 'center_y':.7}) button_back.height="50dp" button_back.width="100dp" button_back.bind(on_press = lambda widget: self.show_option_view()) scroll.add_widget(grid) boxl.add_widget(scroll) boxl.add_widget(button_back) color.add_widget(boxl) self.add_widget(color)
class MyScroll(ScrollView): def __init__(self, **kwargs): super(MyScroll, self).__init__(**kwargs) self.grid1 = GridLayout(cols=10) self.add_widget(self.grid1) self.grid1.size_hint = None, None self.grid1.bind(minimum_height=self.grid1.setter("height")) self.grid1.bind(minimum_width=self.grid1.setter("width")) for i in range(20): for j in range(10): ti = TextInput(size_hint=(None, None)) ti.width = metrics.sp(160) ti.height = metrics.sp(40) if i > 2: ti.row = i ti.col = j self.grid1.add_widget(ti) ti.bind(text=self.textChanged) return def textChanged(self, instance, val): if getattr(instance, "row", None): print instance.row, instance.col, val else: print "Variable row is not implimented"
def kernel_mods(self): Box = BoxLayout(orientation="vertical", spacing=10) msg = GridLayout(cols=1, padding=15, spacing=10, size_hint_y=None) btn_layout = GridLayout(cols=1) done = Button(text="Done") btn_layout.add_widget(done) msg.bind(minimum_height=msg.setter('height')) over = CustomButton(text='OverClocking', size=(475, 40), size_hint=(None, None)) over.bind(on_release=overclock) gpu = CustomButton(text='Gpu Overclock', size=(475, 40), size_hint=(None, None)) gpu.bind(on_release=gpu_overclock) gov = CustomButton(text='Governors', size=(475, 40), size_hint=(None, None)) gov.bind(on_release=gov_select) mhl = CustomButton(text='MHL Refresh Hack', size=(475, 40), size_hint=(None, None)) mhl.bind(on_release=msl_options) msg.add_widget(over) msg.add_widget(gpu) msg.add_widget(gov) msg.add_widget(mhl) root = ScrollView(size_hint=(None, None),bar_margin=-22, size=(475, 390), do_scroll_x=False) root.add_widget(msg) Box.add_widget(root) Box.add_widget(btn_layout) popup = Popup(background='atlas://images/eds/pop', title='Kernel Mods',content=Box, auto_dismiss=True, size_hint=(None, None), size=(520, 500)) done.bind(on_release=popup.dismiss) popup.open()
class CaterpillarList(ScrollView): def __init__(self,**kwargs): super(CaterpillarList, self).__init__(**kwargs) self.caterpillars=[] self.bind(size=self.draw) self.box=GridLayout(orientation="vertical",cols=2,size_hint_y=None,spacing=10) self.box.bind(minimum_height=self.box.setter('height')) self.add_widget(self.box) def reset(self): self.caterpillars=[] self.draw() def add(self,caterpillar): if caterpillar in self.caterpillars: self.caterpillars.remove(caterpillar) self.caterpillars=[caterpillar]+self.caterpillars self.draw() def draw(self,*args): self.box.clear_widgets() x,y=self.size if x>y: cols = 2 else: cols =1 self.box.cols=cols for guess in self.caterpillars: self.box.add_widget(Caterpillar(chain=guess,size_hint_y=None,size=(x,x/7/cols))) self.scroll_y=1
def update_file_layout(self): auth_token='S2_xUq0_iNAAAAAAAAAACYNG1zf1GAzKpVWVfmLcZLA-FIiSlGxMvmxBkAtspuWQ' client = dropbox.client.DropboxClient(auth_token) self.clear_widgets() b=BoxLayout(orientation='vertical') file_system = FileSystemLocal() root_dir= App.get_running_app().user_data_dir+'/';result_dir=root_dir+'results' file_list=file_system.listdir(root_dir) # this returns a list of files in dir if os.path.exists(result_dir):file_list.extend(file_system.listdir(App.get_running_app().user_data_dir+'/'+'results'+'/')) file_list=[x for x in file_list if x[-4:]=='.csv'] b.add_widget(Label(text='Select Files to Upload',bold=True,font_size=sp(25),size_hint_y= 0.1)) file_system = FileSystemLocal() file_list=file_system.listdir(App.get_running_app().user_data_dir+'/') # this returns a list of files in dir file_list=[x for x in file_list if x[-4:]=='.csv'] s=ScrollView(size_hint_y=0.75) g=GridLayout(cols=2,size_hint_y=None) for file_1 in file_list: c=CheckBox(active=False) l=Label(bold= True,font_size=sp(20),text=file_1,size_hint_y= None,height=70) self.check_boxes[c]=file_1 g.add_widget(l);g.add_widget(c) g.bind(minimum_height=g.setter('height')) s.add_widget(g) b.add_widget(s) g_options=GridLayout(cols=2,size_hint_y= 0.1,orientation='horizontal') g_options.add_widget(Button(text="Send",on_press=self.upload,font_size=sp(25))) g_options.add_widget(Button(text="Back",on_press=self.return_back,font_size=sp(25))) b.add_widget(g_options) self.add_widget(b)
def viewGames(self): sview = ScrollView(size_hint=(.9, .8), pos_hint={'center_x':.5, 'center_y':.5}) layout = GridLayout(cols=1, spacing=10, size_hint_y=None) # Make sure the height is such that there is something to scroll. layout.bind(minimum_height=layout.setter('height')) # Run sql query to get all available games availableGames = retrieve("SELECT * FROM Games") if availableGames == "": popup = Popup(title='No Games', content=Label(text='There are currently no available games'), size_hint=(None, None), size=(400, 100)) popup.open() elif availableGames == 0: popup = Popup(title='Connection', content=Label(text='Could not connect to the database'), size_hint=(None, None), size=(400, 100)) popup.open() else: for tpl in availableGames: uid, name, location, creator, status = tpl print "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n\n" print name print "\n\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n\n" btn = Button(id=name, text=name, size_hint_y=None, height=200) btn.bind(on_press=self.seeInfo) layout.add_widget(btn) sview.add_widget(layout) self.add_widget(sview)
def load_custom_ker(self): Box = BoxLayout(orientation="vertical", spacing=10) panel = SettingsPanel(title="Custom HTC Kernels", settings=self) msg = GridLayout(cols=1, size_hint=(None, 0.8), width=700) btn_layout = GridLayout(cols=1) done = Button(text="Done") easy = Button(text='Show Stock Kernels',size_hint_y=(None), height=25) btn_layout.add_widget(done) msg.bind(minimum_height=msg.setter('height')) try: for name in kernels: item = SettingItem(panel = panel, title = "%s" % name, disabled=False, desc = "https://github.com/wes342/%s" % name) item_btn = CustomButton(text="Clone: %s" % name ,size_hint=(None, None),width=250, height=40) item.add_widget(item_btn) msg.add_widget(item) item_btn.bind(on_release=get_kernel) root = ScrollView(size_hint=(None, None), size=(675, 350), do_scroll_x=False) root.add_widget(msg) Box.add_widget(easy) Box.add_widget(root) Box.add_widget(btn_layout) easy.bind(on_release=load_ker) popup = Popup(background='atlas://images/eds/pop', title='Custom HTC Kernels',content=Box, auto_dismiss=True, size_hint=(None, None), size=(700, 500)) done.bind(on_release=popup.dismiss) easy.bind(on_release=popup.dismiss) popup.open() except: EdsNotify().run("'system/app Directory Not Found", 'Cant Find:\n' + SystemApp)
def update_screen(self, *args, **kwargs): self.ids["player_list"].clear_widgets() txt = TURN.team.txt(LANG) for key, value in txt.iteritems(): try: self.ids[key].text = value except: pass layout = GridLayout(cols=1, size_hint_y=None) layout.bind(minimum_height=layout.setter('height')) sorted_players = TURN.sort_players("Pos + Skill") for player in sorted_players: txt = player.txt(LANG) btn = PlayerBtn(size_hint_y=None, height=45) for key, value in txt.iteritems(): try: btn.ids[key].text = value except: pass btn.player_idx = player.idx layout.add_widget(btn) self.ids["player_list"].add_widget(layout) possible_tactics = [] for tactic in TURN.possible_tactics(): possible_tactics.append(tactic2txt(tactic)) possible_tactics.append("Best 11") possible_tactics.append("Clear") self.ids["assman_team"].values = possible_tactics labels = [self.ids["player_list_label"]] for x in labels: for i in x.ids: x.ids[i].text = LANG[i]
def OnIceFenwickStats(obj): # Clear widgets in order to hide previous table if user searched for other play stat categories first Layout.clear_widgets() Layout.add_widget(BackToPlayerSearch) Layout.add_widget(PlayerSearchLabel) Layout.add_widget(IndividualButton) Layout.add_widget(On_Ice_Goals_Button) Layout.add_widget(On_Ice_Fenwick_Button) Grid = GridLayout(rows = len(On_ice_Fenwick_stats) + 1, cols = len(On_ice_Fenwick_categories), size_hint = (None, None)) Grid.bind(minimum_height=Grid.setter('height'), minimum_width = Grid.setter('width')) for stat_category in On_ice_Fenwick_categories: Grid.add_widget(TextInput(text = str(stat_category), size_hint = (None, None), font_size = 18, readonly = True)) for i in range(len(On_ice_Fenwick_stats)): if i % 2 == 0: ColorBackGround = [200./255, 204./255, 255./255, 1] else: ColorBackGround = [1,1,1,1] season = On_ice_Fenwick_stats[i] for stat in season: Grid.add_widget(TextInput(text = str(stat), size_hint = (None, None), font_size = 18, background_color = ColorBackGround, readonly = True)) Scroll = ScrollView(size_hint = (1, .65)) Scroll.add_widget(Grid) Layout.add_widget(Scroll)
from kivy.uix.gridlayout import GridLayout from kivy.uix.button import Button from kivy.uix.scrollview import ScrollView from kivy.core.window import Window from kivy.app import runTouchApp layout = GridLayout(cols=1, spacing=10, size_hint_y=None) # Make sure the height is such that there is something to scroll. layout.bind(minimum_height=layout.setter('height')) for i in range(10): btn = Button(text=str(i), size_hint_y=None, height=40) layout.add_widget(btn) boxlayout = root = ScrollView(size_hint=(1, None), size=(Window.width, Window.height)) root.add_widget(layout) runTouchApp(root)
def getcheckboxes_active(self, *arg): username = "******" password = "******" # Here enter your API password authServiceUrl = "https://sandbox-authservice.priaid.ch" # Be aware that sandbox link is for testing pourpose (not real data) once you get live access you shold use https://authservice.priaid.ch/login healthServiceUrl = "https://sandbox-healthservice.priaid.ch" # Be aware that sandbox link is for testing pourpose (not real data) once you get live access you shold use https://healthservice.priaid.ch language = "en-gb" gender = "male" yearOfBirth = "1996" '''how to get the active state of all checkboxed created in def show''' # Iterate over the dictionary storing the CheckBox widgets selected_symptoms = [] for idx, wgt in self.check_ref.items(): #print(wgt.active) if wgt.active == True: #print(idx) selected_symptoms.append(idx) #print(selected_symptoms) selectedSymptoms = [] if self.connection_check(): for person in self.loadsymptoms: #print(person) for k, v in person.items(): #print('{}: {}'.format(k, v)) #print(v) if v in selected_symptoms: selectedSymptoms.append(person['ID']) else: return self.connection_popup() #print(selectedSymptoms) load = DiagnosisClient(username, password, authServiceUrl, healthServiceUrl, language) self.diagnose = load.loadDiagnosis(selectedSymptoms, Gender.Male, 1996) #print(self.diagnose) self.diagnose_list = [] for person in self.diagnose: #print(person) for k, v in person.items(): #print(person['Issue']['Name']) self.diagnose_list.append(person['Issue']['Name']) #print(diagnose_list) layout = GridLayout(cols=1, padding=10, size_hint_y=None, row_force_default=True, row_default_height='30dp') layout.bind(minimum_height=layout.setter("height")) for each in range(len(self.diagnose_list)): layout3 = BoxLayout(padding=[0, 0, 30, 0], orientation="horizontal") label1 = Button(color=(0, 0, 0, 1), font_size=15, background_normal="", background_color=(1, 1, 1, 1), text=self.diagnose_list[each], halign='left', markup=True) chckbox = CheckBox(color=(0, 0, 0, 1)) #chckbox.bind(active=self.getcheckboxes_active) # Stores a reference to the CheckBox instance #self.check_ref[chckbox] = prods[each] self.check_ref[str(self.diagnose_list[each])] = chckbox layout3.add_widget(chckbox) layout3.add_widget(label1) layout.add_widget(layout3) if len(self.diagnose_list) > 0: self.diagnosis_box.clear_widgets() self.diagnosis_box.add_widget(layout) else: #print('empty') self.diagnosis_box.clear_widgets() self.diagnosis_box.add_widget( Label( text='No diagnosis found!', color=(0, 0, 0, 1), ))
def filesync(self): """Callback when the user presses the Sync button. This relies on keyless ssh working, and does most of the work in shell scripts.""" Logger.info('Config: filesync') # set up a popup containing a scrollview to contain stdout output layout = GridLayout(cols=1, spacing=1, padding=1, size_hint_y=None) layout.bind(minimum_height=layout.setter('height')) popup = Popup(title='Sync', size_hint=(0.8, 1)) sv = ScrollView(size_hint=(1, 1)) sv.add_widget(layout) popup = Popup(title='Sync', content=sv, size_hint=(0.8, 1)) popup.open() # temp file for the rsync, probably a better way to do this # this file describes exactly what songs should exist on the host, no more, no less tpath = os.path.join(self.config.get('paths', 'tmppath'), "rsync.inc") # look in the ini file for all the relevant paths synchost = self.config.get('sync', 'synchost') syncbasepath = self.config.get('sync', 'syncmusicpath') syncfanartpath = self.config.get('sync', 'syncfanartpath') basepath = self.config.get('paths', 'musicpath') fanartpath = self.config.get('paths', 'fanartpath') Logger.info('Filesync: Copying rsync file to carpi') # TODO: figure out why this doesn't show up on the screen until after the os.walk has completed l = OutlineLabel(text='Copying rsync file to carpi', size_hint=(None, None), font_size='12sp', halign='left') l.bind(texture_size=l.setter('size')) layout.add_widget(l) sv.scroll_to(l) # copy the rsync file from the synchost # TODO: implement this using python instead of call call(["scp", synchost + ":rsync.inc", tpath]) filelist = {} # use codecs.open to ensure the file is read as utf8, otherwise special chars can be mangled with codecs.open(tpath, 'r', 'utf-8') as f: for line in f: # add each filename to a dict for easy searching later filelist[Helpers.decodeFileName(line.rstrip())] = True Logger.info('Filesync: Removing old files from carpi') # TODO: figure out why this doesn't show up on the screen until after the os.walk has completed l = OutlineLabel(text='Removing old files from carpi', size_hint=(None, None), font_size='12sp', halign='left') l.bind(texture_size=l.setter('size')) layout.add_widget(l) sv.scroll_to(l) # this whole block walks the filesystem and deletes any file that is not in the rsync file # the sync operation is split up into a delete and a copy because that was the only way I could get # rsync to work correctly, it was always copying/deleting the wrong things otherwise for dirpath, dirnames, filenames in os.walk( Helpers.decodeFileName(basepath)): if len(filenames) > 0: rpath = dirpath[len(basepath + os.sep):] for filename in filenames: fpath = os.path.join(Helpers.decodeFileName(rpath), Helpers.decodeFileName(filename)) apath = os.path.join(Helpers.decodeFileName(dirpath), Helpers.decodeFileName(filename)) if fpath not in filelist: Logger.debug("Filesync: Deleting " + apath) os.remove(Helpers.decodeFileName(apath)) # TODO: somehow do this all in python instead of shell script, it's ugly # also, if the host somehow has tmppath mounted with the no-execute bit set, this will fail with open(os.path.join(self.config.get('paths', 'tmppath'), 'sync.sh'), 'w') as sfile: sfile.write("#!/bin/bash\n") # delete all empty directories sfile.write('find "' + basepath + '" -type d -empty -delete 2>/dev/null\n') # copy/update only the files that exist in the rsync file sfile.write('rsync -vruxhm --files-from="' + tpath + '" ' + synchost + ':"' + syncbasepath + '"/ "' + basepath + '"\n') # copy the car sticker database to the synchost sfile.write('scp /var/lib/mpd/sticker.sql ' + synchost + ':' + self.config.get('sync', 'synctmppath') + '\n') # build a secondary shell script to perform the sticker update on the synchost with open( os.path.join(self.config.get('paths', 'tmppath'), 'scmd'), 'w') as f: # attach the copied database and merge sticker data from it to update ratings user has added in the car # not using os.path.join here since who knows what os the synchost uses...use linux f.write("attach database \"" + self.config.get('sync', 'synctmppath') + "/sticker.sql\" as carpi;\n") f.write("replace into sticker select * from carpi.sticker;\n") f.write( "replace into carpi.sticker select * from sticker where name='rating';\n" ) f.write(".quit\n") # copy secondary script to synchost and run it sfile.write( 'scp ' + os.path.join(self.config.get('paths', 'tmppath'), 'scmd') + ' ' + synchost + ':' + self.config.get('sync', 'synctmppath') + '\n') # not using os.path.join here since who knows what os the synchost uses...use linux sfile.write('ssh -t ' + synchost + ' sudo sqlite3 /var/lib/mpd/sticker.sql < ' + self.config.get('sync', 'synctmppath') + '/scmd\n') # copy the now updated sticker database back from the synchost # not using os.path.join here since who knows what os the synchost uses...use linux sfile.write('scp ' + synchost + ':' + self.config.get('sync', 'synctmppath') + '/sticker.sql ' + self.config.get('paths', 'tmppath') + '\n') # build a secondary shell script to perform the sticker update on the host with open( os.path.join(self.config.get('paths', 'tmppath'), 'scmd'), 'w') as f: # attach the copied database and merge sticker data from it to update ratings user has added at home f.write("attach database \"" + os.path.join( self.config.get('paths', 'tmppath'), "sticker.sql") + "\" as carpi;\n") f.write("replace into sticker select * from carpi.sticker;\n") f.write(".quit\n") # run the secondary script sfile.write( 'cat ' + os.path.join(self.config.get('paths', 'tmppath'), 'scmd') + ' | sudo sqlite3 /var/lib/mpd/sticker.sql\n') # rsync over all the fanart sfile.write('rsync -vruxhm ' + synchost + ':"' + syncfanartpath + '"/ "' + fanartpath + '"\n') # tell mpd about any changes sfile.write("mpc update\n") # make the shell script executable os.chmod( os.path.join(self.config.get('paths', 'tmppath'), 'sync.sh'), os.stat( os.path.join(self.config.get('paths', 'tmppath'), 'sync.sh')).st_mode | 0111) # queue for holding stdout q = Queue() # create a subprocess for the shell script and capture stdout p = Popen( [os.path.join(self.config.get('paths', 'tmppath'), 'sync.sh')], stdout=PIPE, bufsize=1, close_fds=True) # check the stdout queue every .1 seconds and write lines to the scrollview if there is output event = Clock.schedule_interval( partial(self.write_queue_line, q, layout, sv), 0.1) # run all this crap in a separate thread to be non-blocking t = Thread(target=self.enqueue_output, args=(p.stdout, q, event, popup, tpath, synchost, layout, sv)) t.daemon = True t.start()
class Contacti(App): def build(self): self.anx = AnchorLayout() self.osn = Image(source='Fonn.jpg') self.anx.add_widget(self.osn) self.bl = BoxLayout(orientation='vertical', padding=[15, 10], spacing=5) self.gll = GridLayout(minimum_height=20, cols=1, size_hint=(1, None), height=100) self.gll.bind(minimum_height=self.gll.setter('height')) self.scrol = ScrollView( bar_width=10, bar_color=[1, 0, 0, 1], effect_cls="ScrollEffect", scroll_type=['bars'], size_hint=(1, None), do_scroll_y=True, ) self.pcontactim = contactim() self.pcontactem = contactem() for x in range(0, len(self.pcontactim)): self.gll.add_widget( Label(text=self.pcontactim[x] + ": " + self.pcontactem[x], height=40, halign="right", size_hint=(1, None), font_size=20)) self.scrol.add_widget(self.gll) self.gl = GridLayout(rows=2, spacing=3, size_hint=(1, None), width=0, row_default_height=10) self.bl.add_widget( Label(text="Список контактов", font_size='50sp', size_hint=(1, .5))) # назв self.bl.add_widget(self.scrol) # списки self.bl.add_widget( Label(text="Добавить контакт", font_size='40sp', size_hint=(1, .5))) self.txima = TextInput(hint_text="имя", height=60) self.txema = TextInput(hint_text="@email", height=60) self.btn = Button(text="Сохранить", on_press=self.soxrcont, background_color=[0.2, .8, 0.3, 1], background_normal='') self.gl.add_widget(self.txima) self.gl.add_widget(self.txema) self.gl.add_widget(Label(text=" ")) self.gl.add_widget(self.btn) self.bl.add_widget(self.gl) self.bl.add_widget(BoxLayout()) self.anx.add_widget(self.bl) return self.anx def soxrcont(self, instance): f = open('contact.txt', 'a') if self.txima.text != "" and self.txema.text != "" and "@" in self.txema.text and "." in self.txema.text: f.write(self.txima.text + "\n") f.write(self.txema.text + "\n") self.txima.text = "" self.txema.text = "" self.btn.text = "Сохранено" f.close()
class KivyMP3(GridLayout): def MyID3(self, fileLoc): # Create a scrollable container self.scroll = ScrollView(do_scroll_x=(False)) # Asign the directory to a variable self.musicDirectory = fileLoc # Create a grid background to allign the buttons self.gridLayer = GridLayout(cols=1, size_hint=(1, None)) # Size fix for grid self.gridLayer.bind(minimum_height=self.gridLayer.setter('height'), minimum_width=self.gridLayer.setter('width')) # Add the grid widget to the scroller self.scroll.add_widget(self.gridLayer) # Artist label self.artist = Label() # Song label self.song = Label() # Album label self.album = Label() # Begin the alternating count to alternate the background images (see bellow) self.alternate = 1 # Process each file in the targeted directory for file in os.listdir(self.musicDirectory): # Check if the file is an MP3 if file.endswith(".mp3"): # Run ID3 Reader to gather the ID3 data id3r = id3reader.Reader(self.musicDirectory + file) # Try to gather the artist ID3 data try: self.artist.text = self.stripSquare( id3r.getValue('performer')) except: self.artist.text = "Not Found" # Try to gather the song title ID3 data try: self.song.text = self.stripSquare(id3r.getValue('title')) except: self.song.text = "Not Found" # Try to gather the album ID3 data try: self.album.text = self.stripSquare(id3r.getValue('album')) except: self.album.text = "Not Found" # Create a spawn of the music button class self.temp = MusicButton(text="testing", halign="center", size_hint=(1, None), height=("80dp"), background_normal='images/listone.png', background_down='images/bk.png', markup=True) # Set the music buttons filename attribute self.temp.musicFileName = file # Alternate the background colours if self.alternate % 2 == 0: self.temp.background_normal = 'images/listtwo.png' self.alternate += 1 # Shorten the Ssong title to prevent overflow. self.song.text = self.song.text[:30] + (self.song.text[30:] and '..') # Format the music button text self.temp.text = "[anchor=title1][size=18sp][color=#4D5158]" + self.song.text + "[/color][/size]\n[color=#AAAAAA]" + self.artist.text + "[/color]" self.gridLayer.add_widget(self.temp) # Link the button press and release to events self.temp.bind(on_press=self.songSelect, on_release=self.songRelease) # Return the newly created window return self.scroll # Button press action def songSelect(self, instance): ''' Button - On Press display a change to acknowledge a registered PRESS - The button is also disabled at this stage to prevent spamming the NukeBox 2000 server ''' # Set the background colour on press instance.background_color = (1, 1, 1, .9) # Disable the button on press - (Prevent spamming the server) instance.disabled = True # Button release event def songRelease(self, instance): ''' This simple chnages the background color of the button to acknowledge a registered RELEASE. ''' # Set the background colour on release instance.background_color = (.9, .8, 1, .8) # Strip square brackets def stripSquare(self, item): ''' Remove square brackets from file names. This prevents them breaking the format sequence. (The strip option didn't work here for some reason, tried multiple combinations of /[ /] [/]] etc.) ''' # Remove left square bracket item = item.replace('[', "") # Remove right square bracket item = item.replace(']', "") # Return the text return item
class ChatScreen(Screen): def __init__(self, screen_manager, **kwargs): super(ChatScreen, self).__init__(**kwargs) self.screen_manager = screen_manager self.database = None self.client_transport = None self.contact = None self.client_login = None self.main_layout = GridLayout(cols=1) self.header_layout = GridLayout(cols=3, size_hint=(1, 0.1)) self.scroll_view = ScrollView(size_hint=(1, 0.8), size=(100, 100), scroll_y=0) self.footer_layout = GridLayout(cols=2, size_hint=(1, 0.1)) self.contact_list_button = Button(text='<=', size_hint=(0.1, 1)) self.contact_list_button.on_press = self.go_to_contact_list self.label = CLabel(text="Chat with bla bla", size_hint=(0.9, 1)) self.contact_menu = DropDown() for name in ['Info', 'Delete']: btn = Button(text=f'{name}', size_hint_y=None, height=30) btn.bind(on_release=lambda btn: self.contact_menu.select(btn.text)) self.contact_menu.add_widget(btn) self.main_button = Button(text=':', size_hint=(.1, .3)) self.main_button.bind(on_release=self.contact_menu.open) self.contact_menu.bind( on_select=lambda instance, x: self.menu_contact(x)) self.messages = [] self.messages_layout = GridLayout(cols=1, padding=(30, 0, 30, 0), size_hint_y=None, row_force_default=True, row_default_height=40) self.messages_layout.bind( minimum_height=self.messages_layout.setter('height')) self.scroll_view.add_widget(self.messages_layout) self.text_input = TextInput(size_hint=(0.9, 1)) self.send_button = Button(text='>>', size_hint=(0.1, 1)) self.send_button.on_press = self.send_message self.header_layout.add_widget(self.contact_list_button) self.header_layout.add_widget(self.label) self.header_layout.add_widget(self.main_button) self.footer_layout.add_widget(self.text_input) self.footer_layout.add_widget(self.send_button) self.main_layout.add_widget(self.header_layout) self.main_layout.add_widget(self.scroll_view) self.main_layout.add_widget(self.footer_layout) self.add_widget(self.main_layout) def send_message(self): message_text = self.text_input.text if message_text: is_success = self.client_transport.send_user_message( self.contact, message_text) self.text_input.text = '' if not is_success: self.show_info_screen('Lost server connection!', 'login') elif is_success is True: self.add_message_history(message_text) else: self.show_info_screen(is_success, 'contacts') def show_info_screen(self, *args): self.screen_manager.current = 'info' self.screen_manager.get_screen('info').set_message(*args) def go_to_contact_list(self): self.screen_manager.current = 'contacts' def load_chat(self, contact_name): self.contact = contact_name if self.client_transport.is_received_pubkey(contact_name): self.show_history() else: self.clear_messages() def set_objects(self, database, client_transport): self.database = database self.client_transport = client_transport self.client_login = self.client_transport.client_login def clear_messages(self): for msg in self.messages: self.messages_layout.remove_widget(msg) self.messages.clear() self.label.text = f'Chat with {self.contact}' def show_history(self): self.clear_messages() list_message = sorted(self.database.get_history(self.contact), key=lambda item: item[3]) # sort by date length = len(list_message) start_index = 0 if length > 20: start_index = length - 20 for i in range(start_index, length): item = list_message[i] message = re.findall(r'>([^<>]+)</p|>([^<>]+)</span', item[2]) if message: message = message[0][0] else: message = item[2] if item[1] == 'in': time = f'{self.contact}' \ f' {item[3].replace(microsecond=0)}:' label = Label(text=f"{time}\n{message}", color=[0.7, 0.3, 1, 0.8], halign='right', valign='middle') label.bind(size=label.setter('text_size')) self.messages.append(label) self.messages_layout.add_widget(self.messages[-1]) elif item[1] == 'out': time = f'{self.client_login}' \ f' {item[3].replace(microsecond=0)}:' label = Label(text=f"{time}\n{message}", color=[0.8, 1, .3, 0.7], halign='left', valign='middle') label.bind(size=label.setter('text_size')) self.messages.append(label) self.messages_layout.add_widget(self.messages[-1]) def add_message_history(self, message): time = f'{self.client_login}' \ f' {datetime.datetime.now().replace(microsecond=0)}:' label = Label(text=f"{time}\n{message}", color=[0.8, 1, .3, 0.7], halign='left', valign='middle') label.bind(size=label.setter('text_size')) self.messages.append(label) self.messages_layout.add_widget(self.messages[-1]) def get_message(self, *args): if self.screen_manager.current == 'chat': sender = args[0] if sender == self.contact: self.show_history() else: if self.database.is_contact(sender): text_title = f'New message from {sender}' text_label = f'Received a new message from {sender}, open chat with him?' create_message_window(text_title, text_label, self.open_new_chat, sender) else: text_title = f'New message from {sender}' text_label = f'Received a new message from {sender}.\n ' \ f'This user is not in your contact list.\n ' \ f'Add to contacts and open a chat with him?' create_message_window(text_title, text_label, self.add_contact, sender) def add_contact(self, sender): if self.client_transport.add_contact(sender): text_title = 'Info message' text_label = f'Contact {sender} successfully added.' create_message_window(text_title, text_label, self.open_new_chat, sender) else: text_title = 'Info message' text_label = f'Lost server connection!.' create_message_window(text_title, text_label, self.show_login_screen) def open_new_chat(self, sender): self.load_chat(sender) def connect_chat_signal(self, client_obj): client_obj.new_message_signal_chat.connect(self.get_message) def show_login_screen(self): self.screen_manager.current = 'login' def menu_contact(self, button): if button == 'Delete': if self.client_transport.del_contact(self.contact): text_title = 'Success!' text_label = 'Contact successfully removed.' create_message_window(text_title, text_label) self.update_contact_list() else: text_title = 'Error!' text_label = 'Lost server connection.' create_message_window(text_title, text_label, self.go_to_login) elif button == 'Info': self.screen_manager.current = 'contact_info' self.screen_manager.get_screen('contact_info').get_contact_name( self.contact)
def __init__(self, **kwargs): super(box, self).__init__(**kwargs) global bt1, bt2, bt3, main_box_self main_box = BoxLayout() main_box.orientation = 'vertical' main_box_self = main_box self.anim_type = 'slide_above_simple' #################################################################### self.menu1 = BoxLayout(orientation='vertical', spacing=0.2) self.im1 = Image(source='image_2.jpg', color=(1, 1, 1, .5)) self.im1.size_hint = [ self.menu1.size_hint[0] * 0.3, self.menu1.size_hint[1] * 0.3 ] # self.im1.pos = (self.height*1, self.width*1) gd_menu = GridLayout(cols=1, spacing=0.1) menu_btn = Button(text='change wallpaper', background_color=(0, 0, 0, 0.2), color=(1, 1, 1, 1), size_hint_y=None) menu_btn.bind(on_release=lambda x: self.toggle_nav_drawer()) menu_btn.bind(on_release=(self.gonext)) menu_btn.bind( on_release=partial(change_image1.file_manager_open, self)) gd_menu.add_widget(menu_btn) self.menu1.add_widget(self.im1) self.menu1.add_widget(gd_menu) # self.menu1.add_widget(gd_menu.menu_btn) # self.add_widget(self.menu1) ######################################################## tb = MDToolbar(title='menu', background_palette='Primary') tb.md_bg_color = [0, 0, 0, 0] tb.left_action_items = [['menu', lambda x: self.toggle_nav_drawer()]] main_box.add_widget(tb) gridlayout = GridLayout(cols=1, size_hint_y=None, spacing=2) gridlayout.bind(minimum_height=gridlayout.setter('height')) index = 0 main_lyt = main_box dirpath = os.getcwd() for dirpath, dir_name, filename in os.walk(r'/storage/emulated/0/'): if (os.path.basename(dirpath) == 'Download' or os.path.basename(dirpath) == 'audios'): for fn in glob(dirpath + '/*.mp3'): btn = tbtn(id='song_btn', song_index=index) btn_inst.append(btn) songlist[index] = [fn, btn] # print(ID3(fn).text) file2 = File(str(fn)) # song_length = float(file2.info.pprint().split(',')[-1:][0][:-8]) # print(float(song_length)) try: pic_name = fn.split('/')[-1:][0][:-4] artwork = file2.tags['APIC:'].data with open(pic_name + '.jpg', 'wb') as img: img.write(artwork) cover_album.append(pic_name + '.jpg') except: rand_val = random.randint(0, 9) cover_album.append(m_image[rand_val]) btn.bind(on_press=partial(song_btn, index, main_lyt)) index = index + 1 gridlayout.add_widget(btn) for i in range(index): img = Image( id='tn', source=cover_album[index - 1 - i], # img = Image(id='tn',source='icon.png', size=(btn_inst[index - 1 - i].height * 0.8, btn_inst[index - 1 - i].height * 0.8), pos=(btn_inst[index - 1 - i].width - main_box.width * 0.8, (btn_inst[index - 1 - i].size[1] * i) + (main_box.width * 0.5)), allow_stretch=False) btn_inst[index - 1 - i].add_widget(img) lbl = Label( text=str(songlist[index - 1 - i][0].split('/')[-1:][0]), text_size=(btn_inst[index - 1 - i].width * 7.5, None), halign='left', valign='middle', max_lines=1, shorten=True, shorten_from='right', color=(1, 1, 1, 1), pos=(img.pos[0] * 30, (btn_inst[index - 1 - i].size[1] * i) + (main_box.width))) btn_inst[index - 1 - i].add_widget(lbl) scrollview = ScrollView() scrollview.add_widget(gridlayout) main_box.add_widget(scrollview) with self.menu1.canvas.before: Color(1, 1, 1, .8) self.menu1.rect1 = Rectangle(pos=self.menu1.pos, size=self.menu1.size) self.menu1.rect1.source = 'menu_image.jpg' with main_box.canvas.before: main_box.rect = Rectangle(pos=main_box.pos, size=np.array(Window.size)) main_box.rect.source = 'image_1.jpg' # def update_rect1(instance, value): instance.rect1.pos = instance.pos instance.rect1.size = instance.size def update_rect(instance, value): instance.rect.pos = instance.pos instance.rect.size = instance.size self.menu1.bind(pos=update_rect1, size=update_rect1) main_box.bind(pos=update_rect, size=update_rect) self.add_widget(main_box)
def __init__(self, **kwargs): super(box, self).__init__(**kwargs) self.main_box = BoxLayout(size=Window.size) self.main_box.orientation = 'vertical' self.anim_type = 'slide_above_simple' ###############################################################################3 act_current_dir = os.getcwd() #os.chdir(r'/home/nagendra/test_folder') os.chdir(r'/storage/emulated/0/New kivy/My_app/New_music_code') current_dir = os.getcwd() os.chdir(act_current_dir) print('current_dirrrr = ', current_dir) ####################################################################### self.lyt_image = main_lyt_image(self) self.nav_lyt = navigator_lyt(self, self.main_box) # for navigation layout self.nav_lyt.bind(on_press=partial(open_filemanager, music_app, self.main_box, current_dir)) self.nav_lyt.bind(on_release=lambda x: self.toggle_nav_drawer()) #################################################################### gridlayout = GridLayout(cols=1, size_hint_y=None, spacing=1) gridlayout.bind(minimum_height=gridlayout.setter('height')) ##################################################################33######### print('current_di = ', current_dir) index = 0 ## r'/storage/emulated/0/New kivy/My_app/New_music_code/songs/' SD_CARD = primary_external_storage_path() request_permissions([ Permission.READ_EXTERNAL_STORAGE, Permission.WRITE_EXTERNAL_STORAGE ]) for dirpath, dir_name, filename in os.walk(SD_CARD): ##print('dir_pathh = ',dirpath) for fn in glob(dirpath + '/*.mp3'): print('fn_list= ', fn) # song_text = fn.split('/')[-1:][0][:-4] ################################################# song_name, btn_image, song_length = data_extract(fn) if (float(song_length) < 100.0): continue print('son_len = ', str(song_length)) ################################################### song_button = tbtn_new() song_button.bind( on_press=partial(self.gonext, index, self.main_box)) song_button.text = song_name songlist[index] = [fn, song_button] # song_button.canvas.before.children[0].rgba = [1,1,1,0.15] # Background color of button ################################################## song_btn_image(song_button, btn_image) ## Image of button #################################################################### gridlayout.add_widget(song_button) index += 1 #txtfile.close() scrollview = ScrollView() scrollview.add_widget(gridlayout) self.main_box.add_widget(scrollview) self.add_widget(self.main_box)
def __init__(self, **kwargs): super(DisguiseLayout, self).__init__(**kwargs) self.disguise_size = { 'hair': (200, 100), 'eyes': (200, 67), 'nose': (200, 44), 'mouth': (200, 44), 'body': (200, 200) } self.left_panel = GridLayout(cols=1, pos_hint=({ 'center_x': 0.5, 'center_y': 0.5 })) self.right_panel = ScrollView(effect_cls=ScrollEffect) for id, typ in enumerate(self.disguise_size.keys()): but = DisguiseTypeButton( typ=typ, source=os.path.join('data', 'but_{}.png'.format(typ)) ) #, size_hint=(1,0.3))#, size=(50,50), pos_hint={'x':0, 'center_y':0.3+0.1*id}) but.bind(on_release=self.show_hide_list) self.left_panel.add_widget(but) self.add_widget(self.left_panel) self.add_widget(self.right_panel) #self.disguise_size={'hair':(200,100),'eyes':(200,67),'nose':(200,44),'mouth':(200,44),'body':(200,200)} self.disguise_size = { 'hair': (300, 150), 'eyes': (300, 100), 'nose': (300, 67), 'mouth': (300, 67), 'body': (300, 300) } self.scroll_views = {} self.max_texture_size = 0 for typ, siz in self.disguise_size.items(): gridlayout = GridLayout(cols=1, spacing=10, padding=10, size_hint=(1, None)) gridlayout.bind(minimum_height=gridlayout.setter('height')) for filename in os.listdir('data'): if filename.startswith('id_{}'.format(typ)): id_trash, type_trash, name = filename.split('_') name = name.replace('.png', '') btn = DisguiseButton(typ=typ, name=name, size_hint=(None, None), size=siz, background_normal=os.path.join( 'data', filename)) btn.bind(on_release=self.pick_from_list) gridlayout.add_widget(btn) img_size = Image( source=os.path.join('data', filename)).texture_size if img_size > self.max_texture_size: self.max_texture_size = img_size self.scroll_views[typ] = ScrollView(effect_cls=ScrollEffect) self.scroll_views[typ].add_widget(gridlayout) gridlayout.bind( minimum_width=self.scroll_views[typ].setter('width'))
class Building(ButtonBehavior, Image): def __init__(self, **kwargs): super(Building, self).__init__(**kwargs) self.source = 'data/images/city/empty_place.png' self.free_space = True self.active = False self.name = 'Foundament' self.unit_grid = None self.slider = None self.available_list = None def create_building(self, build_name): path_to_building = config.buildings[build_name][3] self.source = path_to_building self.name = build_name self.free_space = False def on_press(self): pass def on_release(self): if self.free_space: self.parent.add_widget(building.menu_content(build_place=self)) else: self.parent.add_widget( self.building_content(build_place=self, build=self.name)) self.active = True def update_available_units(self): # , grid, slider final = [] # TODO: Remove it, need to add ZeroDevision except for unit in config.buildings[self.name][5]: # Для каждого юнита li = [] for i, res in enumerate(config.units[unit][2]): if res > 0: res_cost = config.resources[res_list[i]][0] li.append(res_cost / res) how_many_unit = int(min(li)) final.append(how_many_unit) if len(self.available_list) > 0: for j, widget in enumerate(self.available_list): widget.text = str(final[j]) # TODO: не работает как нужно if self.slider.available_label is not None: self.slider.max = int(self.slider.available_label.text) return final def building_content(self, build_place, build): building = config.buildings[build] scatter = ScatterLayout(id='town_hall_scatter') name_label = PlaceLabel(text=f'{build}, id: {build_place.id}') menu = MenuLayout() inside_menu = InsideMenuLayout() top_layout = BoxLayout(orientation='horizontal', size_hint_y=.3) bottom_layout = BoxLayout(orientation='vertical', size_hint_y=.3) right_layout = BoxLayout(orientation='vertical') upgrade_layout = BoxLayout(orientation='horizontal', size_hint_y=.3) description_layout = BoxLayout(size_hint_y=.7) description_label = Label(text='Описание здания') description_layout.add_widget(description_label) icon_rel = BoxLayout(size_hint_x=.3) icon = Image(source=building[3]) icon_rel.add_widget(icon) upgrade_label = Label(text=f'{building[1]} сек', size_hint_x=.9) upgrade_res_layout = BoxLayout(orientation='horizontal') for i, res_cost in enumerate(building[2]): if res_cost > 0: res_box = BoxLayout(orientation='horizontal', size_hint_x=.5) help_lay_res = RelativeLayout() help_lay_res.add_widget( Image(source=f'{config.resources[res_list[i]][2]}', size=(25, 25), pos_hint=({ 'right': 1 }), size_hint=(None, 1))) add_lay = GridLayout(cols=2, size_hint=(1, 1), pos_hint=({ 'center_x': .5, 'center_y': .5 })) add_lay.add_widget(help_lay_res) add_lay.add_widget(BuildResLabel(text=f'{res_cost}')) res_box.add_widget(add_lay) upgrade_res_layout.add_widget(res_box) upgrade_button = Button(text='Up', size_hint_x=.1) upgrade_layout.add_widget(upgrade_button) upgrade_layout.add_widget(upgrade_label) upgrade_layout.add_widget(upgrade_res_layout) right_layout.add_widget(upgrade_layout) right_layout.add_widget(description_layout) top_layout.add_widget(icon_rel) top_layout.add_widget(right_layout) middle_lay = BoxLayout(size_hint_y=.4) slider_layout = BoxLayout(orientation='vertical', size_hint_y=.7) input_layout = BoxLayout(orientation='horizontal', size_hint=(.3, 1), pos_hint=({ 'right': 1 })) text_input = UnitTextInput(text='0', size_hint_y=.9, pos_hint=({ 'center_y': .5 }), multiline=False) total_res_layout = BoxLayout(orientation='horizontal', size_hint_x=.65, padding=5) self.slider = UnitSlider(text_input, size_hint_y=.55, padding=10) total_inside = TotalInsideLayout(orientation='horizontal', slider=self.slider) time_label = TotalTimeLabel(size_hint_y=.3, halign='left') total_res_label = TotalResLabel(text='Стоимость:', size_hint_x=.35) text_input.slider = self.slider self.slider.total_inside = total_inside self.slider.time_label = time_label self.slider.total_res_label = total_res_label hire_button = HireUnitsButton(text='Нанять', disabled=True, slider=self.slider, build_root=self) count_box = BoxLayout(orientation='vertical', size_hint_x=.25, padding=1, spacing=1) up_button = UpButton(opacity=0, slider=self.slider) down_button = DownButton(opacity=0, slider=self.slider) bottom_slider_lay = BoxLayout(orientation='horizontal', size_hint_y=.45) scroll_unit = ScrollView(do_scroll_x=False, scroll_distance=50, size_hint_y=.8, pos_hint=({ 'center_y': .5 })) butt_list = [up_button, down_button] self.unit_grid = GridLayout(cols=1, padding=5, spacing=5, size_hint_y=None, opacity=0) self.unit_grid.bind(minimum_height=self.unit_grid.setter('height')) self.available_list = [] checkbox_group_list = [] for unit_name in building[5]: unit = config.units[unit_name] checkbox = UnitCheckBox(group='units', size_hint_x=.05, slider=self.slider, txt_inp=text_input, unit=unit_name, hb=hire_button, bl=butt_list, trl=total_res_label, tl=time_label) checkbox.bind(active=on_checkbox_active) checkbox_group_list.append(checkbox) grid_layout = UnitGridLayout(cols=6, size_hint_y=None, height=40, checkbox=checkbox) unit_icon = Image(source=unit[3], size_hint_x=.05) unit_name_label = Label(text=f'{unit_name}', size_hint_x=.2) unit_cost = BoxLayout(orientation='horizontal', size_hint_x=.45) for i, res_cost in enumerate(unit[2]): if res_cost > 0: res_box = BoxLayout(orientation='horizontal', size_hint_x=.5) help_lay_res = RelativeLayout() help_lay_res.add_widget( Image(source=f'{config.resources[res_list[i]][2]}', size=(25, 25), pos_hint=({ 'right': 1 }), size_hint=(None, 1))) add_lay = GridLayout(cols=2, size_hint=(1, 1), pos_hint=({ 'center_x': .5, 'center_y': .5 })) add_lay.add_widget(help_lay_res) add_lay.add_widget(BuildResLabel(text=f'{res_cost}')) res_box.add_widget(add_lay) unit_cost.add_widget(res_box) unit_time = Label(text=f'{unit[1]} сек', size_hint_x=.15) how_many_lay = BoxLayout(orientation='horizontal', size_hint_x=.1) available_label = Label(text='8', size_hint_y=.8, pos_hint=({ 'center_y': .5 })) checkbox.available_label = available_label self.available_list.append(available_label) all_button = AllUnitButton(text='All', size_hint_y=.6, pos_hint=({ 'center_y': .5 }), checkbox=checkbox) how_many_lay.add_widget(all_button) how_many_lay.add_widget(available_label) grid_layout.add_widget(checkbox) grid_layout.add_widget(unit_icon) grid_layout.add_widget(unit_name_label) grid_layout.add_widget(unit_cost) grid_layout.add_widget(unit_time) grid_layout.add_widget(how_many_lay) self.unit_grid.add_widget(grid_layout) self.slider.group_list = checkbox_group_list scroll_unit.add_widget(self.unit_grid) count_box.add_widget(up_button) count_box.add_widget(down_button) input_layout.add_widget(count_box) input_layout.add_widget(text_input) input_layout.add_widget(hire_button) slider_layout.add_widget(self.slider) total_res_layout.add_widget(total_res_label) total_res_layout.add_widget(total_inside) bottom_slider_lay.add_widget(total_res_layout) bottom_slider_lay.add_widget(input_layout) slider_layout.add_widget(bottom_slider_lay) middle_lay.add_widget(scroll_unit) bottom_layout.add_widget(slider_layout) bottom_layout.add_widget(time_label) inside_menu.add_widget(top_layout) inside_menu.add_widget(middle_lay) inside_menu.add_widget(bottom_layout) menu.add_widget(inside_menu) menu.add_widget(name_label) close_b = CloseMenuButton(self, scatter) menu.add_widget(close_b) scatter.add_widget(menu) self.update_available_units() anim_opacity_up.start(self.unit_grid) return scatter
class DateSelectionDetails(AnchorLayout): def __init__(self, ctrl, **kwargs): super().__init__(**kwargs) self.anchor_y = 'top' self.ctrl = ctrl self.grid = GridLayout() self.grid.cols = 2 self.grid.spacing = 10 self.grid.size_hint_y = None self.grid.bind(minimum_height=self.setter('height')) self.grid.row_default_height = 50 # Input data self.grid.label_date_from = Label(text="Date from:") self.grid.input_date_from = DatePicker() self.grid.label_date_to = Label(text="Date to:") self.grid.input_date_to = DatePicker() self.grid.button_all = Button(text="All dates") self.grid.button_all.bind(on_press=self.btn_all_cb) self.grid.button_ok = Button(text="Ok") self.grid.button_ok.bind(on_press=self.btn_ok_cb) self.add_widget(self.grid) self.update() def update(self): self.grid.clear_widgets() # Set dates to current filter values date_from = self.ctrl.transaction_filter.get_filter_date_from(self.ctrl.model.DATE) date_to = self.ctrl.transaction_filter.get_filter_date_to(self.ctrl.model.DATE) date_from_txt = date_from.strftime(self.ctrl.model.DATE_TIME_FORMAT) date_to_txt = date_to.strftime(self.ctrl.model.DATE_TIME_FORMAT) self.grid.input_date_from.text = date_from_txt self.grid.input_date_to.text = date_to_txt # Add GUI elements self.grid.add_widget(self.grid.label_date_from) self.grid.add_widget(self.grid.input_date_from) self.grid.add_widget(self.grid.label_date_to) self.grid.add_widget(self.grid.input_date_to) self.grid.add_widget(self.grid.button_all) self.grid.add_widget(self.grid.button_ok) def btn_all_cb(self, _): years = self.ctrl.model.years() date_from = datetime(min(years), 1, 1) date_to = datetime(max(years), 12, 31) date_from_txt = date_from.strftime(self.ctrl.model.DATE_TIME_FORMAT) date_to_txt = date_to.strftime(self.ctrl.model.DATE_TIME_FORMAT) self.grid.input_date_from.text = date_from_txt self.grid.input_date_to.text = date_to_txt def btn_ok_cb(self, _): date_from_txt = self.grid.input_date_from.text date_to_txt = self.grid.input_date_to.text date_from = datetime.strptime(date_from_txt, self.ctrl.model.DATE_TIME_FORMAT) date_to = datetime.strptime(date_to_txt, self.ctrl.model.DATE_TIME_FORMAT) self.ctrl.transaction_filter.select_date_range(self.ctrl.model.DATE, date_from, date_to) self.ctrl.update()
class TransactionDetails(AnchorLayout): """ Date: in date Account: in account ... """ def __init__(self, ctrl, index=None, **kwargs): super().__init__(**kwargs) self.anchor_y = 'top' self.ctrl = ctrl self.index = index # Only used when a transaction is edited and not created! self.grid = GridLayout() self.grid.cols = 2 self.grid.spacing = 10 self.grid.size_hint_y = None self.grid.bind(minimum_height=self.setter('height')) self.grid.row_default_height = 50 # Input data self.grid.label_date = Label(text="Date:") self.grid.input_date = DatePicker() self.grid.label_acc = Label(text="Account:") self.grid.input_acc = ListPicker(ctrl.model.accounts, add_callback=self.cb_add_account, topic="Account") self.grid.label_amount = Label(text="Amount:") self.grid.input_amount = TextInput(text="", multiline=False, input_type='number') self.grid.label_category = Label(text="Category:") self.grid.input_category = ListPicker(self.ctrl.model.categories, add_callback=self.cb_add_category, topic="Category") self.grid.label_description = Label(text="Description:") self.grid.input_description = TextInput(text="", multiline=False) # Buttons: self.grid.button_cancel = Button(text="Cancel") self.grid.button_cancel.bind(on_press=self.cancel_callback) self.grid.button_save = Button(text="Save") self.grid.button_save.bind(on_press=self.save_callback) self.grid.button_delete = Button(text="Delete") self.grid.button_delete.bind(on_press=self.delete_callback) self.add_widget(self.grid) self.update() def cb_add_category(self, text): # Add category to model self.ctrl.model.categories.append(text) # Update GUI element to take new category into account self.grid.input_category = ListPicker(self.ctrl.model.categories, add_callback=self.cb_add_category, topic="Category") # Write category text in text box self.grid.input_category.text = text self.update() def cb_add_account(self, text): self.ctrl.model.accounts.append(text) # Update GUI element to take new category into account self.grid.input_acc = ListPicker(self.ctrl.model.accounts, add_callback=self.cb_add_account, topic="Account") self.grid.input_acc.text = text self.update() def update(self): if self.index != None: # The transaction is not new -> fill fields with data model = self.ctrl.model data = model.get_data() row = data.loc[self.index] self.grid.input_date.text = row[self.ctrl.model.DATE].strftime(model.DATE_TIME_FORMAT) self.grid.input_acc.text = str(row[self.ctrl.model.ACCOUNT]) self.grid.input_amount.text = str(row[self.ctrl.model.AMOUNT]) self.grid.input_description.text = str(row[self.ctrl.model.DESCRIPTION]) self.grid.input_category.text = str(row[self.ctrl.model.CATEGORY]) self.grid.clear_widgets() self.grid.add_widget(self.grid.label_date) self.grid.add_widget(self.grid.input_date) self.grid.add_widget(self.grid.label_acc) self.grid.add_widget(self.grid.input_acc) self.grid.add_widget(self.grid.label_amount) self.grid.add_widget(self.grid.input_amount) self.grid.add_widget(self.grid.label_category) self.grid.add_widget(self.grid.input_category) self.grid.add_widget(self.grid.label_description) self.grid.add_widget(self.grid.input_description) # Buttons: self.grid.add_widget(self.grid.button_cancel) if self.index != None: additional_grid = GridLayout(cols=2) additional_grid.add_widget(self.grid.button_delete) additional_grid.add_widget(self.grid.button_save) self.grid.add_widget(additional_grid) else: self.grid.add_widget(self.grid.button_save) def cancel_callback(self, _): self.ctrl.update() def _check_input(self): amount_str = self.grid.input_amount.text return TextCheck(amount_str).check_float() def save_callback(self, _): if self._check_input(): print(self.grid.input_category.text) if self.index != None: print(self.index) print(self.ctrl.model.get_data()) self.ctrl.model.edit_transaction(self.index, self.grid.input_date.text, self.grid.input_acc.text, self.grid.input_description.text, float(self.grid.input_amount.text), self.grid.input_category.text) else: self.ctrl.model.new_transaction(self.grid.input_date.text, self.grid.input_acc.text, self.grid.input_description.text, float(self.grid.input_amount.text), self.grid.input_category.text) self.ctrl.update() else: MsgBox("The entered amount is not valid.\nThe decimal separator is \".\"") def delete_callback(self, _): # ToDo: Implement additional question if the user is sure to delete the transaction self.ctrl.model.delete_transaction(self.index) self.ctrl.update()
class SettingsScreen(Screen): logic = ObjectProperty(None) mainlayout = ObjectProperty(None) menubutton = ObjectProperty(None) settingsbutton = ObjectProperty(None) settingsview = ObjectProperty(None) def __init__(self, logic, iconsize, iconratio_x, iconratio_y, **kwargs): super(SettingsScreen, self).__init__(**kwargs) self.logic = logic self.iconsize = iconsize self.iconratio_x = iconratio_x self.iconratio_y = iconratio_y self.setting_items = {} self.build_interface() def on_enter(self): '''get settings from logic''' for key in self.logic.settings: if key in self.setting_items: self.setting_items[key].value = self.logic.settings[key] def on_leave(self): '''write setting to logic and save to file''' for key in self.logic.settings: if key in self.setting_items: self.logic.settings[key] = self.setting_items[key].value self.logic.apply_settings() App.get_running_app().settings.save() def build_interface(self): self.mainlayout = FloatLayout() self.settingsview = ScrollView(size_hint=(0.7, 0.7), pos_hint={ 'x': 0.15, 'y': 0.15 }) # use gridlayout to put items into scrollview self.settingslayout = GridLayout(cols=1, size_hint_y=None, spacing=80) # magic binding self.settingslayout.bind( minimum_height=self.settingslayout.setter('height')) controller = self.logic.settings model = controller.model # sort items by seqnum itemlist = [ item for item in sorted(model, key=lambda x: model[x].seqnum) ] for settings_item in itemlist: item = model[settings_item] if not item.show: continue settings_type = item.settings_type widget = None if settings_type == 'select': widget = SettingsSlot(size_hint=(1, None), setting_type='select', label_text=item.label, items=item.values) elif settings_type == 'bool': widget = SettingsSlot(size_hint=(1, None), setting_type='bool', label_text=item.label) elif settings_type == 'number': widget = SettingsSlot(size_hint=(1, None), setting_type='number', label_text=item.label, setting_max=item.max_value, setting_min=item.min_value, setting_value=item.value) if not widget: continue self.setting_items[settings_item] = widget self.settingslayout.add_widget(widget) self.settingsbutton = Button(text='KivySettings', size_hint=(1, None), on_press=self.switchto_kivysettings) self.settingslayout.add_widget(self.settingsbutton) self.menubutton = RealButton('./media/icons/arrowleft.png', './media/icons/arrowleft.png', self.switchto_menu, size_hint=(None, None), size=(self.iconsize, self.iconsize), pos_hint={ 'x': 0, 'y': 0 }, source='./media/icons/arrowleft.png', always_release=True) # add settingslayout to scrollview self.settingsview.add_widget(self.settingslayout) self.mainlayout.add_widget(self.menubutton) self.mainlayout.add_widget(self.settingsview) self.add_widget(self.mainlayout) def switchto_menu(self, instance): self.manager.transition = FadeTransition() self.manager.current = 'menu' def switchto_credits(self, instance): self.manager.transition = FadeTransition() self.manager.current = 'credits' def switchto_kivysettings(self, instance): App.get_running_app().open_settings()
def __init__(self, title, content, type, avatar, login, reputation, deadline, userId, selfUserID, blockId, openDialog, **kwargs): super(DopActivity, self).__init__(**kwargs) infoBlock = GridLayout(cols=1, spacing=10, size_hint_y=None, height=200) self.openDialog = openDialog self.userId = userId self.sUserID = selfUserID self.type = type self.blockId = blockId self.d = selfUserID # self.postCreateDialog = postCreateDialog imagePlace = FloatLayout(size_hint=[1, None], height=150) imagePlace.add_widget( AsyncImage(pos_hint={ "center_x": .5, "center_y": .5 }, source=avatar)) infoBlock.add_widget(imagePlace) infoBlock.add_widget( Label(text=login, color=COLOR["LIGHT"]["MAIN_COLOR"], size_hint_y=None, height=10)) infoBlock.add_widget(InfoPlate(reputation)) infoBlock.add_widget(InfoPlate(deadline)) endButtons = FloatLayout(size_hint=[.7, None], height=75) list = ScrollView() layoutList = GridLayout(cols=1, size_hint_y=None) layoutList.bind(minimum_height=layoutList.setter('height')) layoutList.add_widget(infoBlock) layoutList.add_widget(Widget(size_hint=[1, None], height=50)) layoutList.add_widget( AllInformation(title=title, content=content, type=type)) layoutList.add_widget(Widget(size_hint=[1, None], height=20)) if userId == selfUserID: endButtons.add_widget(OkButton(text="Редактировать")) else: okButton = OkButton(text="Отозваться", on_press=self.createDialog, idFrom=selfUserID, idTo=userId, userName=login, blockName=title, blockId=blockId, avatar=avatar) noButton = Button(size_hint=[.3, None], height=35, background_normal="images/backLayoutBad.png", text="Жалоба", pos_hint={ "center_x": .5, "y": 0 }, on_press=self.sendReport) endButtons.add_widget(okButton) endButtons.add_widget(noButton) layoutList.add_widget(endButtons) layoutList.add_widget(Widget(size_hint_y=None, height=15)) list.add_widget(layoutList) self.add_widget(list)
class Game(Screen): def __init__(self, **kwargs): Screen.__init__(self, **kwargs) self.layout = BoxLayout(orientation='vertical') self.top_bar = BoxLayout(orientation='horizontal', size_hint_y=0.2) self.grid = GridLayout(cols=4, padding=2) self.score = 0 self.over = False self.touch_initial = (0, 0) self.matrix = np.zeros((4, 4), np.int) self.tiles = [] for i in range(4): for j in range(4): if j == 0: self.tiles.append([]) self.tiles[i].append(Tile(value=0, disabled=True)) self.grid.add_widget(self.tiles[i][j]) # top bar restartButton = Button(text='Restart', on_press=self.restart, font_size=24, size_hint_x=0.5) quitButton = Button(text='Quit', on_press=self.quit, font_size=24, size_hint_x=0.5) saveButton = Button(text='Save', on_press=self.save, font_size=24, size_hint_x=0.5) loadButton = Button(text='Load', on_press=self.load, font_size=24, size_hint_x=0.5) self.scoreLabel = Label(text=str(self.score), font_size=24) self.top_bar.add_widget(quitButton) self.top_bar.add_widget(restartButton) self.top_bar.add_widget(self.scoreLabel) self.top_bar.add_widget(saveButton) self.top_bar.add_widget(loadButton) # swipe control self.grid.bind(on_touch_down=self._touch_down) self.grid.bind(on_touch_up=self._touch_up) # keyboard control self._keyboard = Window.request_keyboard(self._keyboard_closed, self) self._keyboard.bind(on_key_down=self._on_keyboard_down) self.layout.add_widget(self.top_bar) self.layout.add_widget(self.grid) self.add_widget(self.layout) # initialize with two tiles self.add_tile() self.add_tile() def _touch_down(self, instance, touch): self.touch_initial = (touch.x, touch.y) def _touch_up(self, instance, touch): if not self.over: dx = touch.x - self.touch_initial[0] dy = touch.y - self.touch_initial[1] if abs(dx) >= abs(dy): if dx < -40: self.move(3) # left elif dx > 40: self.move(2) # right else: if dy < -40: self.move(0) # down elif dy > 40: self.move(1) # up return True def _keyboard_closed(self): self._keyboard.unbind(on_key_down=self._on_keyboard_down) self._keyboard = None def _on_keyboard_down(self, keyboard, keycode, text, modifiers): if not self.over: if keycode[1] == 'up': self.move(1) elif keycode[1] == 'down': self.move(0) elif keycode[1] == 'left': self.move(3) elif keycode[1] == 'right': self.move(2) return True def add_tile(self): '''randomly add one tile with number 2 or 4''' choices = np.array([2, 4]) probabilities = np.array([0.9, 0.1]) val = np.random.choice(choices, 1, p=probabilities)[0] empties = self.get_empty() empty_index = np.random.choice(empties.shape[0]) empty = empties[empty_index] self.matrix[empty[0], empty[1]] = val self.over = self.is_over() self.update() def get_empty(self): '''retuen a 2d numpy array with locations of empty entries''' return np.argwhere(self.matrix == 0) def move(self, direction, trial=False): ''' one move of the game. direction: 0, 1, 2, 3 represent down, up, right, left tiral: when True: trial mode, won't change the matrix return: whether changed, score of the move ''' changed = False score = 0 shift_dir = (direction + 1) % 2 if direction <= 1: # up or down, split matrix into columns for y in range(4): col = self.matrix[:, y] (new_col, s) = self.shift(col, shift_dir) score += s if (new_col != col).any(): changed = True if not trial: self.matrix[:, y] = new_col else: # left or right, split matrix into rows for x in range(4): row = self.matrix[x, :] (new_row, s) = self.shift(row, shift_dir) score += s if (new_row != row).any(): changed = True if not trial: self.matrix[x, :] = new_row if not trial and changed: self.score += score self.add_tile() return (changed, score) def shift(self, row, direction): ''' shift the row and combine the rows direction: left if direction==0, right if direction==1 return:output row, score ''' if direction: row = np.flip(row) # shift shifted_row = np.zeros([4], np.int) i = 0 for n in row: if n != 0: shifted_row[i] = n i += 1 # combine score = 0 output = np.zeros([4], np.int) output_index = 0 skip = False for i in range(3): if skip or shifted_row[i] == 0: skip = False continue output[output_index] = shifted_row[i] if shifted_row[i] == shifted_row[i + 1]: output[output_index] += shifted_row[i + 1] score += shifted_row[i] * 2 skip = True output_index += 1 if not skip: output[output_index] = shifted_row[-1] if direction: output = np.flip(output) return (output, score) def update(self): '''update the labels''' for i in range(4): for j in range(4): self.tiles[i][j].value = self.matrix[i, j] if self.over: self.scoreLabel.text = 'Game Over\nScore: {}'.format(self.score) popup = Popup(title='Notification', content=Label(text='Game Over\nScore: {}'.format( self.score), font_size=24), size_hint=(0.4, 0.3)) popup.open() else: self.scoreLabel.text = str(self.score) def is_over(self): '''check if the game is over by trying all possible movements''' if self.get_empty().size != 0: return False else: for dir in range(4): if self.move(dir, trial=True)[0] == True: return False return True def restart(self, value): '''restart the game, bound to restart button''' self.score = 0 self.over = False self.matrix = np.zeros((4, 4), np.int) for row in self.tiles: for tile in row: tile.value = 0 self.add_tile() self.add_tile() def save(self, value): '''save the game''' if self.over: msg = 'You cannot save a game\n that is already over!' else: try: archive = (self.score, self.matrix.tolist()) pickle.dump(archive, open('save.p', 'wb')) msg = 'Saved Successfully!' except: msg = 'Error saving the game:(' popup = Popup(title='Notification', content=Label(text=msg, font_size=24), size_hint=(0.4, 0.3)) popup.open() def load(self, value): '''load saved game''' backup = self.matrix try: score, lmatrix = pickle.load(open('save.p', 'rb')) assert len(lmatrix) == 4 assert len(lmatrix[0]) == 4 self.matrix = np.array(lmatrix) self.score = score msg = 'Loaded successfully!' except: msg = 'Error loading saved game :(' self.matrix = backup popup = Popup(title='Notification', content=Label(text=msg, font_size=24), size_hint=(0.4, 0.3)) popup.open() self.over = self.is_over() self.update() def quit(self, value): '''move back to menu screen without resetting the game''' self.manager.transition.direction = 'right' self.manager.current = 'menu'
class SecondaryWindow(Screen): def __init__(self, **kwargs): # GUI from top to bottom, left to right super(SecondaryWindow, self).__init__(**kwargs) self.scroll = ScrollView(size_hint=(1, None), size=(Window.width, Window.height)) self.scroll_btn = None self.scroll_grid = GridLayout(cols=2, spacing=1, size_hint_y=None) self.scroll_grid.bind(minimum_height=self.scroll_grid.setter('height')) with self.canvas: Color(0.2, 0.2, 0.28) Rectangle(size=(Window.width**2, Window.height**2)) self.btn_live_orders = Button(size_hint_y=None, height=40, text="< Current Orders", background_color=[0.45, 0.45, 0.45, 3], on_release=self.changeWindow) self.scroll_grid.add_widget(self.btn_live_orders) self.btn_menu = Button(size_hint_y=None, height=40, text="Menu >", background_color=[0.45, 0.45, 0.45, 3], on_release=self.changeWindow) self.scroll_grid.add_widget(self.btn_menu) self.drp_date = DropDown() self.drp_date_check = str(datetime.date.today()) self.drp_date_btn = Button(size_hint_y=None, height=40, text=f"{self.drp_date_check}", background_color=[0.45, 0.45, 0.45, 3], on_release=self.drp_date.open) self.drp_date_btn_dates = None self.scroll_grid.add_widget(self.drp_date_btn) self.popup = Popup(title='Title', title_align='center', content=Label(text='Text', size=(400, 400), text_size=[380, 380], halign='center', valign='center'), size_hint=(None, None), size=(400, 400)) self.popup_db_list = [] # self.dropDown() # # def dropDown(self): # Always called with __init__ # for i in range(len(screen_main.order_database_dates)): # self.drp_date_btn_dates = Button(text=f"{screen_main.order_database_dates[i]}", size_hint_y=None, # height=44, background_color=[0.45, 0.45, 0.45, 3], # on_release=self.checkDate) # self.drp_date.add_widget(self.drp_date_btn_dates) def connectSocket(self): host = '10.0.0.69' port = 8912 address = (host, port) client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect(address) while True: msg = pickle.loads(client.recv(4096)) print(msg) def checkDate(self, instance): self.drp_date_check = instance.text self.generateOrders() self.drp_date.dismiss() def changeWindow(self, instance): if 'Menu' in instance.text: sm.current = 'main' sm.transition.direction = 'left' self.reset() elif 'Orders' in instance.text: sm.current = 'tertiary' sm.transition.direction = 'right' self.reset() def reset(self): self.scroll_grid.clear_widgets() self.scroll_grid.add_widget(self.btn_live_orders) self.scroll_grid.add_widget(self.btn_menu) self.scroll_grid.add_widget(self.drp_date_btn) self.popup_db_list.clear() def popupItem(self, instance): num = int(instance.text.split('Order #')[-1]) self.popup.content.text = f"{self.popup_db_list[num - 1]}" self.popup.title = f"Order #{num}" self.popup.open()
class ViewItem(Screen): def __init__(self, **kw): super(ViewItem, self).__init__(**kw) self.fields = [] self.title_item = None box = BoxLayout(orientation='vertical') back_button = Button(text='< Назад в главное меню', on_press=lambda x: set_screen('main'), size_hint_y=None, height=dp(60)) box.add_widget(back_button) scroll_view = ScrollView(size_hint=(1, 1), size=(Window.width, Window.height)) self.layout_fields = GridLayout(cols=1, spacing=10, size_hint_y=None) self.layout_fields.bind( minimum_height=self.layout_fields.setter('height')) scroll_view.add_widget(self.layout_fields) box.add_widget(scroll_view) self.lbl_total = Label(text="Итог: ", size_hint_y=None, height=dp(40)) box.add_widget(self.lbl_total) wrapper = BoxLayout(size_hint_y=None, height=dp(60)) btn_add = Button(text="Добавить поле") btn_add.bind( on_press=lambda x: self._add_item(None, None, None, 'Sum')) btn_submit = Button(text="Сохранить") btn_submit.bind(on_press=self.submit_click) wrapper.add_widget(btn_submit) wrapper.add_widget(btn_add) box.add_widget(wrapper) self.add_widget(box) def submit_click(self, btn): res_fields = [] for field in self.fields: a = {} for (k, v) in field.items(): if is_lambda(v): a[k] = v() else: a[k] = v res_fields.append(a) gv.db.update_item(self.id_item, self.title_item.text, res_fields) set_screen('main') def on_enter(self): # Будет вызвана в момент открытия экрана # self.layout_fields self.id_item = gv.cur_id_item (item, item_fields) = gv.db.get_item_by_id(self.id_item) self.title_item = TextInput(text=item[1], multiline=False, height=dp(40), size_hint_y=None, hint_text="Название") self.layout_fields.add_widget(self.title_item) for field in item_fields: self._add_item(field[0], field[1], field[3], field[2]) def _ping4total(self, *_): sum_val = 0 for field in self.fields: if field['type'] == 'notSum': continue str_val = field['val']() if not str_val: continue try: float_val = float(str_val) except ValueError: self.lbl_total.text = 'Error' return sum_val += float_val self.lbl_total.text = 'Итог: ' + str(sum_val) def _add_item(self, id_item, title, val, item_type): box = BoxLayout(size_hint_y=None, height=dp(40)) if title: title = TextInput(text=title, multiline=False, height=dp(40), size_hint_y=None, hint_text="Название") else: title = TextInput(multiline=False, height=dp(40), size_hint_y=None, hint_text="Название") if val: val = TextInput(text=val, multiline=False, height=dp(40), size_hint_y=None, hint_text="Значение") else: val = TextInput(multiline=False, height=dp(40), size_hint_y=None, hint_text="Значение") val.bind(text=self._ping4total) box.add_widget(title) box.add_widget(val) self.layout_fields.add_widget(box) self.fields.append({ 'id': id_item, 'title': lambda: title.text, 'val': lambda: val.text, 'type': item_type }) self._ping4total() def on_leave(self): # Будет вызвана в момент закрытия экрана self.layout_fields.clear_widgets() self.fields = [] self.title_item = None
class TabbedCEFBrowser(GridLayout): def __init__(self, urls=["http://www.rentouch.ch"], *largs, **dargs): super(TabbedCEFBrowser, self).__init__(cols=1, *largs, **dargs) gl = GridLayout(rows=1, size_hint=(1, None), height=controls_size) self.current_tab = None self.__tab_bar_scroll = ScrollView(size_hint=(1, 1)) self.__tab_bar_grid = GridLayout(rows=1, size_hint=(None, 1)) self.__tab_bar_grid.bind( minimum_width=self.__tab_bar_grid.setter("width")) last_tab = None for url in urls: this_tab = TabbedCEFBrowserTab(self, url, url) this_tab.last_tab = last_tab self.__tab_bar_grid.add_widget(this_tab) last_tab = this_tab self.current_tab = last_tab self.__tab_bar_scroll.add_widget(self.__tab_bar_grid) self.__tab_bar_scroll.bind(height=self.__tab_bar_grid.setter("height")) gl.add_widget(self.__tab_bar_scroll) self.__tab_bar_new = Button(text="+", font_size=controls_size / 2, size_hint=(None, 1), width=controls_size) self.__tab_bar_new.bind(on_press=self._on_new_tab) gl.add_widget(self.__tab_bar_new) self.__control_bar_grid = GridLayout(rows=1, size_hint=(1, None), height=controls_size) self._back_button = Button(text="<", font_size=controls_size / 2, size_hint=(None, 1), width=controls_size) self._back_button.bind(on_press=self._on_back_press) self._forward_button = Button(text=">", font_size=controls_size / 2, size_hint=(None, 1), width=controls_size) self._forward_button.bind(on_press=self._on_forward_press) self._url_input = TextInput(text="http://", font_size=controls_size / 2, size_hint=(1, 1), multiline=False) self._url_input.bind(focus=self._on_url_focus) self._url_input.bind(on_text_validate=self._on_url_validate) self._load_button = Button(text="Go", font_size=controls_size / 2, size_hint=(None, 1), width=controls_size) self._load_button.bind(on_press=self._on_load_button) self.__control_bar_grid.add_widget(self._back_button) self.__control_bar_grid.add_widget(self._forward_button) self.__control_bar_grid.add_widget(self._url_input) self.__control_bar_grid.add_widget(self._load_button) self._current_browser = CEFBrowser() self.add_widget(gl) self.add_widget(self.__control_bar_grid) self.add_widget(self._current_browser) self.select_first_tab() def _focus_url_input(self, *largs): self._url_input.focus = True def _on_new_tab(self, but): self.add_tab(TabbedCEFBrowserTab(self, "http://google.com", "Google")) Clock.schedule_once(self._focus_url_input, 0) def _on_back_press(self, back_button): self._current_browser.go_back() def _on_forward_press(self, forward_button): self._current_browser.go_forward() def _on_url_focus(self, url_input, new_focus): if new_focus: def fn(*largs): url_input.select_all() Clock.schedule_once(fn, 0) self._load_button.text = "Go" else: url_input.text = self._current_browser.url self._load_button.text = \ "x" if self._current_browser.is_loading else "r" def _on_url_validate(self, url_input): self._current_browser.url = self._url_input.text def _on_load_button(self, load_button): if self._url_input.focus: self._current_browser.url = self._url_input.text elif self._current_browser.is_loading: self._current_browser.stop_loading() else: self._current_browser.reload() def select_first_tab(self): for tab in self.__tab_bar_grid.children: tab.select() break @property def tabs(self): return self.__tab_bar_grid.children def add_tab(self, new_tab): self.__tab_bar_grid.add_widget(new_tab) new_tab.select() def remove_tab(self, remove_tab): self.__tab_bar_grid.remove_widget(remove_tab) self.current_tab = remove_tab.last_tab remove_tab.last_tab.select() def _set_tab(self, new_tab): if self.current_tab != new_tab: ct = self.current_tab tmp = ct while tmp: if tmp.last_tab == new_tab: tmp.last_tab = new_tab.last_tab tmp = tmp.last_tab new_tab.last_tab = ct self.current_tab = new_tab try: self._current_browser.unbind(url=self._url_input_set_text) except: pass Clock.schedule_once( functools.partial(self._old_tab_remove_keyboard, self._current_browser)) self.remove_widget(self._current_browser) self._url_input.text = new_tab.url self._current_browser = new_tab.cef_browser self.add_widget(self._current_browser) self._current_browser.bind(url=self._url_input_set_text) def _url_input_set_text(self, browser, url): self._url_input.text = url if self._url_input.focus: self._url_input.select_all() def _old_tab_remove_keyboard(self, browser, *largs): print("old_tab_remove_keyboard", browser) browser.focus = False
class TertiaryWindow(Screen): order_list = [] order_list_past = [] def __init__(self, **kwargs): # GUI from top to bottom, left to right super(TertiaryWindow, self).__init__(**kwargs) with self.canvas: Color(0.2, 0.2, 0.28) Rectangle(size=(Window.width**2, Window.height**2)) self.scroll = ScrollView(size_hint=(1, None), size=(Window.width, Window.height)) self.scroll_btn = None self.scroll_grid = GridLayout(cols=1, spacing=1, size_hint_y=None) self.scroll_grid.bind(minimum_height=self.scroll_grid.setter('height')) self.btn_menu = Button(size_hint_y=None, height=40, text="Order Database >", background_color=[0.45, 0.45, 0.45, 3], on_release=self.changeWindow) self.scroll_grid.add_widget(self.btn_menu) self.btn_menu.set_disabled(1) self.btn_connecting = Button( size_hint_y=None, height=80, text="Connecting to server . . .", background_color=[1.3, 0.2, 0.2, 3], background_down='atlas://data/images/defaulttheme/button') self.scroll_grid.add_widget(self.btn_connecting) self.button_id = None self.div = Button( text=f"[b]----------[/b]", markup=True, size_hint_y=None, height=20, background_color=[0.4, 0.4, 0.4, 3], background_down='atlas://data/images/defaulttheme/button') self.popup = Popup( title='Notice', title_align='center', content=Label( text= 'This order has not been submitted by the cashier yet. Please wait until' ' the order has been submitted to finish it.', size=(400, 400), text_size=[380, 380], halign='center', valign='center'), size_hint=(None, None), size=(400, 400)) threading.Thread(target=self.connectSocket).start() if len(self.scroll.children) == 0: self.scroll.add_widget(self.scroll_grid) self.add_widget(self.scroll) def connectSocket(self): host = '10.0.0.69' port = 8912 address = (host, port) header_len = 19 while True: time.sleep(0.5) try: client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect(address) self.scroll_grid.remove_widget(self.btn_connecting) self.btn_connecting.text = 'Lost connection with server. Trying to reconnect. . .' self.btn_menu.set_disabled(0) while True: time.sleep(0.5) header = '0'.encode() try: header = client.recv(10) if header.decode() == 'B=G#J3>m$p': print('<Connection alive>') except UnicodeDecodeError: msg = pickle.loads(header + client.recv(4096)) self.order_list_past.append(msg) self.generatePastOrders() except ConnectionResetError: print('<Connection to server lost>') self.scroll_grid.add_widget(self.btn_connecting) break except ConnectionRefusedError: continue def changeWindow(self, instance): if 'Order Database' in instance.text: sm.current = 'secondary' sm.transition.direction = 'left' screen_second.generateOrders() def reset(self): self.scroll_grid.clear_widgets() self.scroll_grid.add_widget(self.btn_menu) def cancelOrder(self): temp_list = [] temp_num = 0 temp_total = 0 rev = [] for child in self.scroll_grid.children: rev.append(child) rev.reverse() for child in rev: if 'Order' not in child.text and '^ ^ ^' not in child.text and '- - -' not in child.text and '----------' not in child.text: temp_list.append(child) temp_total += 1 continue elif '----------' in child.text: for items in temp_list: temp_num += 1 if temp_total == temp_num and temp_num > 0: for item in temp_list: self.scroll_grid.remove_widget(item) self.scroll_grid.remove_widget(self.div) temp_list.clear() temp_num = 0 temp_total = 0 break else: temp_list.clear() temp_num = 0 temp_total = 0 else: temp_list.clear() temp_num = 0 temp_total = 0 def itemFinished(self, instance=None): self.button_id = instance if "[s]" not in instance.text: instance.text = f"[s]{instance.text}[/s]" instance.background_color = [0.6, 0.6, 0.6, 3] else: instance.text = f"{instance.text[3:-4]}" instance.background_color = [1.8, 0.8, 0, 3] temp_list = [] temp_num = 0 temp_total = 0 rev = [] for child in self.scroll_grid.children: rev.append(child) rev.reverse() for child in rev: if 'Order' not in child.text and '^ ^ ^' not in child.text and '- - -' not in child.text and '----------' not in child.text: temp_list.append(child) temp_total += 1 continue else: div = child for items in temp_list: if '[/s]' in items.text: temp_num += 1 if temp_total == temp_num and temp_num > 0: if "----------" in div.text: self.popup.open() instance.text = f"{instance.text[3:-4]}" instance.background_color = [1.8, 0.8, 0, 3] break for item in temp_list: self.scroll_grid.remove_widget(item) self.scroll_grid.remove_widget(div) temp_list.clear() temp_num = 0 temp_total = 0 break else: temp_list.clear() temp_num = 0 temp_total = 0 # def generateCurOrders(self, instance=None, text=None): # self.cancelOrder() # # for i in range(len(screen_main.order_list)): # t = screen_main.order_list[i].time # if int(t.split(':')[0]) > 12 and 'PM' not in t: # hour = int(t.split(':')[0]) - 12 # screen_main.order_list[i].time = f"{hour}{t[-3:]} PM" # else: # if 'AM' not in t and 'PM' not in t: # screen_main.order_list[i].time = f"{t} AM" # # self.scroll_grid.add_widget( # Button( # text=f"{screen_main.order_list[i].details}{screen_main.order_list[i].food}" # f"{screen_main.order_list[i].to_go} | [b]{screen_main.order_list[i].time}[/b]", # size_hint_y=None, height=40, background_color=[1.8, 0.8, 0, 3], # markup=True, on_release=self.itemFinished)) # # if len(screen_main.order_list) > 0: # self.scroll_grid.add_widget(self.div) # def generatePastOrders(self, instance=None, text=None): self.cancelOrder() for i in range(len(self.order_list_past[-1])): t = self.order_list_past[-1][i].time if int(t.split(':')[0]) > 12 and 'PM' not in t: hour = int(t.split(':')[0]) - 12 self.order_list_past[-1][i].time = f"{hour}{t[-3:]} PM" else: if 'AM' not in t and 'PM' not in t: self.order_list_past[-1][i].time = f"{t} AM" self.scroll_grid.add_widget( Button( text= f"{self.order_list_past[-1][i].details}{self.order_list_past[-1][i].food}" f"{self.order_list_past[-1][i].to_go} | [b]{self.order_list_past[-1][i].time}[/b]", markup=True, size_hint_y=None, height=40, background_color=[1.8, 0.8, 0, 3], on_release=self.itemFinished)) # if len(screen_main.txt_name.text) == 0: self.scroll_grid.add_widget( Button(text=f"[b]- - -[/b]", markup=True, size_hint_y=None, height=20, background_color=[0.4, 0.4, 0.4, 3], background_down='atlas://data/images/defaulttheme/button'))
def __init__(self, **kwargs): super(MainScreen, self).__init__(**kwargs) # Some responsive maths size_win = Window.size s = float(size_win[1]) / 720 colors = standard_color_theme() self.colors = [list(c) + [1] for c in colors] title_y = int(0.2 * size_win[1]) btn_fold = size_win[1] - title_y # The button is 4:5 (1/5 for stars) # And the grid is 4 cols pad_btn = 80 * s spacing_btn = (pad_btn, 120 * s) btn_size_x = float(size_win[0]) - (pad_btn * 2) - spacing_btn[0] * (3) btn_size_x /= 4 # Main boxlayout and title main_l = GridLayout(cols=1, padding=10, spacing=0, size_hint_y=None) main_l.bind(minimum_height=main_l.setter('height')) title = Label(text='ROCKET KITE', font_size=85 * s, size_hint_y=None, height=title_y, color=self.colors[8]) main_l.add_widget(title) # Scroll and Grid scroll = ScrollView(size_hint=(None, None), size=Window.size) btn_l = GridLayout(cols=4, spacing=spacing_btn, padding=pad_btn, size_hint_y=None) btn_l.bind(minimum_height=btn_l.setter('height')) Window.clearcolor = self.colors[2] # Load highscore and check which levels are available self.highscore = self.load_highscore() # Make some btns self.btns = [] t = [0, 3, 4] for i, level in enumerate(progression_levels): btn_img = 'img/maps/{}.png'.format(level['name']) btn = Button(on_press=self.btn_press, size_hint_y=None, height=btn_size_x, font_size=80 * s, color=self.colors[8]) btn.background_color = self.colors[7] btn.background_normal = btn_img btn.background_down = '' btn.name = i btn_l.add_widget(btn) self.btns.append(btn) btn = Button(on_press=self.on_settings, size_hint_y=None, height=btn_size_x) btn.background_color = self.colors[6] btn.background_normal = 'img/buttons/settings.png' btn.background_down = '' btn_l.add_widget(btn) main_l.add_widget(btn_l) #main_l.bind(minimum_height=main_l.setter('height')) scroll.add_widget(main_l) self.add_widget(scroll) self.current_game = -1 self.update_btns()
class ContextMenu(TabbedPanel): '''ContextMenu class. See module documentation for more information. :Events: `on_select`: data Fired when a selection is done, with the data of the selection as first argument. Data is what you pass in the :meth:`select` method as first argument. `on_dismiss`: .. versionadded:: 1.8.0 Fired when the ContextMenu is dismissed either on selection or on touching outside the widget. ''' container = ObjectProperty(None) '''(internal) The container which will be used to contain Widgets of main menu. :data:`container` is a :class:`~kivy.properties.ObjectProperty`, default to :class:`~kivy.uix.boxlayout.BoxLayout`. ''' main_tab = ObjectProperty(None) '''Main Menu Tab of ContextMenu. :data:`main_tab` is a :class:`~kivy.properties.ObjectProperty`, default to None. ''' bubble_cls = ObjectProperty(MenuBubble) '''Bubble Class, whose instance will be used to create container of ContextMenu. :data:`bubble_cls` is a :class:`~kivy.properties.ObjectProperty`, default to :class:`MenuBubble`. ''' header_cls = ObjectProperty(MenuHeader) '''Header Class used to create Tab Header. :data:`header_cls` is a :class:`~kivy.properties.ObjectProperty`, default to :class:`MenuHeader`. ''' attach_to = ObjectProperty(allownone=True) '''(internal) Property that will be set to the widget on which the drop down list is attached to. The method :meth:`open` will automatically set that property, while :meth:`dismiss` will set back to None. ''' auto_width = BooleanProperty(True) '''By default, the width of the ContextMenu will be the same as the width of the attached widget. Set to False if you want to provide your own width. ''' dismiss_on_select = BooleanProperty(True) '''By default, the ContextMenu will be automatically dismissed when a selection have been done. Set to False to prevent the dismiss. :data:`dismiss_on_select` is a :class:`~kivy.properties.BooleanProperty`, default to True. ''' max_height = NumericProperty(None, allownone=True) '''Indicate the maximum height that the dropdown can take. If None, it will take the maximum height available, until the top or bottom of the screen will be reached. :data:`max_height` is a :class:`~kivy.properties.NumericProperty`, default to None. ''' __events__ = ('on_select', 'on_dismiss') def __init__(self, **kwargs): self._win = None self.add_tab = super(ContextMenu, self).add_widget self.bubble = self.bubble_cls(size_hint=(None, None)) self.container = None self.main_tab = self.header_cls(text='Main') self.main_tab.content = ScrollView(size_hint=(1, 1)) self.main_tab.content.bind(height=self.on_scroll_height) super(ContextMenu, self).__init__(**kwargs) self.bubble.add_widget(self) self.bind(size=self._reposition) self.bubble.bind(on_height=self._bubble_height) def _bubble_height(self, *args): '''Handler for bubble's 'on_height' event. ''' self.height = self.bubble.height def open(self, widget): '''Open the dropdown list, and attach to a specific widget. Depending the position of the widget on the window and the height of the dropdown, the placement might be lower or higher off that widget. ''' #ensure we are not already attached if self.attach_to is not None: self.dismiss() #we will attach ourself to the main window, so ensure the widget we are #looking for have a window self._win = widget.get_parent_window() if self._win is None: raise ContextMenuException( 'Cannot open a dropdown list on a hidden widget') self.attach_to = widget widget.bind(pos=self._reposition, size=self._reposition) self.add_tab(self.main_tab) self.switch_to(self.main_tab) self.main_tab.show_arrow = False self._reposition() # attach ourself to the main window self._win.add_widget(self.bubble) self.main_tab.color = (0, 0, 0, 0) def on_select(self, data): '''Default handler for 'on_select' event. ''' pass def dismiss(self, *largs): '''Remove the dropdown widget from the iwndow, and detach itself from the attached widget. ''' if self.bubble.parent: self.bubble.parent.remove_widget(self.bubble) if self.attach_to: self.attach_to.unbind(pos=self._reposition, size=self._reposition) self.attach_to = None self.switch_to(self.main_tab) for child in self.tab_list[:]: self.remove_widget(child) self.dispatch('on_dismiss') def select(self, data): '''Call this method to trigger the `on_select` event, with the `data` selection. The `data` can be anything you want. ''' self.dispatch('on_select', data) if self.dismiss_on_select: self.dismiss() def on_dismiss(self): '''Default event handler for 'on_dismiss' event. ''' pass def _set_width_to_bubble(self, *args): '''To set self.width and bubble's width equal. ''' self.width = self.bubble.width def _reposition(self, *largs): # calculate the coordinate of the attached widget in the window # coordinate sysem win = self._win widget = self.attach_to if not widget or not win: return wx, wy = widget.to_window(*widget.pos) wright, wtop = widget.to_window(widget.right, widget.top) # set width and x if self.auto_width: #Calculate minimum required width if len(self.container.children) == 1: self.bubble.width = max(self.main_tab.parent.parent.width, self.container.children[0].width) else: self.bubble.width = max( self.main_tab.parent.parent.width, self.bubble.width, *([i.width for i in self.container.children])) Clock.schedule_once(self._set_width_to_bubble, 0.01) # ensure the dropdown list doesn't get out on the X axis, with a # preference to 0 in case the list is too wide. x = wx if x + self.bubble.width > win.width: x = win.width - self.bubble.width if x < 0: x = 0 self.bubble.x = x #determine if we display the dropdown upper or lower to the widget h_bottom = wy - self.bubble.height h_top = win.height - (wtop + self.bubble.height) if h_bottom > 0: self.bubble.top = wy self.bubble.arrow_pos = 'top_mid' elif h_top > 0: self.bubble.y = wtop self.bubble.arrow_pos = 'bottom_mid' else: #none of both top/bottom have enough place to display the widget at #the current size. Take the best side, and fit to it. height = max(h_bottom, h_top) if height == h_bottom: self.bubble.top = wy self.bubble.height = wy self.bubble.arrow_pos = 'top_mid' else: self.bubble.y = wtop self.bubble.height = win.height - wtop self.bubble.arrow_pos = 'bottom_mid' def on_touch_down(self, touch): '''Default Handler for 'on_touch_down' ''' if super(ContextMenu, self).on_touch_down(touch): return True if self.collide_point(*touch.pos): return True self.dismiss() def on_touch_up(self, touch): '''Default Handler for 'on_touch_up' ''' if super(ContextMenu, self).on_touch_up(touch): return True self.dismiss() def add_widget(self, widget, index=0): '''Add a widget. ''' if self.tab_list and widget == self.tab_list[0].content or\ widget == self._current_tab.content or \ self.content == widget or\ self._tab_layout == widget or\ isinstance(widget, TabbedPanelContent) or\ isinstance(widget, TabbedPanelHeader): super(ContextMenu, self).add_widget(widget, index) return if not self.container: self.container = GridLayout(orientation='vertical', size_hint_y=None, cols=1) self.main_tab.content.add_widget(self.container) self.container.bind(height=self.on_main_box_height) self.container.add_widget(widget, index) if hasattr(widget, 'cont_menu'): widget.cont_menu = self widget.bind(height=self.on_child_height) widget.size_hint_y = None def remove_widget(self, widget): '''Remove a widget ''' if self.container and widget in self.container.children: self.container.remove_widget(widget) else: super(ContextMenu, self).remove_widget(widget) def on_scroll_height(self, *args): '''Event Handler for scollview's height. ''' if not self.container: return self.container.height = max(self.container.height, self.main_tab.content.height) def on_main_box_height(self, *args): '''Event Handler for main_box's height. ''' if not self.container: return self.container.height = max(self.container.height, self.main_tab.content.height) if self.max_height: self.bubble.height = min( self.container.height + self.tab_height + dp(16), self.max_height) else: self.bubble.height = self.container.height + \ self.tab_height + dp(16) def on_child_height(self, *args): '''Event Handler for children's height. ''' height = 0 for i in self.container.children: height += i.height self.main_tab.content.height = height self.container.height = height def add_tab(self, widget, index=0): '''To add a Widget as a new Tab. ''' super(ContextMenu, self).add_widget(widget, index)
def new_back(self): # Popup for changing backgrounds val = '180dp' self.popup = Popup(title='Choose background', auto_dismiss=True, size_hint=(0.95, 0.62), separator_color=(0, 0, 1, 1), title_align='center', title_color=(1, 1, 1, 1), title_size='16sp', title_font='fonts/Fcarbim.ttf') scroll = ScrollView() scroll.size_hint = (1, 1) scroll.do_scroll_x = False scroll.do_scroll_y = True grd = GridLayout(cols=3, spacing='3dp') grd.size_hint = (1, None) grd.bind(minimum_height=grd.setter('height')) but1 = ImageButton( source='boc/BackOfCards.png', on_release=lambda x: self.receive('boc/BackOfCards.png'), size_hint=(1, None), height=val) but2 = ImageButton( source='boc/BackOfCards1.png', on_release=lambda x: self.receive('boc/BackOfCards1.png'), size_hint=(1, None), height=val) but3 = ImageButton( source='boc/BackOfCards2.png', on_release=lambda x: self.receive('boc/BackOfCards2.png'), size_hint=(1, None), height=val) but4 = ImageButton( source='boc/BackOfCards3.png', on_release=lambda x: self.receive('boc/BackOfCards3.png'), size_hint=(1, None), height=val) but5 = ImageButton( source='boc/BackOfCards4.png', on_release=lambda x: self.receive('boc/BackOfCards4.png'), size_hint=(1, None), height=val) but6 = ImageButton( source='boc/BackOfCards5.png', on_release=lambda x: self.receive('boc/BackOfCards5.png'), size_hint=(1, None), height=val) grd.add_widget(but1) grd.add_widget(but2) grd.add_widget(but3) grd.add_widget(but4) grd.add_widget(but5) grd.add_widget(but6) scroll.add_widget(grd) self.popup.add_widget(scroll) self.popup.open()
def __init__(self, **kwargs): super(MoviesViewMain, self).__init__(**kwargs) Logger.info('MoviesViewMain: Initialized {}'.format(self)) self.name = 'movies view main screen' self.add_widget( Button(text='go to single movie', on_press=self.change_to_movies_single, size_hint_y=0.1)) movies_layout = GridLayout(cols=3, padding=50, spacing=50, size_hint=(None, None), width=ViewControl.width_x - 30) # when we add children to the grid layout, its size doesn't change at # all. we need to ensure that the height will be the minimum required # to contain all the childs. (otherwise, we'll child outside the # bounding box of the childs) movies_layout.bind(minimum_height=movies_layout.setter('height')) movies_scroll_list = ScrollView(size_hint=(None, None), size=(ViewControl.width_x - 20, ViewControl.height_x - 190), pos_hint={ 'center_x': .5, 'center_y': .5 }, do_scroll_x=False) movies_scroll_list.add_widget(movies_layout) # print(self.ids) self.ids.movies_view_main_container.add_widget(movies_scroll_list) # pippp = Shows(genre='animation', order='1', sort='name').get_search() # check_api_validity(pippp) # Logger.info(json.dumps(pippp.json(), sort_keys=True, indent=4)) # _items = Item() # _items.add_widget(AsyncImage(source=hashed_dic_grouop['6b43cd1e32c32983ff0b1a520812ecc7b008c32097ead5812168d33967246151']['images']['poster'])) # self.add_widget(_items) for kk in hashed_dic_movies: # print('{}----{}'.format(kk, hashed_dic_grouop[kk])) _items = Item(hashed_dic_movies[kk]['_id']) _items.size = ((Window.size[0] / 3) - 80, (Window.size[1] / 2) - 30) try: _items.add_widget( AsyncImage( source=hashed_dic_movies[kk]['images']['poster'], nocache=True)) except Exception as e: pass Logger.info('No image setting default cause of {}'.format(e)) _items.add_widget(Image(source='images/logo.png')) _items.add_widget( Label(text=hashed_dic_movies[kk]['title'], size_hint_y=.1, text_size=(250, None), shorten_from='right', halign='center', shorten=True)) _items.add_widget( Button(text='show', on_press=lambda x: self.change_to_movies_single( hashed_dic_movies[kk]['_id']))) movies_layout.add_widget(_items)
class ItemDisplay(GridLayout): ''' TODO: format buttons!!! -expiry date buttons mainly add good font add variable reading from Item Name, Quantity (Number) and Quantity (Units) -> then use that to make a new FridgeItem ->check if the item is valid by checking all 6 variables ^DONE make inputting text not make user have to backspace everything, and potentially make it all reset after clicking add item. add pop up keyboard when clicking on text areas (maybe already done?) confirm item deletion make each item button have a border color that is green if not expired, yellow if within a day or two of expiring, red if expired, and white (?) if no expiration date was etnered --- figure out date comparison for expiry dates delete items from list (open popup when selecting a button? maybe the popup has a delete button with all the detailed info) figure out how to get pictures for items edit item button in the Item popup need to figure out how to update item popups immediately after user clicks edit (the popup user returns to is incorrect) ->i added a little info label to tell the user that they need to re-open the item to see updated information. if i can figure out how to fix it, do that, but this is fine. add new markers for different things (low on quantity, custom marker by user, etc.) add custom marking system fix scrolling to see all of the items add a login screen with password? make it so that unless year and month are selected, the day button is disabled. (either visually via color, or actually disabled) things to add to FridgeItem: quantity units (string) date obtained (datetime object) -> figure out which variables are going to be optional ''' def __init__(self, **kwargs): super(ItemDisplay, self).__init__(**kwargs) self.cols = 1 self.padding = 5 #setting new item fields self.new_item_day = None self.new_item_month = None self.new_item_year = None self.new_item_name = None self.new_item_quantity = None self.new_item_quantity_units = None #setting up keyboard pop-up Config.set('kivy', 'keyboard_mode', 'systemandmulti') #adding test items """ for i in range(10): x = FridgeItem("Item" + str(i)); self.fridge.add_item(x); """ scroller = ScrollView() self.button_box = GridLayout(cols=2, padding=5, size_hint_x=1, size_hint_y=None) #made this self. so i can affect it in reload_item_selectors self.button_box.bind(minimum_height=self.button_box.setter('height')) scroller.add_widget(self.button_box) add_item_button = Button(text="Add Item!", size_hint_y=None, font_size="25sp") add_item_button.bind(on_press=self.add_item_popup) self.add_widget(add_item_button) #contents of add_item_popup used to be here #generating buttons for each item on the list self.reload_item_selectors() #item label item_label = Label(text="Items: (Try scrolling up and down!)", size_hint_y=None, font_size="20sp") self.add_widget(item_label) self.add_widget(scroller) def reload_item_selectors(self): """ Clears all buttons, then scans through the fridges' item_list and adds a button for each item. """ self.button_box.clear_widgets() i = 0 for item in fridge.item_list: button = Button(text=item.name + " - " + str(item.quantity) + " " + str(item.quantity_units), size_hint_y=None, font_size="25sp") button.id = str(i) button.bind(on_press=self.item_button_callback) days_until_item_expiry = item.get_days_until_expiration() button.background_color = (0.8, 0.8, 0.8, 1) #make item buttons with no Expiry value gray if (days_until_item_expiry is not None): if (days_until_item_expiry < 0): button.background_color = (1, 0, 0, 1) #item expired, make it red elif (days_until_item_expiry > 0 and days_until_item_expiry < 3): button.background_color = (1, 1, 0, 1) #item expires soon, make it yellow else: button.background_color = (0, 1, 0, 1) #item not expiring soon, make it green self.button_box.add_widget(button) i += 1 def item_button_callback(self, button): """ Triggers when user selects an item button. Loads a popup with specific item details as well as showing a Delete button. """ item = fridge.item_list[int(button.id)] popup_pane = BoxLayout(orientation="vertical") name_label = Label(text=item.name) quantity_label = Label(text=str(item.quantity) + " " + item.quantity_units) date_obtained_label = Label(text="Obtained on " + str(item.date_obtained)) expiry_label = Label(text="Expiration date: " + str(item.expiry)) date_explanation_label = Label(text="Dates are YY/MM/DD") #days until expiry label days_until_item_expiry = item.get_days_until_expiration() add_days_until_expiry_label = False if (days_until_item_expiry is not None): #expiration message add_days_until_expiry_label = True days_until_expiry_label = Label(text=str(days_until_item_expiry) + " days left", font_size="25sp") if (days_until_item_expiry < 0): #already expired message days_until_expiry_label.text = "Expired " + str( abs(days_until_item_expiry)) + " days ago!" days_until_expiry_label.color = (1, 0, 0, 1) #item expired, make it red elif (days_until_item_expiry > 0 and days_until_item_expiry < 3): days_until_expiry_label.color = (1, 1, 0, 1) #item expires soon, make it yellow else: days_until_expiry_label.color = (0, 1, 0, 1) #item not expiring soon, make it green """ part of old expiry label expired_code_dict = { -1: "No Expiry Date Entered", 0: "Not Expired", 1: "Expired!" }; expired_code = item.is_expired(); expired = expired_code_dict.get(expired_code); expired_label= Label(text="Expired?: " + str(expired)); """ item_delete_button = Button(text="Delete this Item", id=button.id) #passing button id (item index) to the delete callback #item_delete_button.bind(on_press=self.delete_item_callback); item_delete_button.bind(on_press=self.delete_item_confirm) popup_pane.add_widget(item_delete_button) popup_pane.add_widget(name_label) popup_pane.add_widget(quantity_label) popup_pane.add_widget(date_obtained_label) popup_pane.add_widget(expiry_label) """ part of old expiry label if(expired_code > -1): #hiding the expired label if no expiration date was entered popup_pane.add_widget(expired_label); """ if (add_days_until_expiry_label): popup_pane.add_widget(days_until_expiry_label) popup_pane.add_widget(date_explanation_label) #edit item button item_edit_button = Button(text="Edit this Item", id=button.id) item_edit_button.bind(on_press=self.edit_item_popup) popup_pane.add_widget(item_edit_button) popup_close_button = Button(text="Close") popup_pane.add_widget(popup_close_button) popup = Popup(title="Fridge Item Information", content=popup_pane, size_hint=(0.6, 0.6)) popup_close_button.bind(on_press=popup.dismiss) item_delete_button.bind(on_release=popup.dismiss) popup.open() def generate_item_detail_popup(self, item_index=None): """ The popup used by add_item_popup and edit_item_popup. Abstracts the code so I don't write it twice. If item_id is None, then this function will produce the add_item_popup. If item_id is defined, then this function will autofill the fields of the popup with the item details. """ #add item panel popup_pane = GridLayout(cols=1, padding=10) #1 column. everything will be stacked. name_input_pane = BoxLayout(orientation="horizontal") #label then textinput quantity_number_input_pane = BoxLayout(orientation="horizontal") #label then textinput quantity_units_input_pane = BoxLayout(orientation="horizontal") #label then textinput popup_pane.add_widget(name_input_pane) popup_pane.add_widget(quantity_number_input_pane) popup_pane.add_widget(quantity_units_input_pane) #The name input row name_input_label = Label(text="Item Name: ") name_input_text_input = TextInput(text="", multiline=False, font_size="30sp", halign="center") name_input_text_input.bind(text=self.name_input_callback) name_input_pane.add_widget(name_input_label) name_input_pane.add_widget(name_input_text_input) #The quantity number input row quantity_number_input_label = Label( text="Quantity Number: (Can be decimal, e.g. 4, 12, 1.5, etc.)") quantity_number_input_text_input = TextInput(text="", input_filter="float", multiline=False, font_size="30sp", halign="center") quantity_number_input_text_input.bind( text=self.quantity_input_callback) quantity_number_input_pane.add_widget(quantity_number_input_label) quantity_number_input_pane.add_widget(quantity_number_input_text_input) #The quantity units input row quantity_units_input_label = Label( text="Quantity Units: (A word or two, e.g. cartons, ounces, etc.)") quantity_units_input_text_input = TextInput(text="", multiline=False, font_size="30sp", halign="center") quantity_units_input_text_input.bind( text=self.quantity_units_input_callback) quantity_units_input_pane.add_widget(quantity_units_input_label) quantity_units_input_pane.add_widget(quantity_units_input_text_input) #expiry date optional label add_item_expiry_row_label = Label( text="Optional: (select none or all 3)") popup_pane.add_widget(add_item_expiry_row_label) #expiry date row (month: day: year: ; a row of 3 cols of text entries) add_item_expiry_date_pane = GridLayout(cols=3) popup_pane.add_widget(add_item_expiry_date_pane) #expiry month months = ("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December") add_item_expiry_month_input = Spinner(text="Month", values=months) add_item_expiry_month_input.bind(text=self.month_input_callback) #triggers a callback whenever a value is selected add_item_expiry_date_pane.add_widget(add_item_expiry_month_input) #expiry day self.days = ("Day - Pick a month first", "If you want February 29,", "pick a leap year first") #set blank by default, updates when month is selected self.add_item_expiry_day_input = Spinner(text="Day", values=self.days) #made self. to target from day_update_on_month_input self.add_item_expiry_day_input.bind(on_press=self.day_update_callback) #updating day list whenever user clicks on it self.add_item_expiry_day_input.bind(text=self.day_input_callback) #saving day value user selects self.add_item_expiry_day_input.color = (0, 0, 0, 0.2) #making the day color dark as if it's disabled self.add_item_expiry_day_input.disabled = True #actually disabling the button add_item_expiry_date_pane.add_widget(self.add_item_expiry_day_input) #expiry year #generating year options right_now = datetime.date.today() current_year = right_now.year #print(current_year); year_gen = [] year_range = 15 #giving a range of now to 15 years from now. for i in range(0, year_range + 1): year_gen.append(str(current_year + i)) years = tuple(year_gen) add_item_expiry_year_input = Spinner(text="Year", values=years) add_item_expiry_year_input.bind(text=self.year_input_callback) add_item_expiry_date_pane.add_widget(add_item_expiry_year_input) #date input info label date_input_info_label = Label( text="To make things easy, first enter Year, then Month, then Day." ) popup_pane.add_widget(date_input_info_label) #resetting date variables because they persist through item creation self.new_item_day = None self.new_item_month = None self.new_item_year = None #Add Item button add_item_button = Button(text="Add Item!", size_hint_y=None, font_size="25sp") #default is 15sp add_item_button.bind(on_press=self.save_item) popup_pane.add_widget(add_item_button) popup = Popup(title="Add an Item", content=popup_pane) #add_item_button.bind(on_release=popup.dismiss); #add popup close button popup_pane_close_button = Button(text="Cancel") popup_pane_close_button.bind(on_press=popup.dismiss) popup_pane.add_widget(popup_pane_close_button) #autofilling - this is an edit popup if (item_index is not None): popup.title = "Edit an Item" item = fridge.item_list[int(item_index)] #the id is actually the index of the item in the item list name_input_text_input.text = item.name quantity_number_input_text_input.text = str(item.quantity) quantity_units_input_text_input.text = item.quantity_units expiry_date = item.expiry if (expiry_date is not None): month = expiry_date.month month_str = months[month - 1] #subtracting 1 because the index of january is 0 (value of january is 1) day = expiry_date.day year = expiry_date.year add_item_expiry_year_input.text = str(year) add_item_expiry_month_input.text = month_str self.add_item_expiry_day_input.disabled = False #enabling the day button for items who already have a day value self.add_item_expiry_day_input.text = str(day) add_item_button.text = "Save Item Changes!" add_item_button.id = item_index #passing item index so it can be used by save_item add_item_button.bind(on_press=self.save_item) return popup def add_item_popup(self, button): """ When the Add Item button is pressed, show a popup with TextInputs and another button to add it, with another button to cancel. """ popup = self.generate_item_detail_popup() popup.open() def delete_item_confirm(self, button): """ Pops up a "Are you sure?" prompt which the user must accept to delete the item. """ confirmation_popup_pane = BoxLayout(orientation="vertical") confirmation_label = Label(text="Are you sure?") options_pane = GridLayout(cols=2) yes_button = Button(text="Yes", id=button.id) #passing the item id to delete_item_callback no_button = Button(text="No") options_pane.add_widget(yes_button) options_pane.add_widget(no_button) confirmation_popup_pane.add_widget(confirmation_label) confirmation_popup_pane.add_widget(options_pane) confirmation_popup = Popup(title="Delete this Item", content=confirmation_popup_pane, size_hint=(0.5, 0.5)) no_button.bind(on_press=confirmation_popup.dismiss) yes_button.bind(on_press=self.delete_item_callback) yes_button.bind(state=confirmation_popup.dismiss) confirmation_popup.open() def delete_item_callback(self, button): """ Triggered when user selects the Delete button in an Item popup and confirms the deletion. Deletes the item from the fridge's item_list, then reloads buttons. """ item_index = int(button.id) fridge.item_list.pop(item_index) self.reload_item_selectors() def save_item(self, button): """ Checks validity of the 6 new_item variables. If any are invalid, show a popup detailing the error. Otherwise, create the new_item. If an item_index is not specified within button.id, add it to the fridge.item_list. Otherwise, set the item at the specified index to this new item. """ #first, check if all variables are defined. then create the fridge item and add it. errors = [] if (self.new_item_name is None or self.new_item_name == ""): errors.append("Name") if (self.new_item_quantity is None): errors.append("Quantity") if ( self.new_item_quantity_units is None or self.new_item_quantity_units == "" or self.new_item_quantity_units == "Quantity (Units)" ): #need this special check because the quantity units is set to Quantity (Units) by default for some reason errors.append("Quantity Units") #not error checking date vars because they're optional """ if(self.new_item_month is None): errors.append("Month"); if(self.new_item_day is None): errors.append("Day"); if(self.new_item_year is None): errors.append("Year"); """ if ( len(errors) > 0 ): #errors - not all vars were properly defined. open a popup showing which were wrong. error_message = ", ".join(errors) error_label = Label(text="Invalid: " + error_message) popup_close_button = Button(text="Close this popup") popup_pane = BoxLayout(orientation="vertical") popup_pane.add_widget(error_label) popup_pane.add_widget(popup_close_button) error_popup = Popup(title="Invalid Item Entry", content=popup_pane, size_hint=(0.6, 0.6)) #size_hint resizes popup popup_close_button.bind(on_press=error_popup.dismiss) error_popup.open() else: #continue with adding item if ( self.new_item_month is None or self.new_item_day is None or self.new_item_year is None ): #if any part of the date is invalid, don't create a datetime object. expiry = None else: #if every part of the date entry is valid, then make a datetime object and use that. expiry = datetime.date(self.new_item_year, self.new_item_month + 1, self.new_item_day) #month is +1 because i need to go from 0..11 to 1..12 item = FridgeItem(self.new_item_name, expiry_date=expiry, quantity=self.new_item_quantity, quantity_units=self.new_item_quantity_units) success_popup_pane = BoxLayout(orientation="vertical") success_label = Label( text="Item added successfully! Exit the Add Item Menu.") success_popup_pane.add_widget(success_label) success_popup_close_button = Button(text="Close", size_hint_y=None) success_popup_pane.add_widget(success_popup_close_button) success_popup = Popup(title="Success!", content=success_popup_pane, size_hint=(0.6, 0.6)) success_popup_close_button.bind(on_press=success_popup.dismiss) print_log = "Item added: %s" if (button.id is None): fridge.add_item(item) else: item_index = int(button.id) fridge.item_list[item_index] = item success_label.text = "Item added successfully! Exit the Edit Item Menu.\nChanges won't be updated until you \nclose the Item Information Menu and re-open it." print_log = "Item changed: %s" print(print_log % item) success_popup.open() self.reload_item_selectors() def edit_item_popup(self, button): """ Triggers whenever the user selects the Edit Item option within the item button popup. Opens the edit_item popup. """ popup = self.generate_item_detail_popup(button.id) #passing id to the generator so it autofills with the item's details popup.open() def name_input_callback(self, text_input, text): """ Triggers whenever the new item name TextInput receives new input. Saves the input to a variable, self.new_item_name. """ self.new_item_name = text print("New Item Name updated: %s" % text) def quantity_input_callback(self, text_input, text): """ Triggers whenever the new item quantity TextInput receives new input. If the input is a float, save it. """ if (text == ""): self.new_item_quantity = None #making a blank text field set the quantity to None, it makes more sense print("New Item Quantity reset: %s" % str(self.new_item_quantity)) return try: float(text) except: return else: self.new_item_quantity = float(text) print("New Item Quantity updated: %s" % text) def quantity_units_input_callback(self, text_input, text): """ Triggers whenever the new item quantity units TextInput receives new input. Saves the input to a variable, self.new_item_quantity_units. """ self.new_item_quantity_units = text print("New Item Quantity Units updated: %s" % text) def month_input_callback(self, spinner, text): """ Triggers whenever user selects a different month on the month drop down. Sets self.month value. """ month_day_count = { "January": 31, "February": 28, "March": 31, "April": 30, "May": 31, "June": 30, "July": 31, "August": 31, "September": 30, "October": 31, "November": 30, "December": 31 } self.new_item_month = int(list(month_day_count.keys()).index(text)) #turning dict keys into a list and scanning it for the month number of the input text day_count = month_day_count.get(text) days_gen = [] for i in range(1, day_count + 1): days_gen.append(str(i)) days = tuple(days_gen) self.days = days self.day_update_on_date_input() #resets day selection on month select self.day_range_update_on_date_input() #calls function to attempt leap year check spinner.color = (0, 1, 0, 1) #makes the spinner green print("Month selected: %d" % self.new_item_month) def day_range_update_on_date_input(self, *args): """ Triggers whenever user selects a year/month. If the month selected is February, adds 29 to February's day options on leap years. Also, if the selected day is February 29 and the user switches off of a leap year, the selected day switches to February 28. """ #checks if year and month are selected. if so, run leap year check. if (self.new_item_year is not None and self.new_item_month is not None): if (self.new_item_year % 4 == 0 and self.new_item_month == 1): #1 = index of february days_list = list(self.days) days_list.append("29") #adds 29 as a day option in February to leap years. self.days = tuple(days_list) print("Leap year day added.") elif (self.days[len(self.days) - 1] == "29"): self.days = self.days[:-1] #removes 29 when returning to non-leap years if (self.add_item_expiry_day_input.text == "29"): self.add_item_expiry_day_input.text = "28" #automatically unsetting day from 29 if switching away from a leap year. def day_update_on_date_input(self, *args): """ Triggers whenever user selects a month. Resets the day so that no issue where the day doesn't exist for that month occurs. (e.g. Feb 31) """ self.add_item_expiry_day_input.color = (1, 1, 1, 1) #making the day button color white, as if enabling it self.add_item_expiry_day_input.disabled = False #actually enabling the button self.new_item_day = None #undefine day because it needs to be re-picked print("Reset selected day.") def day_update_callback(self, instance): """ Triggers whenever user clicks on the Days spinner. Updates the options and resets the selected option. """ instance.values = self.days days_length = len(self.days) #print(days_length); print(self.days) if ( days_length > 2 ): #checking if self.days holds the range of days instead of just "Pick a month" if (instance.text.isnumeric()): if ( int(instance.text) > int(self.days[days_length - 1]) ): #resets day so if I switch from March to February and I selected 30 it switches to the new max as a sort of error protection, instance.text = self.days[days_length - 1] print("Day menu updated") def day_input_callback(self, spinner, text): """ Triggers whenever user selects a day. Sets self.day value. """ if (text.isnumeric()): #if the day isn't a number, dont save it self.new_item_day = int(text) spinner.color = (0, 1, 0, 1) #makes the spinner green print("Day selected: %d" % self.new_item_day) def year_input_callback(self, spinner, text): """ Triggers whenever user selects a year. Sets self.year value. Checks if the year is divisible by 4. If so, and the month selected is February, reset the day value and change it's range to 1-29. The spinner becomes green once the user selects an option. """ self.new_item_year = int(text) self.day_range_update_on_date_input() #calls function to attempt leap year check spinner.color = (0, 1, 0, 1) #makes the spinner green print("Year selected: %d" % self.new_item_year)
class client_view(GridLayout):#innherit class GridLayout def __init__(self, **kwargs):#defining constructor for class page super().__init__(**kwargs)#defining constructor for class GridLayout self.rows = 4 self.cols = 1 top = GridLayout(rows=1, size_hint_y=0.08) revenue_button = Button(text = 'Revenue') revenue_button.bind(on_press = self.revenue_button_pressed) expense_button = Button(text = 'Expense') expense_button.bind(on_press = self.expense_button_pressed) assets_button = Button(text = 'Assets') assets_button.bind(on_press = self.assets_button_pressed) liabilities_button = Button(text = 'Liabilities') liabilities_button.bind(on_press = self.liabilities_button_pressed) search_button = Button(text = 'Search') search_button.bind(on_press = self.search_pressed) top.add_widget(revenue_button) top.add_widget(expense_button) top.add_widget(assets_button) top.add_widget(liabilities_button) top.add_widget(Label()) top.add_widget(Label()) top.add_widget(Label()) top.add_widget(search_button) self.add_widget(top) self.head = GridLayout(rows=1, size_hint_y=0.08) self.add_widget(self.head) self.root = ScrollView() self.root.bar_width = 10 self.add_widget(self.root) self.layout = GridLayout(cols=6, spacing=10, size_hint_y=None) self.layout.bind(minimum_height=self.layout.setter('height')) self.root.add_widget(self.layout) back = Button(text = 'Back', size_hint_y=None, height = 20) back.bind(on_press = self.back_pressed) self.add_widget(back) def revenue_button_pressed(self, instance): self.head.clear_widgets() self.layout.clear_widgets() self.head.add_widget(Label(text = "Amount")) self.head.add_widget(Label(text = "Cashflow ID")) self.head.add_widget(Label(text = "Tax Rate")) self.head.add_widget(Label(text = "Time Stamp")) self.head.add_widget(Label(text = "Tax Payed?")) self.head.add_widget(Label(text = "Download documents")) sql.execute(f"select distinct k.AMOUNT, k.CASHFLOW_ID, s.TAX, k.DATE_TIME, k.TAX_PAYED, k.ID from keep_in_book k, client c, source_of_cashflow s where k.amount>0 AND k.CASHFLOW_ID = s.CASHFLOW_ID AND c.BOOK_NO = k.BOOK_NO AND c.CLIENT_ID = '{cid}' ORDER BY k.DATE_TIME DESC") cashflows = sql.fetchall() for cashflow in cashflows: amount_label = Label(text = f"{cashflow[0]}", size_hint_y=None, height=40) self.layout.add_widget(amount_label) cashflow_label = Label(text = f"{cashflow[1]}", size_hint_y=None, height=40) self.layout.add_widget(cashflow_label) tax_label = Label(text = f"{cashflow[2]}", size_hint_y=None, height=40) self.layout.add_widget(tax_label) date_time_label = Label(text = f'{cashflow[3].strftime("%d-%m-%Y %H:%M")}', size_hint_y=None, height=40) self.layout.add_widget(date_time_label) if cashflow[4]: tax_payed_label = Label(text = "Yes", size_hint_y=None, height=40) else: tax_payed_label = Label(text = "No", size_hint_y=None, height=40) self.layout.add_widget(tax_payed_label) download_button = Button(text = "Download File", size_hint_y=None, height=40) # lam = lambda c = cashflow[-1]: self.download_button_pressed(c) download_button.bind(on_press = lambda instance, c = cashflow[-1]: self.download_button_pressed(c)) # download_button.bind(on_press = lambda instance: lambda c = cashflow[-1]: print(c)) self.layout.add_widget(download_button) def expense_button_pressed(self, instance): self.head.clear_widgets() self.layout.clear_widgets() self.head.add_widget(Label(text = "Amount")) self.head.add_widget(Label(text = "Cashflow ID")) self.head.add_widget(Label(text = "Tax Rate")) self.head.add_widget(Label(text = "Time Stamp")) self.head.add_widget(Label(text = "Tax Payed?")) self.head.add_widget(Label(text = "Download documents")) # self.layout = GridLayout(cols=6, spacing=10, size_hint_y=None) # self.layout.bind(minimum_height=self.layout.setter('height')) sql.execute(f"select distinct k.AMOUNT, k.CASHFLOW_ID, s.TAX, k.DATE_TIME, k.TAX_PAYED, k.ID from keep_in_book k, client c, source_of_cashflow s where k.amount<0 AND k.CASHFLOW_ID = s.CASHFLOW_ID AND c.BOOK_NO = k.BOOK_NO AND c.CLIENT_ID = '{cid}' ORDER BY k.DATE_TIME DESC") cashflows = sql.fetchall() for cashflow in cashflows: amount_label = Label(text = f"{cashflow[0]}", size_hint_y=None, height=40) self.layout.add_widget(amount_label) cashflow_label = Label(text = f"{cashflow[1]}", size_hint_y=None, height=40) self.layout.add_widget(cashflow_label) tax_label = Label(text = f"{cashflow[2]}", size_hint_y=None, height=40) self.layout.add_widget(tax_label) date_time_label = Label(text = f'{cashflow[3].strftime("%d-%m-%Y %H:%M")}', size_hint_y=None, height=40) self.layout.add_widget(date_time_label) if cashflow[4]: tax_payed_label = Label(text = "Yes", size_hint_y=None, height=40) else: tax_payed_label = Label(text = "No", size_hint_y=None, height=40) self.layout.add_widget(tax_payed_label) download_button = Button(text = "Download File", size_hint_y=None, height=40) download_button.bind(on_press = lambda instance, c = cashflow[-1]: self.download_button_pressed(c)) self.layout.add_widget(download_button) def assets_button_pressed(self, instance): self.head.clear_widgets() self.layout.clear_widgets() self.head.add_widget(Label(text = "Amount")) self.head.add_widget(Label(text = "Download documents")) sql.execute(f"select distinct a.AMOUNT, a.ID from keep_in_book k, client c, asset a where k.ID = a.ID AND c.BOOK_NO = k.BOOK_NO AND c.CLIENT_ID = '{cid}'") cashflows = sql.fetchall() for cashflow in cashflows: self.layout.add_widget(Label()) amount_label = Label(text = f"{cashflow[0]}", size_hint_y=None, height=40) self.layout.add_widget(amount_label) self.layout.add_widget(Label()) self.layout.add_widget(Label()) # print("cashflow[-1] = " ,cashflow[-1]) download_button = Button(text = "Download File", size_hint_y=None, height=40) download_button.bind(on_press = lambda instance, c = cashflow[-1]: self.download_button_pressed(c)) self.layout.add_widget(download_button) self.layout.add_widget(Label()) def liabilities_button_pressed(self, instance): self.head.clear_widgets() self.layout.clear_widgets() self.head.add_widget(Label(text = "Amount")) self.head.add_widget(Label(text = "Download documents")) sql.execute(f"select distinct l.AMOUNT, l.ID from keep_in_book k, client c, liability l where k.ID = l.ID AND c.BOOK_NO = k.BOOK_NO AND c.CLIENT_ID = '{cid}'") cashflows = sql.fetchall() for cashflow in cashflows: self.layout.add_widget(Label()) amount_label = Label(text = f"{cashflow[0]}", size_hint_y=None, height=40) self.layout.add_widget(amount_label) self.layout.add_widget(Label()) self.layout.add_widget(Label()) download_button = Button(text = "Download File", size_hint_y=None, height=40) download_button.bind(on_press = lambda instance, c = cashflow[-1]: self.download_button_pressed(c)) self.layout.add_widget(download_button) self.layout.add_widget(Label()) def download_button_pressed(self, id): print("Received ID = ", id) doc = db['files'].find_one({'_id':ObjectId(id)}) with open('C:\\Users\\anshs\\Desktop\\DOCUMENT'+doc['extension'], 'wb') as file: file.write(doc['file_data']) def search_pressed(self, instance): client_search_launch(cid, app, 'client_search_screen') def back_pressed(self, instance): app.screenmanager.current = 'client_main_menu_screen'
class ContextSubMenu(MenuButton): '''ContextSubMenu class. To be used to add a sub menu. ''' attached_menu = ObjectProperty(None) '''(internal) Menu attached to this sub menu. :data:`attached_menu` is a :class:`~kivy.properties.ObjectProperty`, default to None. ''' cont_menu = ObjectProperty(None) '''(internal) Reference to the main ContextMenu. :data:`cont_menu` is a :class:`~kivy.properties.ObjectProperty`, default to None. ''' container = ObjectProperty(None) '''(internal) The container which will be used to contain Widgets of main menu. :data:`container` is a :class:`~kivy.properties.ObjectProperty`, default to :class:`~kivy.uix.boxlayout.BoxLayout`. ''' show_arrow = BooleanProperty(False) '''(internal) To specify whether ">" arrow image should be shown in the header or not. If there exists a child menu then arrow image will be shown otherwise not. :data:`show_arrow` is a :class:`~kivy.properties.BooleanProperty`, default to False ''' def __init__(self, **kwargs): super(ContextSubMenu, self).__init__(**kwargs) self._list_children = [] def on_text(self, *args): '''Default handler for text. ''' if self.attached_menu: self.attached_menu.text = self.text def on_attached_menu(self, *args): '''Default handler for attached_menu. ''' self.attached_menu.text = self.text def add_widget(self, widget, index=0): '''Add a widget. ''' if isinstance(widget, Image): Button.add_widget(self, widget, index) return self._list_children.append((widget, index)) if hasattr(widget, 'cont_menu'): widget.cont_menu = self.cont_menu def on_cont_menu(self, *args): '''Default handler for cont_menu. ''' self._add_widget() def _add_widget(self, *args): if not self.cont_menu: return if not self.attached_menu: self.attached_menu = self.cont_menu.header_cls(text=self.text) self.attached_menu.content = ScrollView(size_hint=(1, 1)) self.attached_menu.content.bind(height=self.on_scroll_height) self.container = GridLayout(orientation='vertical', size_hint_y=None, cols=1) self.attached_menu.content.add_widget(self.container) self.container.bind(height=self.on_container_height) for widget, index in self._list_children: self.container.add_widget(widget, index) widget.cont_menu = self.cont_menu widget.bind(height=self.on_child_height) def on_scroll_height(self, *args): '''Handler for scrollview's height. ''' self.container.height = max(self.container.height, self.attached_menu.content.height) def on_container_height(self, *args): '''Handler for container's height. ''' self.container.height = max(self.container.height, self.attached_menu.content.height) def on_child_height(self, *args): '''Handler for children's height. ''' height = 0 for i in self.container.children: height += i.height self.container.height = height def on_release(self, *args): '''Default handler for 'on_release' event. ''' if not self.attached_menu or not self._list_children: return try: index = self.cont_menu.tab_list.index(self.attached_menu) self.cont_menu.switch_to(self.cont_menu.tab_list[index]) tab = self.cont_menu.tab_list[index] if hasattr(tab, 'show_arrow') and index != 0: tab.show_arrow = True else: tab.show_arrow = False except: curr_index = self.cont_menu.tab_list.index( self.cont_menu.current_tab) for i in range(curr_index - 1, -1, -1): self.cont_menu.remove_widget(self.cont_menu.tab_list[i]) self.cont_menu.add_tab(self.attached_menu) self.cont_menu.switch_to(self.cont_menu.tab_list[0]) if hasattr(self.cont_menu.tab_list[1], 'show_arrow'): self.cont_menu.tab_list[1].show_arrow = True else: self.cont_menu.tab_list[1].show_arrow = False from kivy.clock import Clock Clock.schedule_once(self._scroll, 0.1) def _scroll(self, dt): '''To scroll ContextMenu's strip to appropriate place. ''' from kivy.animation import Animation self.cont_menu._reposition() total_tabs = len(self.cont_menu.tab_list) tab_list = self.cont_menu.tab_list curr_index = total_tabs - tab_list.index(self.cont_menu.current_tab) to_scroll = len(tab_list) / curr_index anim = Animation(scroll_x=to_scroll, d=0.75) anim.cancel_all(self.cont_menu.current_tab.parent.parent) anim.start(self.cont_menu.current_tab.parent.parent)
import kivy kivy.require('1.11.1') # replace with your current kivy version ! from kivy.app import App from kivy.uix.gridlayout import GridLayout from kivy.uix.floatlayout import FloatLayout from kivy.uix.label import Label from kivy.uix.textinput import TextInput from kivy.uix.button import Button from kivy.uix.scrollview import ScrollView from dbConn import * from kivy.app import runTouchApp from kivy.core.window import Window layout = GridLayout(cols=1, spacing=10, size_hint_y=None) # Make sure the height is such that there is something to scroll. layout.bind( minimum_height=layout.setter('height')) # ******必须指定.................. print(layout.setter('height')) for i in range(100): btn = Button(text=str(i), size_hint_y=None, height=40) layout.add_widget(btn) root = ScrollView(size_hint=(1, None), size=(Window.width, Window.height)) root.add_widget(layout) runTouchApp(root)
class Spotlight(App): ''' This class represents the kivy app that will run the spotlight ''' def __init__(self, **kwargs): super(Spotlight, self).__init__(**kwargs) # fixed width of the app, will never change self._width = kwargs.get('width', 500) # tells how many entries can be displayed on the screen at the same time. The rest will be accessible via a scroller self._max_results_displayed = kwargs.get('max_results_displayed', 5) # gives the height of the separators that will be used between each entry self._sep_height = kwargs.get('sep_height', 1) # static height of the main search bar: SearchInput self._search_field_height = kwargs.get('search_field_height', 35) # height of each entry self._result_height = kwargs.get('result_height', 25) # this is the spacing between the search bar and the scroller containing the entries self._spacing = kwargs.get('spacing', 1) # this is the padding of the main window self._padding = 5 # this is the space between each separator/result in the dropdown list self._result_spacing = kwargs.get('result_spacing', 1) # color of a non-selected entry self._inactive_button_color = (.0, .0, .0, 0) # color of a selected entry self._active_button_color = (.4, .4, .4, 1) # store all the visible entries on the screen as a pair (button, separator) for convenience self._results = [] # index of the result that is currently highlighted self._highlight_index = -1 # these 3 variables are the 3 callbacks that the controller can input self._on_build = None self._on_enter = None self._on_text = None # this field holds a preset number of buttons for efficiency self._button_pool = [] # parse the callbacks passed in the constructor self.user_bind(**kwargs) self.build_window() # update the window size self.update_window() def user_bind(self, **kwargs): ''' this function saves the callbacks passed to this function into the 3 available holders ''' # this event is triggered when the application is drawn for the first time self._on_build = kwargs.get('on_build', self._on_build) # this event is triggered when the user presses enter self._on_enter = kwargs.get('on_enter', self._on_enter) # this even is triggered whenever the text in the search field is changed self._on_text = kwargs.get('on_text', self._on_text) def on_start(self): ''' when the window is drawn and the application started we update the size of the window ''' self.update_window() def build_window(self): ''' this function builds the whole app ''' self._search_field = SearchInput(multiline=False, focus=True, realdonly=False, height=self._search_field_height, size_hint=(1, None), markup=True, valign='middle', font_size=20, font_name='data/fonts/DejaVuSans.ttf') self._search_field.bind(focus=self._on_focus) self._search_field._keyboard.bind(on_key_down=self._on_keyboard_down) self._search_field.background_active = '' self._search_field.font_size = 20 self._search_field.bind(on_text_validate=self._on_text_validate) self._search_field.bind(text=self._on_new_text) self._search_field.text = '' self._drop_down_list = GridLayout(cols=1, width=self._width, spacing=self._result_spacing, size_hint=(None, None)) self._drop_down_list.bind( minimum_height=self._drop_down_list.setter('height')) self._scroller = ScrollView(scroll_distance=10, scroll_type=['bars'], do_scroll_x=False, bar_width=10, size_hint=(1, 1)) self._scroller.add_widget(self._drop_down_list) self._layout = ColoredGridLayout(cols=1, width=self._width, height=self._search_field_height, padding=(self._padding, self._padding), spacing=self._spacing * 2) self._layout.add_widget(self._search_field) self._layout.add_widget(self._scroller) if self._on_build: self._on_build() return self._layout def build(self): return self._layout def _unbind_all(self): self._search_field.unbind(focus=self._on_focus) self._search_field._keyboard.unbind(on_key_down=self._on_keyboard_down) self._search_field.unbind(on_text_validate=self._on_text_validate) self._search_field.unbind(text=self._on_new_text) self._drop_down_list.unbind( minimum_height=self._drop_down_list.setter('height')) for btn in self._button_pool: btn.unbind(width=button_width_setter) btn.unbind(on_press=self._on_click) btn.unbind(texture_size=btn.setter('text_size')) def _on_new_text(self, value, text): if self._on_text: self._on_text(self, value, text) def _on_text_validate(self, value): ''' when the user pressed enter, we forward the callback to the controller with the current hightlight index ''' if self._on_enter: ret = self._on_enter(value, self._highlight_index) if ret: self._unbind_all() self.stop() def _on_focus(self, instance, value): ''' this function is called whenever the focus of the search field changes. We do NOT allow defocus ''' if not value: self._search_field.focus = True # since the search field has to re-claim the keyboard, we re-bind our callback self._search_field._keyboard.bind( on_key_down=self._on_keyboard_down) def update_window(self, *args): ''' based on the current amount of entries shown, we adapt the size of the window ''' result_count = len(self._results) win_width = 2 * self._padding + self._width win_height = 2 * self._padding + self._search_field_height + self._spacing + ( self._result_spacing * 2 + self._result_height + self._sep_height) * result_count max_height = 2 * self._padding + self._search_field_height + self._spacing + ( self._result_spacing * 2 + self._result_height + self._sep_height) * self._max_results_displayed if self._app_window: self._app_window.size = win_width, min(win_height, max_height) def _on_keyboard_down(self, keyboard, keycode, text, modifiers): ''' we handle 3 keys: up (resp. down) to hightlight the entry above (resp. below) and escape to quit the application ''' if keycode[1] == 'up': self._highlight_up() elif keycode[1] == 'down': self._highlight_down() elif keycode[1] == 'escape': keyboard.release() self._unbind_all() self.stop() else: # mark the key press as not handled return False # mark the key press as handled return True def pre_allocate(self, number): self._button_pool = [] for _ in range(0, number): btn = Button(text='str', height=self._result_height, size_hint=(1, None), valign='middle', halign='left', background_color=self._inactive_button_color, markup=True, padding_x=0) btn.bind(width=button_width_setter) btn.bind(on_press=self._on_click) btn.bind(texture_size=btn.setter('text_size')) btn.background_normal = '' btn.background_down = btn.background_normal self._button_pool.append(btn) def _build_button(self): if self._button_pool: return self._button_pool.pop() btn = Button(text='str', height=self._result_height, size_hint=(1, None), valign='middle', halign='left', background_color=self._inactive_button_color, markup=True, padding_x=0) btn.bind(width=button_width_setter) btn.bind(on_press=self._on_click) btn.bind(texture_size=btn.setter('text_size')) btn.background_normal = '' btn.background_down = btn.background_normal return btn def _release_button(self, btn): btn.background_color = self._inactive_button_color self._button_pool.append(btn) def add_result(self, str, redraw=True): ''' add a new entry to the dropdown list; an index is returned ''' btn = self._build_button() btn.text = str sep = Separator(height=self._sep_height) self._drop_down_list.add_widget(sep) self._drop_down_list.add_widget(btn) self._results.append((btn, sep)) # we reset the highlight self._highlight_reset() if redraw: self.update_window() return len(self._results) - 1 def get_result(self, idx): ''' get a button object from an index - returned from a previous call to add_result ''' if not idx < len(self._results) or not idx >= 0: return e, _ = self._results[idx] return e def remove_result(self, idx, redraw=True): ''' remove a result object from its index - returned from a previous call to add_result ''' if not idx < len(self._results) or not idx >= 0: return e, sep = self._results[idx] if sep: self._drop_down_list.remove_widget(sep) self._drop_down_list.remove_widget(e) self._results.remove((e, sep)) self._release_button(e) # we reset the highlight self._highlight_reset() # resize the window accordingly if redraw: self.update_window() def clear_results(self, redraw=True): ''' clear all the results ''' for e, sep in self._results: self._release_button(e) self._drop_down_list.clear_widgets() self._results = [] # we reset the highlight self._highlight_reset() # resize the window accordingly if redraw: self.update_window() def _on_click(self, instance): ''' this callback is called whenever a click on a result is done; the highlight is adapted ''' for i in range(0, len(self._results)): e, _ = self._results[i] if e is instance: offset = i - self._highlight_index self._highlight_update(offset) self._on_text_validate(1) break def _scroll_update(self): ''' this function adapts the scroller to ensure that the highlighted object is visible ''' highlight_reverse_index = len( self._results) - 1 - self._highlight_index item_lb = highlight_reverse_index * ( self._result_spacing * 2 + self._sep_height + self._result_height) item_ub = item_lb + self._result_height + self._result_spacing * 2 + self._sep_height view_size = (self._result_spacing * 2 + self._result_height + self._sep_height) * self._max_results_displayed total_size = (self._result_spacing * 2 + self._result_height + self._sep_height) * len(self._results) lb = self._scroller.scroll_y * (total_size - view_size) ub = lb + view_size if item_lb < lb: self._scroller.scroll_y -= self._scroller.convert_distance_to_scroll( 0, lb - item_lb)[1] elif item_ub > ub: self._scroller.scroll_y += self._scroller.convert_distance_to_scroll( 0, item_ub - ub)[1] def _highlight_update(self, offset): ''' move the hightlight by `offset' amount ''' if self._highlight_index > -1 and self._highlight_index < len( self._results): e, sep = self._results[self._highlight_index] e.background_color = self._inactive_button_color self._highlight_index += offset self._highlight_index = min(self._highlight_index, len(self._results) - 1) if self._results: self._highlight_index = max(self._highlight_index, 0) else: self._highlight_index = max(self._highlight_index, 1) if self._highlight_index > -1 and self._highlight_index < len( self._results): e, sep = self._results[self._highlight_index] e.background_color = self._active_button_color self._scroll_update() def _highlight_reset(self): offset = -self._highlight_index self._highlight_update(offset) def _highlight_up(self): self._highlight_update(-1) def _highlight_down(self): self._highlight_update(+1) def on_stop(self): pygame.display.quit() pass
def picturesContent(): pictures = {} for picnum in picindex: p = {} p['data'] = blorbfile.getPict(picnum) p['size'] = len(p['data']) p['scale'] = blorbfile.getScaleData(picnum) p['format'] = blorbfile.getPictFormat(picnum) pictures[picnum] = p if len(pictures) == 0: return None if blorbfile.getExecFormat(0) == b'ZCOD': zcode = True else: zcode = False if blorbfile.findChunk(b'Reso') == 0: reso = False else: reso = True titles = ['Number', 'Format', 'Size'] if zcode or reso: titles.extend(['Standard Ratio', 'Minimum Ratio', 'Maximum Ratio']) layout = GridLayout(cols=len(titles), size_hint_y=None) layout.bind(minimum_height=layout.setter('height')) picnums = list(pictures.keys()) picnums.sort() for t in titles: l = Label(text=t, size_hint_y=None) layout.add_widget(l) for p in picnums: numberLabel = Label(text=str(p), size_hint_y=None) formatLabel = Label(text=pictures[p]['format'].decode('latin-1'), size_hint_y=None) sizeLabel = Label(text=str(pictures[p]['size']), size_hint_y=None) layout.add_widget(numberLabel) layout.add_widget(formatLabel) layout.add_widget(sizeLabel) if zcode or reso: stdrat = str(pictures[p]['scale']['ratnum']) + '/' + str( pictures[p]['scale']['ratden']) stdratLabel = Label(text=stdrat, size_hint_y=None) minrat = str(pictures[p]['scale']['minnum']) + '/' + str( pictures[p]['scale']['minden']) minratLabel = Label(text=minrat, size_hint_y=None) maxrat = str(pictures[p]['scale']['maxnum']) + '/' + str( pictures[p]['scale']['maxden']) maxratLabel = Label(text=maxrat, size_hint_y=None) layout.add_widget(stdratLabel) layout.add_widget(minratLabel) layout.add_widget(maxratLabel) return layout
def display_matching_tiles(self): # Check if Wang Tiles Map in Place if self.wang_tiles_map: self.wang_tiles_map.disable_user_interaction() else: print('Wang Tiles Map does not exist!') return popup_content = FloatLayout(size_hint=(1, 1), pos_hint={ 'center_x': 0.5, 'center_y': 0.5 }) if len(self.wang_tiles_map.tiles.keys()) < 1: print('No tiles found in Wang Tiles Map!') print('Tiles:', self.wang_tiles_map.tiles) return # Add Widgets popup = MatchingTiles(content=popup_content) main_tile = Label(pos_hint={ 'x': 0, 'top': 1.0 }, size_hint=(None, None), size=(200, 33), text='_', markup=True, valign='middle', halign='left') main_tile.text_size = main_tile.size with main_tile.canvas: main_tile_rect = Rectangle(pos=(main_tile.pos[0] + 25, main_tile.pos[1]), size=(self.displayed_size, self.displayed_size)) self.bind(pos=partial(self.update_lbl_rect, main_tile, main_tile_rect), size=partial(self.update_lbl_rect, main_tile, main_tile_rect)) grid = GridLayout(rows=4, spacing=0, size_hint=(None, 1.0), pos_hint={ 'x': 0.0, 'y': 0.0 }) north_lbl = Label(text='North\nMatches:', pos_hint={ 'x': 0, 'top': 0.8 }, size_hint=(0.25, 0.2)) east_lbl = Label(text='East\nMatches:', pos_hint={ 'x': 0, 'top': 0.6 }, size_hint=(0.25, 0.2)) south_lbl = Label(text='South\natches:', pos_hint={ 'x': 0, 'top': 0.4 }, size_hint=(0.25, 0.2)) west_lbl = Label(text='West\nMatches:', pos_hint={ 'x': 0, 'top': 0.2 }, size_hint=(0.25, 0.2)) popup_content.add_widget(north_lbl) popup_content.add_widget(east_lbl) popup_content.add_widget(south_lbl) popup_content.add_widget(west_lbl) north_box = BoxLayout(size_hint=(1, 0.25), orientation='horizontal') east_box = BoxLayout(size_hint=(1, 0.25), orientation='horizontal') south_box = BoxLayout(size_hint=(1, 0.25), orientation='horizontal') west_box = BoxLayout(size_hint=(1, 0.25), orientation='horizontal') # north_box.bind(size_hint_min_x=west_box.setter('width')) # east_box.bind(size_hint_min_x=west_box.setter('width')) # south_box.bind(size_hint_min_x=west_box.setter('width')) # west_box.bind(size_hint_min_x=west_box.setter('width')) # grid.add_widget(north_box) # grid.add_widget(east_box) # grid.add_widget(south_box) # grid.add_widget(west_box) grid.bind(minimum_width=grid.setter('width')) scrollview = ScrollView(size_hint=(0.8, 0.8), size=popup.size, do_scroll_x=True, do_scroll_y=False, pos_hint={ 'x': 0.2, 'y': 0 }) scrollview.add_widget(grid) popup_content.add_widget(scrollview) spinner = Spinner(pos_hint={ 'right': 1.0, 'top': 1.0 }, size_hint=(None, None), size=(100, 33), values=sorted(self.wang_tiles_map.tiles.keys())) spinner.bind( text=partial(self._update_match_spinner, main_tile, main_tile_rect, grid, north_box, east_box, south_box, west_box)) popup_content.add_widget(main_tile) popup_content.add_widget(spinner) popup.bind(on_dismiss=self.wang_tiles_map.enable_user_interaction) popup.open() Clock.schedule_once( partial(self.update_lbl_rect, main_tile, main_tile_rect), 0.05)