def on_enter(self): popup = Popup(title='Dish Options', size_hint=(1,1)) layout1 = StackLayout(orientation='lr-bt') #This time the options are layed out in a stack layout, so that I can have multiple options in a small space closebutton = Button(text='I want to make a different dish', size_hint=(0.9,0.05)) #This is a button that will make a different dish for the user closebutton.bind(on_press= popup.dismiss) #The size_hint is the x and y co-ordinate score of how much percentage of the screen the button will have (with 1 being all the screen) closebutton.bind(on_release = self.change_page) scrlv = ScrollView(size_hint=(0.9,0.95)) #This adds a scrollable bar to the list of dishes, if there are lots of them slid = Slider(min=0, max=1, value=25, orientation='vertical', step=0.01, size_hint=(0.1, 0.95)) #The slid is the physical slider used, which calles the scrlv #step is the percentage of the screen it takes up, min and max are always 1 and 0 as they show the ful percentage of the screen covered by the bar scrlv.bind(scroll_y=partial(self.slider_change, slid)) #what this does is, whenever the slider is dragged, it scrolls the previously added scrollview by the same amount the slider is dragged slid.bind(value=partial(self.scroll_change, scrlv)) layout2 = GridLayout(cols=4, size_hint_y=None) #This is another grdi layout used within the popup layout2.bind(minimum_height=layout2.setter('height')) #Bind the height of the layout to the minimum height so that the scroll bar functions for txt in choices: btn = Button(text=txt, size_hint_y=None, height=80, valign='middle', font_size=12) # Add a button for each dish btn.text_size = (btn.size) #set the buttons so that their size changes depending on the screen size btn.bind(on_press = self.find_dish) #When the button is pressed, call the find_dish subroutine btn.bind(on_release = popup.dismiss) #Close the popup if they click the button layout2.add_widget(btn) # Add the buttons to the layout scrlv.add_widget(layout2) layout1.add_widget(closebutton) #Add the close button to the layout layout1.add_widget(scrlv) # Add the scroll bar to the layout layout1.add_widget(slid) #Add the slider to the layout for the scroll bar popup.content = layout1 popup.open() if len(choices) == 0: popup.dismiss() sm.current = "main" #This changes the screen back to the original "main" screen if there are no dishes, which allows the users to choose another dish
def build(self): popup = Popup(title='Draggable Scrollbar', size_hint=(0.8, 1), auto_dismiss=False) #this layout is the child widget for the main popup layout1 = BoxLayout(orientation="vertical") #this button is a child of layout1 closebutton = Button(text='close', size_hint=(0.9, 0.05)) closebutton.bind(on_press=popup.dismiss) def corelate(instance, value): f = 1 - scrlv.scroll_y b.text = str(floor(f * 60)) #another child of layout1 and this is the scrollview which will have a custom draggable scrollbar scrlv = ScrollView(size_hint=(0.4, 0.4)) b = Label(text=str(floor((1 - scrlv.scroll_y) * 60)), size_hint=(0.9, 0.1)) scrlv.bind(scroll_y=corelate) #the last child of layout1 and this will act as the draggable scrollbar s = Slider(min=0, max=1, value=25, orientation='vertical', step=0.01, size_hint=(0.1, 0.95)) scrlv.bind(scroll_y=partial(self.slider_change, s)) #what this does is, whenever the slider is dragged, it scrolls the previously added scrollview by the same amount the slider is dragged s.bind(value=partial(self.scroll_change, scrlv)) layout2 = GridLayout(cols=1, size_hint_y=None) layout2.bind(minimum_height=layout2.setter('height')) for i in range(0, 61): btn = Label(text=str(i), size_hint_y=None, size_hint_x=0.2, height=60, valign='middle', halign='center', font_size=12) btn.text_size = (btn.size) layout2.add_widget(btn) scrlv.add_widget(layout2) layout1.add_widget(scrlv) layout1.add_widget(b) layout1.add_widget(closebutton) layout1.add_widget(s) popup.content = layout1 popup.open()
class CategoryIcon(BoxLayout): """Show the category name plus a selection of icons.""" screen = ObjectProperty() category = ObjectProperty() def __init__(self, **kwargs): super(CategoryIcon, self).__init__(**kwargs) label = Label(text=self.category.name, halign="left", valign="middle", size_hint=(3, 1)) label.bind(size=label.setter('text_size')) self.add_widget(label) for filename, index in self.category.backgrounds[:3]: self.add_widget(BackgroundDisplay(screen=self.screen, filename=filename, index=index, label=False)) for i in range(3 - len(self.category.backgrounds)): self.add_widget(Widget()) self.bind(size=self._set_pad) def _set_pad(self, *args): self.padding = self.size[0] * 0.05, self.size[1] * 0.01 def on_touch_up(self, touch): if self.collide_point(*touch.pos): self._show_category() return True return super(CategoryIcon, self).on_touch_up(touch) def _show_category(self): popup = Popup(title="%s Backgrounds" % self.category.name) self.scroller = ScrollView(do_scroll_x=False) self.grid = GridLayout(cols=3, size_hint_y=None) for filename, index in self.category.backgrounds: self.grid.add_widget(BackgroundDisplay(screen=self.screen, filename=filename, index=index, popup=popup)) for i in range(3 - len(self.category.backgrounds)): self.grid.add_widget(Widget()) self.scroller.bind(size=self._resize) self.scroller.add_widget(self.grid) popup.add_widget(self.scroller) popup.open() def _resize(self, *args): rows = math.ceil(len(self.category.backgrounds) / 3.0) self.grid.size = (self.scroller.size[0], rows * self.scroller.size[0] / 3)
def display_out(self, uid, out='out'): process = self.processes[uid] p = Popup(size_hint=(.95, .95), title='std%s %s' % (out, process['label'].text)) sc = ScrollView() content = Label(text=process[out], size_hint=(None, None)) sc.bind(width=content.setter('width')) content.bind(width=lambda c, w: content.setter('text_size')(c, (w, None))) content.bind(texture_size=content.setter('size')) sc.add_widget(content) p.add_widget(sc) p.open()
def display_out(self, uid, out='out'): process = self.processes[uid] p = Popup(size_hint=(.95, .95), title='std%s %s' % (out, process['label'].text)) sc = ScrollView() content = Label(text=process[out], size_hint=(None, None)) sc.bind(width=content.setter('width')) content.bind( width=lambda c, w: content.setter('text_size')(c, (w, None))) content.bind(texture_size=content.setter('size')) sc.add_widget(content) p.add_widget(sc) p.open()
def create_group_tab_layout(self): scroll = ScrollView(size_hint=(1, 1)) with scroll.canvas.before: scroll.rect = Image(source=BKGD_DCHRC, allow_stretch=True, keep_ratio=False, size_hint=(1, 1)) scroll.bind(pos=manager.update_rect, size=manager.update_rect) self.group_tab_layout = GridLayout(cols=1, size_hint_y=None, row_default_height=28, spacing=[0, 1]) self.group_tab_layout.bind( minimum_height=self.group_tab_layout.setter('height')) scroll.add_widget(self.group_tab_layout) self.group_tab.add_widget(scroll)
class StockAnalysis(App): def build(self): searchables = pickle.load(open("res/searchables.p", 'rb')) self.crossRefs = pickle.load(open("res/crossMark6.p", 'rb')) self.searchRecs = SearchTree(searchables) self.searchDB = (self.crossRefs, self.searchRecs) self.activities = {"search": SearchActivity(self, self.searchDB)} self.root = GridLayout(cols=1) self.activity = self.activities["search"] ####################################### ############# Scroll View ############# ####################################### self.scrollView = ScrollView(size_hint=(1, None), do_scroll_x=False, do_scroll_y=True, size=(Window.width, Window.height * .9), scroll_timeout=250, y=Window.height * .1) def scrollViewScale(*args): self.scrollView.size = (Window.width, Window.height * .9) self.scrollView.y = Window.height * .1 self.scrollView.bind(size=scrollViewScale) self.scrollView.add_widget(self.activity) self.root.add_widget(self.scrollView) self.activitySelect = ActivitySelect(self) def activitySelectScale(*args): self.activitySelect.size = (Window.width, Window.height * .1) self.activitySelect.y = 0 self.activitySelect.bind(size=activitySelectScale) self.root.add_widget(self.activitySelect) self.currentConduitLabel = "" self.conduit = None Window.bind(on_keyboard=self.androidBack) return self.root def androidBack(self, window, key1, key2, *args): # print(self.conduit) if key1 in [27, 1001]: if self.conduit: self.conduit.back() return True return False
def make_dialog(self, title, finalc): content = Button(text=finalc, padding=(0, 0), font_name='Hack-Regular', halign='left', size_hint=(None, None), color=[0, 0, 0, 1], background_normal='./transparent.png', background_down='./transparent.png') content.bind(size=lambda x, y: Logger.info(y)) content.bind( texture_size=lambda obj, t: content.setter('size')(obj, t)) bx = ScrollView(size_hint=(1, None), size=(Window.width * 0.7, Window.height * 0.6)) bx.add_widget(content) bx.bind(size=lambda obj, x: Logger.info(x)) self.dialog = MDDialog(title=title, content=bx, size_hint=(0.8, 0.8)) self.dialog.add_action_button('Dismiss', lambda *args: self.dialog.dismiss()) self.dialog.open()
def create_info_panel(self): scroll = ScrollView(size_hint=(1, 1)) with scroll.canvas.before: scroll.rect = Image(source=BKGD_CHRC, allow_stretch=True, keep_ratio=False) scroll.bind(pos=self.update_rect, size=self.update_rect) info_panel_layout = GridLayout(cols=1, size_hint_y=None, pos_hint={ "x-center": .5, "top": 1 }, row_default_height=30, row_force_default=True, padding=15) info_panel_layout.bind( minimum_height=info_panel_layout.setter('height')) scroll.add_widget(info_panel_layout) self.panel_layout.add_widget(scroll) return info_panel_layout
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 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
def __init__(self, dataList, title): self.name = "readonlytable" super(ReadOnlyTable, self).__init__() self.dataList = dataList parent_layout = FloatLayout() self.title = str(title) scroll_layout = ScrollView(size_hint=(1, None), size=(Window.width, Window.height)) scroll_layout.bind(size=self._update_rect, pos=self._update_rect) table_layout = GridLayout(cols=len(dataList[0]) + 1, size_hint_y=None, spacing=5) table_layout.bind(minimum_height=table_layout.setter('height')) # table_layout.bind(size=self._update_rect, pos=self._update_rect) length = len(dataList[0]) # # for record in dataList: # # for p, column in enumerate(record): # if len(str(column)) > sizes[p]: # sizes[p] = len(str(column)) + 3 self.company = Button(text='Back|', color=(0, 0, 0, 1), background_color=(0, 0, 0, 0), font_size=20, on_press=self.back, pos_hint={'center_x': 0.12, 'center_y': 0.95}) table_layout.add_widget(self.company) table_layout.add_widget(Label(text="KAKABOKA", size_hint_y=None, color=(0, 0, 0, 1), font_size=20, )) table_layout.add_widget(Label(text="Sales", size_hint_y=None, height=50, color=(0, 0, 0, 1), font_size=20)) table_layout.add_widget( Button(text="Show stats", size_hint_y=None, height=50, font_size=10, on_press=self.stats)) forsales = dataList[1:] total_sale = 0 for d in forsales: total_sale = total_sale + float(d[5]) table_layout.add_widget(Label(text="", size_hint_y=None, height=50)) table_layout.add_widget( Label(text="Total Sales: ${}".format(total_sale), size_hint_y=None, height=50, color=(0, 0, 0, 1), font_size=15)) self.show_details_btn = Button(text="Show Details", size_hint_y=None, size_hint=(0.1, None), height=50, font_size=10, on_press=self.show_sale_details) table_layout.add_widget(self.show_details_btn) i = 0 while i < length - 6: table_layout.add_widget(Label(text="", size_hint_y=None, height=50)) i = i + 1 dataList[0].reverse() for i, row_data in enumerate(dataList[0]): t = Label(text=row_data, size_hint_y=None, height=40, color=(0, 0, 0, 1)) table_layout.add_widget(t, index=i) dataList = dataList[1:] table_layout.add_widget(Label(text="")) self.dataList = dataList for row_n, row_data in enumerate(dataList): row_data.reverse() row_data.append("") for i, row in enumerate(row_data): new_row = row_data t = Label(text=str(row), size_hint_y=None, font_size=14, pos_hint={"x_center": 0.9}, height=40, color=(0, 0, 0, 1)) if i <= length - 1: table_layout.add_widget(t, index=i) def changeText(event, data): new_row[i] = data print(data) t.bind(text=changeText) else: btn = Label(text="", size_hint_y=None, height=40, color=(0, 0, 0, 1)) def updateRecord(self): print("Record to be updated : ") db = InventoryDB() data = db.getInventoryRecodeByBarcode(barcode=new_row[5])[0] data.id = new_row[5] data.barcode = new_row[5] data.price = float(3) # data.itemname = itemname # data.manufacturer = manufacturer # data.quantity = quantity data.category = str(new_row[0]) print(row_data) btn.bind(on_press=updateRecord) table_layout.add_widget(btn) with scroll_layout.canvas.before: base_folder = os.path.dirname(__file__) image_path = os.path.join(base_folder, 'background.png') self.rect = Rectangle(source=image_path, size=scroll_layout.size, pos=scroll_layout.pos) scroll_layout.add_widget(table_layout) self.add_widget(scroll_layout) self.add_widget(parent_layout)
class FoodChooser(Screen): def __init__(self, screenmanager, *args, **kwargs): super().__init__(*args, **kwargs) self.screenmanager = screenmanager ui_grid = GridLayout(rows=1) main_grid = GridLayout(rows=2, cols=1) buttons_grid = GridLayout(cols=1, size_hint=(0.2, 1)) # viewer self.txtviewer = ScrollView() def txtviewer_update_rect(self, *args): self.rect.pos = self.pos self.rect.size = [self.size[0] - 10, self.size[1] - 10] with self.txtviewer.canvas.before: Color(0.73828125, 0.48828125, 0.2890625, 0.5) self.txtviewer.rect = Rectangle(size=[ self.txtviewer.size[0] - 10, self.txtviewer.size[1] - 10 ], pos=self.txtviewer.pos) self.txtviewer.bind(pos=txtviewer_update_rect, size=txtviewer_update_rect) # --- # listings in viewer self.scoll_view_update_callback() # --- # title temp = Label(text='All Food Ideas', size_hint=(1, 0.1), font_size=50, bold=True) def title_update_rect(self, *args): temp.rect.pos = temp.pos temp.rect.size = [temp.size[0] - 10, temp.size[1] - 10] with temp.canvas.before: Color(0.73828125, 0.48828125, 0.2890625, 0.5) temp.rect = Rectangle(size=[temp.size[0] - 10, temp.size[1] - 10], pos=temp.pos) temp.bind(pos=title_update_rect, size=title_update_rect) # --- main_grid.add_widget(temp) main_grid.add_widget(self.txtviewer) # Buttons add_new = Tile(image_normal='plus_sign.png', background_color=(0, 0, 0, 0)) add_new.bind(on_press=self.addnew_callback) random7 = Tile(image_normal='dice.png', background_color=(0, 0, 0, 0)) random7.bind(on_press=self.randomiser) back = Tile(image_normal='back.png', background_color=(0, 0, 0, 0)) back.bind(on_press=self.back_callback) # --- buttons_grid.add_widget(random7) buttons_grid.add_widget(add_new) buttons_grid.add_widget(back) ui_grid.add_widget(main_grid) ui_grid.add_widget(buttons_grid) self.add_widget(ui_grid) def scoll_view_update_callback(self, *args): self.txtviewer.clear_widgets() temp = open('food_list.txt', 'r') lines = temp.read().split('\n') temp.close() lists = GridLayout(cols=1) for i in lines: temp_b = Label(text=str(i), font_size=30, bold=True) lists.add_widget(temp_b) self.txtviewer.add_widget(lists) def addnew_callback(self, *args): # Popup gird = GridLayout(cols=1) self.chars = Label(text='', size_hint=(1, 0.1), font_size=50, bold=True) gird.add_widget(self.chars) # Keyboard def keyboardpress(button): self.chars.text = self.chars.text + str(button.text) def keyboardspace(*args): self.chars.text = self.chars.text + ' ' def backspace(*args): if len(self.chars.text) > 0: self.chars.text = self.chars.text[:-1] keyboard = GridLayout(rows=3, cols=10) keys_in_order = [ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', '', 'z', 'x', 'c', 'v', 'b', 'n', 'm', '', '', '' ] for key in keys_in_order: if key == '': keyboard.add_widget(Label()) else: temp = Button(text=key, font_size=50, bold=True) temp.bind(on_press=lambda i: keyboardpress(i)) keyboard.add_widget(temp) gird.add_widget(keyboard) # --- buttons = GridLayout(rows=1, size_hint=(1, 0.2)) temp = Button(text='Space', font_size=40, bold=True) temp.bind(on_press=lambda i: keyboardspace(i)) buttons.add_widget(temp) temp = Button(text='BackSpace', size_hint=(0.25, 1), font_size=40, bold=True) temp.bind(on_press=lambda i: backspace(i)) buttons.add_widget(temp) quiter = Button(text='Quit', size_hint=(0.25, 1), font_size=40, bold=True) buttons.add_widget(quiter) saver = Button(text='Save', size_hint=(0.1, 1), font_size=40, bold=True) buttons.add_widget(saver) gird.add_widget(buttons) self.popup = Popup(title='New Food Item', content=gird, auto_dismiss=False) self.popup.open() def close_popup(*args): self.popup.dismiss() quiter.bind(on_press=close_popup) def save_item(*args): file = open('food_list.txt', 'a') file.write('\n' + self.chars.text) file.close() self.scoll_view_update_callback() self.popup.dismiss() saver.bind(on_press=save_item) def randomiser(self, *args): file = open('food_list.txt', 'r') lines = file.read().split('\n') lister = GridLayout(cols=1) for i in range(7): slec = lines[randint(0, len(lines) - 1)] lister.add_widget(Label(text=slec, font_size=50, bold=True)) quiter = Button(text='Quit', font_size=50, bold=True) lister.add_widget(quiter) self.popup = Popup(title='7 Food Items', content=lister, auto_dismiss=False) self.popup.open() def close_popup(*args): self.popup.dismiss() quiter.bind(on_press=close_popup) def back_callback(self, *args): self.screenmanager.switch_to(MainScreen(self.screenmanager))
class FileBrowser(BoxLayout): def __init__(self, name, **kwargs): super().__init__(**kwargs) self.orientation = "vertical" # the below is now handled #self.size_hint = (None, None) #it would be nice if this could be optionally passed in with kwargs #self.size = (width, height) self.source = "" self.show_file_names = True self.selected_image = SpecialImage(None) self.image_width_hint = 1 # big one self.bind( size=partial(self.set_image_width_hint) ) # will need size or just height, depending on what's being used in the function Window.bind(mouse_pos=self._mouse_move) self.hover_count = None # set this during populate self.menu_bar = MenuBar(name, almost_black, light_grey, light_blue) self.add_widget(self.menu_bar) self.scroll_body = ScrollView(bar_width='12dp', scroll_wheel_distance='20dp', scroll_type=['bars', 'content'], bar_inactive_color=[.7, .7, .7, .2 ]) ### add settings self.add_widget(self.scroll_body) self.scroll_body.bind(on_scroll_stop=self.on_scroll_stop_function) self.body = StackLayout( orientation="lr-tb", size_hint_x=0.99, size_hint_y=None, spacing=[1, 5] ) # the horizontal spacing isn't like the website, but they didn't have background colours like I do self.scroll_body.add_widget(self.body) self.body.bind(minimum_height=self.body.setter('height')) self.body.bind(height=self.scroll_test_function) self.bottom_bar = BottomBar(size_hint=(1, None), height='17dp', font_size='13dp', bold=True) self.add_widget(self.bottom_bar) self.draw() self.bind(pos=self.update_rectangles, size=self.update_rectangles) self.bind(size=self.test_function) self.size = self.size self.test_function() def scroll_test_function(self, *args): self.scroll_body.scroll_wheel_distance = kivy.metrics.dp(20) * math.log( self.body.height ) / 4 #< I think I stumbled across a combination here hat's quite effective (it goes between 35-45 depending on number of items, maybe more maybe less) def test_function(self, *args): self.body.padding = [3, 5, kivy.metrics.dp(12), 0] #self.body.padding = [(self.width - (self.width * 0.99)), 5, kivy.metrics.dp(12), 0] # def draw(self): self.canvas.before.clear() with self.canvas.before: Color(1, 1, 1, 1) self.rectangle = Rectangle(pos=self.pos, size=self.size) def update_rectangles(self, *args): self.rectangle.pos = self.pos self.rectangle.size = self.size def populate(self, source): # a means of setting source self.source = source if self.body.children != []: self.body.clear_widgets() if source != "": direntry_iterator = os.scandir(self.source) for direntry in direntry_iterator: if direntry.is_file( ) == True: # Could also check if they are images (.png, .jpg) a_special_image = SpecialImage(direntry) self.body.add_widget(a_special_image) a_special_image.be_within = self a_special_image.be_not_within = self.menu_bar a_special_image.be_not_within_two = self.bottom_bar # set sizes of specialimage. This might be a dumb way to do it, they only need to be called once, you see. a_special_image.update_height() a_special_image.update_image_height() a_special_image.update_boxlayout() a_special_image.update_text_textboxes() def set_selected(self, a_special_image): if a_special_image != self.selected_image: if self.selected_image != None: self.selected_image.selected = False self.selected_image.set_deselected() self.selected_image = a_special_image a_special_image.set_selected() self.bottom_bar.update_text(self.selected_image.file_name + " selected") def set_image_width_hint(self, *args): pass def _mouse_move(self, *args): if not self.get_root_window(): return is_collide = self.collide_point(*self.to_widget(*args[1])) hovered = False for child in self.body.children: if child.hover == True and child.selected == False: # since until you on_exit a special image, and it's selected, hover will be true (and we don't want to have a hand cursor) hovered = True break if is_collide == True and hovered == True: Window.set_system_cursor("hand") elif is_collide == False: pass else: Window.set_system_cursor("arrow") def on_scroll_stop_function(self, *args): for child in self.body.children: # i.e. when on_scroll_stop is called for scroll_body, iterate through the special images and get them to check if they should be on_hovered or exits (this wouldn't be done otherwise: because a scroll isn't a mouse move) child._mouse_move( "hifdidl", Window.mouse_pos ) # THANK F**K THAT THIS WORKS. My doubt was that it would pass some bull shit Window.mouse_pos.
class ViewerScreen(Screen): src = StringProperty("") label_text = StringProperty("") slider_value = NumericProperty(1) def __init__(self, firebase, **kwargs): super(ViewerScreen, self).__init__(**kwargs) with self.canvas: self.bg = Rectangle(source='app_data/background.jpg', pos=self.pos, size=self.size) self.bind(pos=self.update_bg) self.bind(size=self.update_bg) self.firebase = firebase self.event = None self._popup = None self.user_data = None self.page = 0 self.default_zoom = [1, 2.79] self.num_pages = 0 self.timeout = 30 box_layout = BoxLayout( orientation='vertical' ) bar_panel = BarPanel( orientation='horizontal', size_hint=(1, None), height=80, padding=7 ) image = Image( size_hint=(None, 1), width=150, source='app_data/master_fitness_logo_w_noaddr.png' ) self.label = Label( size_hint=(1, 1), font_size=20, italic=True, text=self.label_text ) self.labelPage = Label( size_hint=(None, 1), width=50, font_size=30, italic=True ) self.qr_button_anchor = AnchorLayout( size_hint=(None, 1), width=100, anchor_x='center', anchor_y='center' ) self.qr_button = Button( size_hint=(None, None), width=70, height=70, valign='center', halign='center', background_normal='app_data/qr_normal.png', background_down='app_data/qr_down.png', border=(0,0,0,0), on_release=self.on_release_qr_button ) self.close_button = Button( size_hint=(None, None), width=70, height=70, valign='center', halign='center', background_normal='app_data/close_normal.png', background_down='app_data/close_down.png', border=(0,0,0,0), on_release=self.on_release_close_button ) self.left_button = Button( size_hint=(None, None), width=70, height=70, valign='center', halign='center', background_normal='app_data/left_normal.png', background_down='app_data/left_down.png', border=(0,0,0,0), on_release=self.on_release_left_button ) self.right_button = Button( size_hint=(None, None), width=70, height=70, valign='center', halign='center', background_normal='app_data/right_normal.png', background_down='app_data/right_down.png', border=(0,0,0,0), on_release=self.on_release_right_button ) self.zoomOut_button = Button( size_hint=(None, None), width=70, height=70, valign='center', halign='center', background_normal='app_data/zoomOut_normal.png', background_down='app_data/zoomOut_down.png', border=(0,0,0,0), on_release=self.on_release_zoomOut_button ) self.zoomIn_button = Button( size_hint=(None, None), width=70, height=70, valign='center', halign='center', background_normal='app_data/zoomIn_normal.png', background_down='app_data/zoomIn_down.png', border=(0,0,0,0), on_release=self.on_release_zoomIn_button ) anchor_layout = AnchorLayout( size_hint=(1, 0.8), anchor_x='right' ) self.scrollview = ScrollView( size_hint=(1, 1), bar_color=[0,0,0,0], bar_inactive_color=[0,0,0,0], effect_cls=ScrollEffect ) self.slider = Slider( orientation='vertical', size_hint=(None, 1), width=50, min=0, max=1, step=0.01, value=self.slider_value, cursor_image='app_data/kettlebell.png', cursor_size=('45sp', '45sp'), background_vertical='app_data/slider.png', background_width='3sp', padding='30sp' ) self.scrollview.bind(scroll_y=self.slider_change) self.slider.bind(value=self.scroll_change) self.img_view = None #Image(size_hint=(1, None), height=1450, nocache=True, source=self.src) bar_panel.add_widget(image) bar_panel.add_widget(self.qr_button_anchor) self.qr_button_anchor.add_widget(self.qr_button) bar_panel.add_widget(self.label) bar_panel.add_widget(self.zoomOut_button) bar_panel.add_widget(self.zoomIn_button) bar_panel.add_widget(self.left_button) bar_panel.add_widget(self.labelPage) bar_panel.add_widget(self.right_button) bar_panel.add_widget(self.close_button) #self.scrollview.add_widget(self.img_view) anchor_layout.add_widget(self.scrollview) anchor_layout.add_widget(self.slider) box_layout.add_widget(bar_panel) box_layout.add_widget(anchor_layout) self.add_widget(box_layout) def reschedule(self): Clock.unschedule(self.event) self.event = Clock.schedule_once(self.go_to_home, self.timeout) def on_pre_enter(self): self.scrollview.remove_widget(self.img_view) self.img_view = None self.num_pages = self.user_data['num_pages'] self.page = self.user_data['page'] if self.page + 1 > self.num_pages: self.page = self.num_pages - 1 self.labelPage.text=str(self.page+1)+"/"+str(self.num_pages) self.label_text = "Scheda di "+self.user_data['name']+" "+self.user_data['surname'] self.setSourcePath("storage_data/"+str(self.user_data['rfid'])+"/scheda_"+str(self.page)+".jpg") self.img_view = Image( size_hint=(self.default_zoom[0], self.default_zoom[1]), allow_stretch = True, nocache=True, source=self.src ) self.img_view.bind(size_hint=self.on_img_hint_update) self.scrollview.add_widget(self.img_view) try: self.slider_value = self.user_data['slider_y'] self.scrollview.scroll_x = self.user_data['slider_x'] zoom = self.user_data['zoom'] if zoom[0] == 0 and zoom[1] == 0: zoom = self.default_zoom self.img_view.size_hint = (zoom[0], zoom[1]) except: self.slider_value = 1 self.scrollview.scroll_x = 0.5 self.img_view.size_hint = (self.default_zoom[0], self.default_zoom[1]) self.reschedule() def on_pre_leave(self): Clock.unschedule(self.event) if self._popup : self._popup.dismiss() self._popup = None def on_leave(self): if self.user_data : data = { "page": self.page, "zoom": self.img_view.size_hint, "slider_x": self.scrollview.scroll_x, "slider_y": self.slider_value } self.saveUserData(self.user_data['rfid'], data) self.scrollview.remove_widget(self.img_view) self.img_view = None def go_to_home(self, *largs): self.manager.current = 'home' def scroll_change(self, instance, value): self.slider_value = value self.scrollview.scroll_y = value self.reschedule() def slider_change(self, instance, value): if value >= 0: #this to avoid 'maximum recursion depth exceeded' error self.slider_value = value self.reschedule() def on_release_close_button(self, instance): self.go_to_home() def on_release_qr_button(self, instance): self.reschedule() content = QrDialog(rfid=str(self.user_data['rfid'])) self._popup = Popup(title="Scansiona il QR Code", content=content, size_hint=(None, None), width=250, height=300) self._popup.open() def changePage(self, new_page): self.reschedule() if path.isfile("storage_data/"+str(self.user_data['rfid'])+"/scheda_"+str(new_page)+".jpg"): self.page=new_page self.labelPage.text=str(self.page+1)+"/"+str(self.num_pages) self.setSourcePath("storage_data/"+str(self.user_data['rfid'])+"/scheda_"+str(self.page)+".jpg") self.slider_value = 1 def on_release_left_button(self, instance): self.changePage(new_page=self.page-1) def on_release_right_button(self, instance): self.changePage(new_page=self.page+1) def on_img_hint_update(self, instance, value): scroll_x = self.scrollview.scroll_x self.scrollview.scroll_x = scroll_x self.reschedule() def on_release_zoomOut_button(self, instance): if self.img_view.size_hint_x / 1.2 >= 1: if self.img_view: self.img_view.size_hint = (self.img_view.size_hint_x / 1.2, self.img_view.size_hint_y / 1.2) self.img_view.width = 0 else: self.scrollview.scroll_x = 0.5 def on_release_zoomIn_button(self, instance): if self.img_view.size_hint_x * 1.2 <= 3: if self.img_view: self.img_view.size_hint = (self.img_view.size_hint_x * 1.2, self.img_view.size_hint_y * 1.2) self.img_view.width = 0 def on_src(self, instance, value): if self.img_view: self.img_view.source = value def on_label_text(self, instance, value): self.label.text = value def on_slider_value(self, isinstance, value): self.slider.value = value def update_bg(self, *args): self.bg.pos = self.pos self.bg.size = self.size def setSourcePath(self, path, *largs): self.src = path def saveUserData(self, rfid, data): if self.firebase: self.firebase.update("users/"+rfid, data) def setUserData(self, user_data, *largs): self.user_data = user_data
class MyApp(App): def BoxLayout(self): # top layout self.layout_top = BoxLayout(orientation='horizontal') self.next_button = Button(text='Next Client', on_press=lambda a: self.next_client()) self.next_button.size_hint = (.2, 1) logo = Image(source='../../Marketing/simbolo_semfundo.png') logo.size_hint = (.6, 1) qr = Image(source='qr.png') qr.size_hint = (.2, 1) self.layout_top.add_widget(qr) self.layout_top.add_widget(logo) self.layout_top.add_widget(self.next_button) self.layout_top.size_hint = (1, 0.2) # center layout self.layout_center = StackLayout(orientation='lr-bt') self.scrlv = ScrollView(size_hint=(0.9, 0.95)) self.s = Slider(min=0, max=1, value=25, orientation='vertical', step=0.01, size_hint=(0.1, 0.95)) self.scrlv.bind(scroll_y=partial(self.slider_change, self.s)) # what this does is, whenever the slider is dragged, it scrolls the previously added scrollview by the same amount the slider is dragged self.s.bind(value=partial(self.scroll_change, self.scrlv)) self.layout_grid = GridLayout(cols=3, size_hint_y=None) self.layout_grid.bind(minimum_height=self.layout_grid.setter('height')) self.scrlv.add_widget(self.layout_grid) self.layout_center.add_widget(self.scrlv) self.layout_center.add_widget(self.s) # bottom layout self.layout_bottom = BoxLayout(orientation='horizontal') label_total = Label(text='Total:', font_size=30, color=[0, 0, 0, 1]) label_total.size_hint = (.5, 1) self.value = Label(text="0€", font_size=30, color=[0, 0, 0, 1]) self.value.size_hint = (.5, 1) self.layout_bottom.add_widget(label_total) self.layout_bottom.add_widget(self.value) self.layout_bottom.size_hint = (1, 0.1) # global layout layout_global = BoxLayout(orientation='vertical') layout_global.add_widget(self.layout_top) layout_global.add_widget(self.layout_center) layout_global.add_widget(self.layout_bottom) return layout_global def scroll_change(self, scrlv, instance, value): scrlv.scroll_y = value def slider_change(self, s, instance, value): if value >= 0: s.value = value def t1(self): self.gotBill = False msg = self.con.receive() #print(msg) try: if msg['src'] == 'GBD': #print(colored("got right src",'green')) for prod in msg['payload']['products']: #print(colored("prod= "+str(prod), 'green')) i = 0 for c in prod: #print(colored("c= " + str(c), 'green')) i += 1 if i == 1: c = base64.b64decode(c).decode('utf-8') lbl = Label(text=c, size_hint_y=None, height=80, valign='middle', font_size=27, color=[0, 0, 0, 1]) # lbl.text_size = (lbl.size) if i % 3 == 0: lbl.size_hint = (0.2, 1) self.layout_grid.add_widget(lbl) self.value.text = msg['payload']['total'] + '€' self.con.send("ACK") self.Bill = msg self.gotBill = True except Exception as e: print(e) print(colored("no valid message found!", 'red')) self.con.send("ERROR") self.layout_top.remove_widget(self.padding) self.layout_top.add_widget(self.next_button) def next_client(self): self.layout_grid.clear_widgets() self.value.text = '' self.layout_top.remove_widget(self.next_button) self.padding = Label(text="Processing Bill", color=[0, 0, 0, 1]) self.padding.size_hint = (.2, 1) self.layout_top.add_widget(self.padding) threading.Thread(target=self.t1).start() def handleApp(self): while True: msg = self.app.receive() print(msg) print(colored('Got new APP request', 'green')) while not self.gotBill: pass try: self.Bill['payload'].pop('bill') except: print("already cleared") self.Bill['src'] = 'GUI' print(self.Bill) self.app.send(self.Bill) def build(self): Window.clearcolor = (1, 1, 1, 1) self.con = Connection('0.0.0.0', '6667') self.app = Connection('0.0.0.0', '7778') self.con.connect() self.app.connect() threading.Thread(target=self.handleApp).start() self.gotBill = False self.Bill = None self.layout_grid = None self.next_button = None self.layout_top = None self.layout_bottom = None self.layout_center = None self.padding = None self.value = None self.scrlv = None self.s = None self.title = 'HyperSmartSolutions' return self.BoxLayout()
class RecipeFinder(Screen): def __init__(self, screenmanager, *args, **kwargs): super().__init__(*args, **kwargs) self.screenmanager = screenmanager ui_grid = GridLayout(rows=1) main_grid = GridLayout(rows=2, cols=1) buttons_grid = GridLayout(cols=1, size_hint=(0.2, 1)) # viewer self.txtviewer = ScrollView() def txtviewer_update_rect(self, *args): self.rect.pos = self.pos self.rect.size = [self.size[0] - 10, self.size[1] - 10] with self.txtviewer.canvas.before: Color(0.73828125, 0.48828125, 0.2890625, 0.5) self.txtviewer.rect = Rectangle(size=[ self.txtviewer.size[0] - 10, self.txtviewer.size[1] - 10 ], pos=self.txtviewer.pos) self.txtviewer.bind(pos=txtviewer_update_rect, size=txtviewer_update_rect) # --- # listings in viewer self.scoll_view_update_callback([]) # --- main_grid.add_widget(self.txtviewer) # Buttons search = Tile(image_normal='search.png', background_color=(0, 0, 0, 0)) search.bind(on_press=self.search_callback) back = Tile(image_normal='back.png', background_color=(0, 0, 0, 0)) back.bind(on_press=self.back_callback) # --- buttons_grid.add_widget(search) buttons_grid.add_widget(back) ui_grid.add_widget(main_grid) ui_grid.add_widget(buttons_grid) self.add_widget(ui_grid) def scoll_view_update_callback(self, items, *args): self.txtviewer.clear_widgets() lists = GridLayout(cols=1) def open_url(url): webbrowser.open(url) for i in items: menu_item = GridLayout(cols=1) temp_b = Button(text=str(i['name']), font_size=30, bold=True, background_color=[0, 0, 0, 0]) temp_b.url = i['url'] temp_b.bind(on_press=lambda x: open_url(x.url)) menu_item.add_widget(temp_b) temp_d = Button(text=str(i['description']), font_size=15, background_color=[0, 0, 0, 0]) temp_d.url = i['url'] temp_d.bind(on_press=lambda x: open_url(x.url)) menu_item.add_widget(temp_d) lists.add_widget(menu_item) self.txtviewer.add_widget(lists) def search_callback(self, *args): # Popup gird = GridLayout(cols=1) self.chars = Label(text='', size_hint=(1, 0.1), font_size=50, bold=True) gird.add_widget(self.chars) # Keyboard def keyboardpress(button): self.chars.text = self.chars.text + str(button.text) def keyboardspace(*args): self.chars.text = self.chars.text + ' ' def backspace(*args): if len(self.chars.text) > 0: self.chars.text = self.chars.text[:-1] keyboard = GridLayout(rows=3, cols=10) keys_in_order = [ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', '', 'z', 'x', 'c', 'v', 'b', 'n', 'm', '', '', '' ] for key in keys_in_order: if key == '': keyboard.add_widget(Label()) else: temp = Button(text=key, font_size=50, bold=True) temp.bind(on_press=lambda i: keyboardpress(i)) keyboard.add_widget(temp) gird.add_widget(keyboard) # --- buttons = GridLayout(rows=1, size_hint=(1, 0.2)) temp = Button(text='Space', font_size=40, bold=True) temp.bind(on_press=lambda i: keyboardspace(i)) buttons.add_widget(temp) temp = Button(text='BackSpace', size_hint=(0.25, 1), font_size=40, bold=True) temp.bind(on_press=lambda i: backspace(i)) buttons.add_widget(temp) quiter = Button(text='Quit', size_hint=(0.25, 1), font_size=40, bold=True) buttons.add_widget(quiter) search = Button(text='Search', size_hint=(0.1, 1), font_size=40, bold=True) buttons.add_widget(search) gird.add_widget(buttons) self.popup = Popup(title='New Food Item', content=gird, auto_dismiss=False) self.popup.open() def close_popup(*args): self.popup.dismiss() quiter.bind(on_press=close_popup) def search_item(*args): query_options = { "wt": self.chars.text, # Query keywords "sort": "p" # Sorting options : 're' for relevance, 'ra' for rating, 'p' for popular (optional) } query_results = AllRecipes.search(query_options) self.scoll_view_update_callback(query_results) self.popup.dismiss() search.bind(on_press=search_item) def back_callback(self, *args): self.screenmanager.switch_to(MainScreen(self.screenmanager))
class EditNoteScreen(Screen): """Screen for editing a note's name and content. When a new note is to be created the user is redirected here to create it.""" def __init__(self, **kwargs): super(EditNoteScreen, self).__init__(**kwargs) # Container------------------------------------------------------------ self.editnote_container = BoxLayout(orientation="vertical", spacing=5) # *Top Bar------------------------------------------------------------- # Back Button back_btn = Button(text="<-", background_normal='', background_color=app_settings.app_bg_color, color=app_settings.text_color, size_hint=(.15, 1), id="Back") back_btn.bind(on_release=self.back) # Settings Button delete_btn = Button(text="|||", background_normal='', background_color=app_settings.app_bg_color, color=app_settings.text_color, size_hint=(.15, 1)) delete_btn.bind(on_release=self.delete) self.editnote_container.add_widget(TopBar(back_btn, delete_btn)) # *Note Screen Container----------------------------------------------- self.note_container = BoxLayout(orientation="vertical", spacing=2, padding=[5]) # *Note Name----------------------------------------------------------- # Name Text Input self.note_name_ti = CustomTextInput(hint_text="Untitled", font_size=18, multiline=False, write_tab=False, size_hint=(1, .09), padding=(10, 10)) self.note_container.add_widget(self.note_name_ti) self._name = 'Untitled' # This is the default title for notes # *Note Body----------------------------------------------------------- body_container = BoxLayout() # The ScrollView self.body_scroll = ScrollView(size_hint=(1, 1), size=(1, 1), bar_color=app_settings.text_color, bar_pos_y='right', ) # Body TextInput Widget self.notebody_textinput = CustomTextInput(hint_text="Enter note body", multiline=True, size_hint_y=None, padding=(10, 10)) # Bind the two widgets to the greater height self.body_scroll.bind(height=self.textinput_height) self.notebody_textinput.bind(minimum_height=self.textinput_height) self.body_scroll.add_widget(self.notebody_textinput) body_container.add_widget(self.body_scroll) self.note_container.add_widget(body_container) # *Pack---------------------------------------------------------------- self.editnote_container.add_widget(self.note_container) self.add_widget(self.editnote_container) # *Load on enter, save on exit----------------------------------------- self.bind(on_enter=self.load, on_pre_leave=self.save) def back(self, *args): """Method for back button, saves the note.""" sm.current = 'notebook' def save(self, *args): """Save the note.""" if self.notebody_textinput.text.strip() != '': if self.note_name_ti.text != '': self._name = self.note_name_ti.text if app_variables.active_note is None: # If we're adding a new note # Add note to database note_manager.new_obj(self._name, self.notebody_textinput.text.strip(), app_variables.active_notebook) else: # If we're editing an existing note_manager.update_obj(app_variables.active_note, name=self._name, data=self.notebody_textinput.text) self.note_name_ti.text = '' self.notebody_textinput.text = '' # Update note list app_variables.notes = note_manager.load() def load(self, *args): """ Loads data and populates TextInput widgets. I had to take away the y hint to use the ScrollView Widget, which led to a crappy resizing while typing behavior. Working on a better solution. """ if app_variables.active_note is not None: # Fill the TextInputs with the note data self.note_name_ti.text = app_variables.get_note_obj( app_variables.active_note)[1] self.notebody_textinput.text = app_variables.get_note_obj( app_variables.active_note)[3] else: self.note_name_ti.text = '' # New note self.notebody_textinput.text = '' def delete(self, *args): """Deletes Note.""" if app_variables.active_note is not None: # If this isn't a new note note_manager.delete(app_variables.active_note) app_variables.notes = note_manager.load() app_variables.active_note = None # Hacky workaround to deal with save method self.notebody_textinput.text = '' sm.current = 'notebook' def textinput_height(self, *args): max_var = max(self.notebody_textinput.minimum_height, self.body_scroll.height) self.notebody_textinput.height = max_var
def __init__(self, dataList, title): self.name = "editabletable" super(EditableTable, self).__init__() parent_layout = FloatLayout() self.title = str(title) scroll_layout = ScrollView(size_hint=(1, None), size=(Window.width, Window.height)) scroll_layout.bind(size=self._update_rect, pos=self._update_rect) table_layout = GridLayout(cols=len(dataList[0]) + 1, size_hint_y=None, spacing=5) table_layout.bind(minimum_height=table_layout.setter('height')) # table_layout.bind(size=self._update_rect, pos=self._update_rect) length = len(dataList[0]) # # for record in dataList: # # for p, column in enumerate(record): # if len(str(column)) > sizes[p]: # sizes[p] = len(str(column)) + 3 self.company = Button(text='Back|', color=(0, 0, 0, 1), background_color=(0, 0, 0, 0), font_size=20, on_press=self.back, pos_hint={'center_x': 0.12, 'center_y': 0.95}) table_layout.add_widget(self.company) # self.company.bind(on_press=lambda m: print("hello")) table_layout.add_widget(Label(text="KAKABOKA", size_hint_y=None, color=(0, 0, 0, 1), font_size=20, )) i = 0 while i < length - 1: table_layout.add_widget(Label(text="", size_hint_y=None, height=50)) i = i + 1 dataList[0].reverse() for i, row_data in enumerate(dataList[0]): t = Label(text=row_data, size_hint_y=None, height=40, color=(0, 0, 0, 1)) table_layout.add_widget(t, index=i) table_layout.add_widget(Label(text="")) dataList = dataList[1:] for row_n, row_data in enumerate(dataList): row_data.reverse() row_data.append("") for i, row in enumerate(row_data): new_row = row_data t = TextInput(hint_text=str(row), text=str(row), disabled=True, size_hint_y=None, height=40, multiline=False) if i <= length - 1: table_layout.add_widget(t, index=i) def changeText(event, data): new_row[i] = data print(data) t.bind(text=changeText) else: btn = Button(text="Edit", size_hint_y=None, height=40) btn.barcode_prop = StringProperty() btn.category_prop = StringProperty() btn.barcode_prop = row_data[5] btn.category_prop = row_data[0] btn.bind(on_press=self.updateRecord) table_layout.add_widget(btn) with scroll_layout.canvas.before: base_folder = os.path.dirname(__file__) image_path = os.path.join(base_folder, 'background.png') self.rect = Rectangle(source=image_path, size=scroll_layout.size, pos=scroll_layout.pos) scroll_layout.add_widget(table_layout) self.add_widget(scroll_layout) self.add_widget(parent_layout)
class MessageWidget(BoxLayout): def __init__(self, *args, **kwargs): super(MessageWidget, self).__init__(*args, **kwargs) self.orientation = 'vertical' self.master_layout = ScrollView(size_hint=(1, 1)) self.master_layout.bind(size=self.master_layout.setter('size')) self.message_layout = GridLayout(cols=1, spacing=10, size_hint_y=None) self.message_layout.bind( minimum_height=self.message_layout.setter('height')) self.sub_layout = GridLayout(cols=1, spacing=10, size_hint_y=None) self.sub_layout.bind(minimum_height=self.sub_layout.setter('height')) bkgrnd_color = (0, 0, 0, 1) self.set_background(self, bkgrnd_color) self.users = {} self.logger = logging.getLogger("kivy.operator.widgets.messaging") self.messages = defaultdict(list) Window.softinput_mode = 'pan' self.chatting = None self.reply = TextInput() self.main_app = App.get_running_app() self.check_xmpp() self.new_lab = Label() self.new = False def set_background(self, layout, color): """ Sets a solid color as a background. :param layout: The layout for whichever part of the screen should be set. """ layout.bind(size=self._update_rect, pos=self._update_rect) with layout.canvas.before: Color(1, 1, 1, 1) self.rect = Rectangle(size=layout.size, pos=layout.pos) def _update_rect(self, instance, value): """ Ensures that the canvas fits to the screen should the layout ever change. """ self.rect.pos = instance.pos self.rect.size = instance.size def redraw(self, event, args): """ Binds the size of the label background to the label size. """ event.bg_rect.size = event.size event.bg_rect.pos = event.pos def get_users(self): """ Pulls the list of users on the XMPP server. """ users = self.main_app.get_users() self.users = {} for user in users: self.users[user.split('@')[0]] = user self.users['Operator Group'] = '*****@*****.**' self.main_app.xmpp_log('info', 'updating user list') if not self.chatting: self.gen_menu() @run_on_ui_thread def check_xmpp(self): """ Check if xmpp is enabled. """ if self.main_app.xmpp_config_ok: self.gen_menu() else: self.disabled_menu() def disabled_menu(self): """ Creates a disabled messaging menu should xmpp be disabled. """ self.clear_widgets() sub_layout = BoxLayout(size_hint=(1, 1)) sub_layout.clear_widgets() lab = Label(text='XMPP messaging is disabled due to config errors!', size_hint=(1, 1), markup=True) lab.color = colorsys.hsv_to_rgb(0, 0, 1) with lab.canvas.before: Color(1, 1, 0, mode='hsv') lab.bg_rect = Rectangle(pos=self.pos, size=self.size) lab.bind(pos=self.redraw, size=self.redraw) sub_layout.add_widget(lab) self.add_widget(sub_layout) def gen_menu(self): """ Creates the base menu which displays all users. """ self.chatting = None self.clear_widgets() self.master_layout.clear_widgets() self.message_layout.clear_widgets() sub_layout = GridLayout(cols=1, spacing=10, size_hint_y=None) sub_layout.bind(minimum_height=sub_layout.setter('height')) sub_layout.clear_widgets() names = [] for user in self.users: names.append(user) names.sort() op_chat = Button(text='Group Chat: OPERATOR', size_hint_y=None, height=180, color=[0, 0, 0, 1], on_release=functools.partial(self.chat_panel, 'Operator Group'), background_normal='', background_color=[.5, 1, .5, 1]) sub_layout.add_widget(op_chat) for name in names: lab = Button(text=name, size_hint_y=None, height=100, color=[1, 1, 1, 1], on_release=functools.partial(self.chat_panel, name), background_normal='', background_color=[0, .3, .3, 1]) sub_layout.add_widget(lab) refresh = Button(text="Refresh Users", size_hint_y=None, on_release=lambda x: self.get_users(), height=180, color=[0, 0, 0, 1], background_normal='', background_color=[0, 1, 0, 1]) self.message_layout.add_widget(refresh) self.message_layout.add_widget(sub_layout) self.master_layout.add_widget(self.message_layout) self.add_widget(self.master_layout) def on_message_receive(self, msg): """ Whenever a message is received, it is processed according to whatever the user is currently doing. :param Message msg: The XMPP message object. """ sender = str(msg['from']).strip() text = str(msg['body']).strip() chk_sender = sender.split('@')[0] if self.chatting == chk_sender: lab = Label(text=chk_sender + ": " + text, size_hint_y=None, markup=True, halign='left') lab.bind(width=lambda s, w: s.setter('text_size')(s, (w, None))) lab.bind(texture_size=lab.setter('size')) lab.color = colorsys.hsv_to_rgb(self.name_to_txt(chk_sender), 1, 1) with lab.canvas.before: Color(name_to_bg(chk_sender), 1, 1, mode='hsv') lab.bg_rect = Rectangle(pos=self.pos, size=self.size) lab.bind(pos=self.redraw, size=self.redraw) self.sub_layout.add_widget(lab) if self.new: self.sub_layout.remove_widget(self.new_lab) self.new = False else: if self.main_app.toast_all: toast(chk_sender + ": " + text, True) vibrator.vibrate(.1) if sender.split('/')[0] in self.messages: self.main_app.xmpp_log('info', 'receiving new message from ' + sender) else: self.main_app.xmpp_log('info', 'receiving first message from ' + sender) m = Message(sender.split('@')[0], text) self.messages[sender.split('/')[0]].append(m) def on_muc_receive(self, msg): """ Whenever a group message is received, it is processed according to whatever the user is currently doing. :param Message msg: The XMPP message object. """ sender = str(msg['from']).strip() text = str(msg['body']).strip() if self.chatting == "Operator Group": lab = Label(text=sender.split('/')[1] + ": " + text, size_hint_y=None, markup=True, halign='left') lab.bind(width=lambda s, w: s.setter('text_size')(s, (w, None))) lab.bind(texture_size=lab.setter('size')) lab.color = colorsys.hsv_to_rgb( self.name_to_txt(sender.split('/')[1]), 1, 1) with lab.canvas.before: Color(name_to_bg(sender.split('/')[1]), 1, 1, mode='hsv') lab.bg_rect = Rectangle(pos=self.pos, size=self.size) lab.bind(pos=self.redraw, size=self.redraw) self.sub_layout.add_widget(lab) if self.new: self.sub_layout.remove_widget(self.new_lab) self.new = False else: toast(sender.split('/')[1] + ": " + text, True) vibrator.vibrate(.1) if sender.split('/')[0] in self.messages: self.main_app.xmpp_log('info', 'receiving new message from ' + sender) else: self.main_app.xmpp_log('info', 'receiving first message from ' + sender) m = Message(sender.split('/')[1], text) self.messages[sender.split('/')[0]].append(m) def chat_panel(self, user, event): """ Creates the actual chat screen where the messages are displayed and where the user can respond. :param str user: The username of whomever the user is chatting with. """ full_name = self.users[user] self.chatting = user self.clear_widgets() self.master_layout.clear_widgets() self.message_layout.clear_widgets() self.sub_layout.clear_widgets() if full_name in self.messages: self.new = False temp = self.messages[full_name] for msg in temp: if not msg.sender: lab = Label(text=msg.body, color=(1, 1, 1, 1), size_hint_y=None, markup=True, halign='right') with lab.canvas.before: Color(.67, .82, 1, mode='hsv') lab.bg_rect = Rectangle(pos=self.pos, size=self.size) else: lab = Label(text=msg.sender + ": " + msg.body, color=(0, 0, 0, 1), size_hint_y=None, markup=True, halign='left') lab.color = colorsys.hsv_to_rgb( self.name_to_txt(msg.sender), 1, 1) with lab.canvas.before: Color(name_to_bg(msg.sender), 1, 1, mode='hsv') lab.bg_rect = Rectangle(pos=self.pos, size=self.size) lab.bind( width=lambda s, w: s.setter('text_size')(s, (w, None))) lab.bind(texture_size=lab.setter('size')) lab.bind(pos=self.redraw, size=self.redraw) self.sub_layout.add_widget(lab) else: self.new_lab = Label(text="Start a new conversation with " + user + "!", color=(0, 0, 0, 1)) self.new = True self.sub_layout.add_widget(self.new_lab) bottom = BoxLayout(size_hint_y=None, height=130) self.reply = TextInput(hint_text="Write a message...") title = Label(text=user, halign='left', color=(0, 0, 0, 1)) send = Button(text="Send", size_hint_x=.25, on_release=functools.partial(self.send_message, full_name)) bottom.add_widget(self.reply) bottom.add_widget(send) header = BoxLayout(size_hint_y=None, height=130) back_btn = Button(text='< Recent', size_hint_x=.5, on_release=lambda x: self.gen_menu()) presence = Label(size_hint_x=.3) header.add_widget(back_btn) header.add_widget(title) header.add_widget(presence) self.message_layout.add_widget(self.sub_layout) self.master_layout.add_widget(self.message_layout) self.add_widget(header) self.add_widget(self.master_layout) self.add_widget(bottom) def send_message(self, user, event): """ When the user hits the reply button, it sends the message back to the user (or group if it is a groupchat). :param str user: The username of whomever the user is chatting with. """ msg = self.reply.text if msg: if user == self.users['Operator Group']: self.main_app.send_muc(msg, user) else: self.main_app.send_message(msg, user) m = Message(None, msg) self.messages[user].append(m) lab = Label(text=msg, size_hint_y=None, color=(1, 1, 1, 1), markup=True, halign='right') lab.bind(width=lambda s, w: s.setter('text_size')(s, (w, None))) lab.bind(texture_size=lab.setter('size')) with lab.canvas.before: Color(.67, .82, 1, mode='hsv') lab.bg_rect = Rectangle(pos=self.pos, size=self.size) lab.bind(pos=self.redraw, size=self.redraw) self.sub_layout.add_widget(lab) self.reply.text = "" if self.new: self.sub_layout.remove_widget(self.new_lab) self.new = False def name_to_txt(self, data): """ Finds the corresponding text color to the background color. :param str data: The same string that is used for the background color. """ rem = name_to_bg(data) dis = rem + 0.5 if dis > 1: dis = dis - 1 return dis