class SideMenu(BoxLayout): def __init__(self, map, **kwargs): super().__init__(**kwargs) self.width = 0 self.scrollView = ScrollView(do_scroll_y=True) self.scrollView.clear_widgets() self.sideMenuItems = [] self.boxView = BoxLayout(orientation="vertical", size_hint_y=None) self.boxView.bind(minimum_height=self.boxView.setter('height')) self.scrollView.add_widget(self.boxView) self.add_widget(self.scrollView) def close(self): self.width = 0 def open(self): self.width = 200 def up(self): for i in range(len(self.sideMenuItems)): if(self.sideMenuItems[i].selected and i > 0): self.selectByIndex(i-1) break def down(self): for i in range(len(self.sideMenuItems)): if(self.sideMenuItems[i].selected and i < len(self.sideMenuItems)): self.selectByIndex(i+1) break def resetColors(self): for sideMenuItem in self.sideMenuItems: sideMenuItem.resetColor() def selectByIndex(self, index): if(len(self.sideMenuItems) > index): self.sideMenuItems[index].selectWithCallback() def select(self, state): for sideMenuItem in self.sideMenuItems: if( sideMenuItem.contentState == state): sideMenuItem.select() def clearItems(self): self.boxView.clear_widgets() self.sideMenuItems = [] def addSideMenuItem(self, sideMenuItem): self.boxView.add_widget(sideMenuItem) self.sideMenuItems.append(sideMenuItem) sideMenuItem.setSideMenu(self) def clearAndAddSideMenuItems(self, sideMenuItems): self.clearItems() for sideMenu in sideMenuItems: self.addSideMenuItem(sideMenu)
class CalendarPanel(BoxLayout): def __init__(self, classes): super(CalendarPanel, self).__init__() self.calendar = CalendarWidget() self.calendar.bind(active_date=self.change_day) self.classes = classes self.selected_courses = list() self.svDay = ScrollView() self.build() def build(self): self.calendar.size_hint = (None,None) self.calendar.size = (400,400) self.calendar.pos_hint = {'top': 1} bltLeft = BoxLayout() bltLeft.add_widget(self.calendar) self.add_widget(bltLeft) bltRight = BoxLayout(orientation='vertical') bltTopRight = BoxLayout(orientation='vertical') lblDay = Label(text='Daily Agenda:', size_hint_y=None, height=30) bltTopRight.add_widget(lblDay) bltTopRight.add_widget(self.svDay) bltRight.add_widget(bltTopRight) bltBottomRight = BoxLayout(orientation='vertical') lblStats = Label(text='Statistics:', size_hint_y=None, height=30) bltBottomRight.add_widget(lblStats) bltRight.add_widget(bltBottomRight) self.add_widget(bltRight) self.change_day() def change_day(self, *args): date = self.calendar.active_date classes = list() for code in self.selected_courses: for c in self.classes.get(code): if c.start.year == date[2]: if c.start.month == date[1]: if c.start.day == date[0]: classes.append(c) self.svDay.clear_widgets() self.svDay.add_widget(DayPanel(classes)) def update_selected_courses(self, courses): self.selected_courses = courses
class ChainScreen(Screen): def __init__(self): self.root = Screen(name="ChainScreen") #data is blockchain self.scroll = ScrollView(size_hint=(1, .6), size=(Window.width, Window.height)) grid = GridLayout(cols=1) self.b = BlockchainDisplay() self.scroll.add_widget(self.b.root) grid.add_widget(self.scroll) #app = App.get_running_app() refresh_chain = Button(text="refresh chain", size_hint_y=.2) refresh_chain.bind(on_press=self.refresh_chain) toolbar = GridLayout(cols=3, size_hint_y=.3) to_network = Button(text="To Netowrk View", size_hint_y=.2) to_network.bind(on_press=self.switch_to_network) switch_page = Button(text="View Current Block", size_hint_y=.2) switch_page.bind(on_press=self.switch_page) toolbar.add_widget(to_network) toolbar.add_widget(switch_page) toolbar.add_widget(refresh_chain) grid2= GridLayout(rows=2) grid2.add_widget(grid) grid2.add_widget(toolbar) self.root.add_widget(grid2) #self.root.add_widget(toolbar) def switch_to_network(self, instance): app = App.get_running_app() app.sm.current = "NetworkScreen" def switch_page(self, instance): app = App.get_running_app() app.sm.current = "CurrentBlockScreen" def refresh_chain(self, instance): app = App.get_running_app() self.scroll.clear_widgets() self.b = BlockchainDisplay() self.scroll.add_widget(self.b.root)
class MainView(FloatLayout): """ Topbar ----------------- full_details """ def __init__(self, ctrl, **kwargs): # Init parent super().__init__(**kwargs) # Create widgets self.sidebar_width = 0.1 self.top_bar_abs_height = 50 self.ctrl = ctrl # Create GUI objects # topbar is always visible self.topbar = Topbar(ctrl=ctrl, size_hint_y=None, height=self.top_bar_abs_height, pos_hint={'top': 1}) self.scroll_view = ScrollView() # Populate GUI objects self.transaction_details = TransactionList(ctrl=self.ctrl) self.eval_view = EvalView(ctrl=self.ctrl) self.num_view = NumbersView(ctrl=self.ctrl) self.update() def update(self): self.ctrl.state = self.topbar.drop_down_button.selection self.clear_widgets() self.scroll_view.clear_widgets() # Calculate dimensions: _, window_height = Window.size top_bar_width = 50.0 / window_height self.scroll_view.size_hint = (1, 1 - top_bar_width) self.add_widget(self.scroll_view) if self.ctrl.state == self.ctrl.TRANSACTIONS: self.scroll_view.add_widget(self.transaction_details) self.transaction_details.update() elif self.ctrl.state == self.ctrl.EVALUATION: self.scroll_view.add_widget(self.eval_view) self.eval_view.update() elif self.ctrl.state == self.ctrl.NUMBERS: self.scroll_view.add_widget(self.num_view) self.num_view.update() self.add_widget(self.topbar)
class ListaTouch(FloatLayout): def __init__(self, listatouch=[], acao=None, img_fundo='blue', **kwargs): super(ListaTouch, self).__init__(**kwargs) self.listatouch = listatouch self.acao = acao self.img_fundo = img_fundo self.scrollview = ScrollView(size_hint=(1, 1), scroll_timeout=250, scroll_distance=20) self.preencher_lista() self.add_widget(self.scrollview) pass def update_lista(self, listatouch=None, acao=None): if listatouch is not None: self.listatouch = listatouch if acao is not None: self.acao = acao self.scrollview.clear_widgets() self.preencher_lista() pass def preencher_lista(self): grade_lista = GridLayout(cols=1, spacing=10, padding=5, orientation='vertical', size_hint=(1, None)) grade_lista.bind(minimum_height=grade_lista.setter('height')) for index, valor in self.listatouch: grade_lista.add_widget( ItemLista(indice=index, acao=self.acao, img_fundo=self.img_fundo, text=valor)) self.scrollview.add_widget(grade_lista) pass
class TraceAnalysisApp(App): icon = 'trace-analysis.png' title = "Trace analysis" def __init__(self): super(TraceAnalysisApp, self).__init__() content = Button(text='Success', size_hint_y=None, height=30) self.popup = Popup(title='Analysis finished', content=content, auto_dismiss=True, size_hint_y=None, height=30) content.bind(on_press=self.popup.dismiss) error_content = Button( text= 'Unknown error encountered when parsing trace. Please try a different trace.', size_hint_y=None, height=30) self.error_in_trace_popup = Popup(title='Error', content=error_content) error_content.bind(on_press=self.error_in_trace_popup.dismiss) self.bl = BoxLayout() self.root = ScrollView(size_hint=(1, None), size=(Window.width, Window.height)) self.root.add_widget(self.bl) self.possible_trace_event_transitions = {} self.reverse_possible_trace_event_transitions = {} self.traceAttrs = {} self.trace_id_to_CSEW_events = {} self.selected_trace_tb = None self.trace_file = None self.trace = None self.trace_ids = {} self.fcl = self.fcl = FileChooserListView( path=os.path.realpath("trace-configurations/"), dirselect=True) # type: FileChooserListView self.fcl.bind(selection=self.selected_traceid_to_csem_events_map_file) self.bl.add_widget(self.fcl) def gen_plots(self, _): if self.trace is not None: self.trace.as_plots() self.popup.open() def gen_xlsx(self, btn: Button): if self.trace is not None: pb = ProgressBar(max=len(self.trace.rows) * 2, value=0, size_hint_y=None, height=30) self.bl.clear_widgets([btn]) self.bl.add_widget(pb, 3) self.trace.regular_as_xlsx(pb, self.popup, self.bl, btn) def parse_trace_file(self): self.root.clear_widgets() gl = GridLayout(cols=1, size_hint_y=None) gl.bind(minimum_height=gl.setter('height')) self.root.add_widget(gl) gl.add_widget( Label(text='Choose what to do with trace ' + self.trace_file.name, size_hint_y=None, height=30)) gen_plots_btn = Button(text="Analyze data and generate plots", size_hint_y=None, height=30) gen_plots_btn.bind(on_press=self.gen_plots) gl.add_widget(gen_plots_btn) gen_xlsx_btn = Button(text="Analyze data and export to excel", size_hint_y=None, height=30) gen_xlsx_btn.bind(on_press=self.gen_xlsx) gl.add_widget(gen_xlsx_btn) decomp_trace_btn = Button(text="Decompress trace", size_hint_y=None, height=30) decomp_trace_btn.bind(on_press=self.decompress_trace) gl.add_widget(decomp_trace_btn) back_btn = Button(text="Back", size_hint_y=None, height=30) back_btn.bind(on_press=self.clear_and_select_trace) gl.add_widget(back_btn) exit_btn = Button(text="Exit", size_hint_y=None, height=30) exit_btn.bind(on_press=lambda _: exit(0)) gl.add_widget(exit_btn) self.trace = Trace(self.trace_file, self.trace_file.name.split(".trace")[0] + ".xlsx", self.trace_ids, self.reverse_possible_trace_event_transitions, self.traceAttrs) if self.trace.collect_data() == -1: self.root.clear_widgets() self.error_in_trace_popup.open() self.select_trace_to_analyze() def selected_trace_file(self, _, selection): self.trace_file = open(selection[0], 'r') self.parse_trace_file() return self.bl def eid_to_event(self, e, cycles): res = self.trace_id_to_CSEW_events.get(e, {}).get('csemEvents', "") return res.replace("[CPU_CYCLES]", str(cycles), -1) def decompress_trace(self, _): if self.trace_file is not None: self.trace_file = open( '../../traces/' + self.selected_trace_tb.text, 'r') output_file = open( "output/processed-" + self.selected_trace_tb.text, "w") output_file.write("EOD\n") i = 0 for l in self.trace_file: line = l.split("\t") if len(line) < 2: break eid = int(line[0]) i += 1 cycles = int(line[3]) output_file.write(self.eid_to_event(eid, cycles) + "\n") output_file.write("H \n") self.popup.open() def select_trace_to_analyze(self): self.fcl.path = os.path.realpath("../../traces/") self.fcl.unbind( selection=self.selected_traceid_to_csem_events_map_file) self.fcl.bind(selection=self.selected_trace_file) return self.fcl def clear_and_select_trace(self, _): return self.select_trace_to_analyze() def selected_traceid_to_csem_events_map_file(self, _, selection): trace_file = open(selection[0], 'r') json_data = trace_file.read() data = json.JSONDecoder( object_pairs_hook=OrderedDict).decode(json_data) self.trace_ids = data['traceIDs'] for k, v in self.trace_ids.items(): for a in v["transitions"]: self.reverse_possible_trace_event_transitions.setdefault( a, [] ).append( k ) # Assume that a given trace Id can only be preceeded by one trace Id self.traceAttrs = data["traceAttributes"] return self.clear_and_select_trace(None) def build(self): return self.root
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 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 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
class ScreenBankGUI(ScreenBank): # Initialize the class. def __init__(self, Data): #Define window size. self.factor = Data.factor Config.set('graphics', 'width', Data.factor*800) Config.set('graphics', 'height', Data.factor*600) # Create main and middle layout self.layout = GridLayout(cols = 1, row_force_default=False, height = 600, width = 800) self.MiddleLayout = GridLayout(cols=1, size_hint_y=11) self.MiddleScroll = ScrollView(size_hint=(1, None), size=(Data.factor*400, Data.factor*500), bar_width=4) self.settings_json = json.dumps([ {'type': 'string', 'title': 'Job Manager IP', 'desc': 'Address of the JM.', 'section': 'example', 'key': 'jm_address'}, {'type': 'numeric', 'title': 'Job Manager Port', 'desc': 'Port of the JM.', 'section': 'example', 'key': 'jm_port'}, {'type': 'path', 'title': 'Library Path', 'desc': 'File with user functions.', 'section': 'example', 'key': 'lib_path'}, {'type': 'numeric', 'title': 'Number of Tasks', 'desc': 'Amount of work to be done.', 'section': 'example', 'key': 'num_tasks'}]) self.settings_json2 = json.dumps([ {'type': 'string', 'title': 'Virtual Machine IP', 'desc': 'Address of the Virtual Machine TM.', 'section': 'example', 'key': 'vm_ip'}, {'type': 'string', 'title': 'Virtual Machine Port', 'desc': 'Port of the Virtual Machine TM.', 'section': 'example', 'key': 'vm_prt'}, {'type': 'string', 'title': 'SSH Login', 'desc': 'Used to log in Virtual Machine TM.', 'section': 'example', 'key': 'ssh_login'}, {'type': 'string', 'title': 'SSH Password', 'desc': 'Look behind you before typing.', 'section': 'example', 'key': 'ssh_pass'}]) self.settings_json3 = json.dumps([ {'type': 'bool', 'title': 'SSH Port Fowarding', 'desc': 'Activate/Deactivate for connecting with Job Manager', 'section': 'example', 'key': 'ssh_pf_bool'}, {'type': 'string', 'title': 'SSH Login', 'desc': 'Username used in SSH connection.', 'section': 'example', 'key': 'ssh_pf_login'}, {'type': 'string', 'title': 'SSH Password', 'desc': 'Look behind you before typing.', 'section': 'example', 'key': 'ssh_pf_pass'}]) self.settings_json4 = json.dumps([ {'type': 'string', 'title': 'Subscription ID', 'desc': 'ID obtained in Azure.', 'section': 'example', 'key': 'subscription_id'}, {'type': 'path', 'title': 'Certificate Path', 'desc': 'Location of the path sent to Azure.', 'section': 'example', 'key': 'certificate_path'}]) # Layout that represents the list. self.ListLayout = GridLayout(cols=len(Data.columns), row_default_height=Data.factor*30, row_force_default = True, rows=(Data.npp + 1) , size_hint_y=10) self.NavigationLayout = GridLayout(cols=2, row_default_height=Data.factor*15) # Layout that represents the VMlist.. self.VMListLayout = GridLayout(cols=len(Data.VMcolumns), row_default_height=Data.factor*30, row_force_default = True, rows=(Data.npp + 1) , size_hint_y=10) self.VMNavigationLayout = GridLayout(cols=2, row_default_height=Data.factor*15) # Layout that represents the log self.LogWidget = TextInput(multiline=True) # Layout that represents the main Header self.HeaderLayout = GridLayout(cols=7, row_default_height=Data.factor*15) # Name of current screen self.ScreenName = "List" # Task FIFOs self.workerFIFO = FIFO() self.mainFIFO = FIFO() #Extra Thread self.WorkerThread = threading.Thread(target=self.worker) self.WorkerThread.start() # Set consume as callback function Clock.schedule_interval(self.consume, 0.1) # Worker function. def worker(self): print 'worker' while(self.workerFIFO.task_end == False): # Check if it's over. self.workerFIFO.pendent_tasks.acquire() # Wait for tasks task = self.workerFIFO.popTask() # Pop task self.workerFIFO.runOneTask(task) # Run the task print 'Worker exited.' return # Function to kill/remove worker from tasks FIFO and exit. def quitWorker(self): self.workerFIFO.task_end = True # Mark as ended. self.workerFIFO.task_FIFO_mutex.acquire() # Add empty task self.workerFIFO.task_FIFO.append([1, None, []]) self.workerFIFO.task_FIFO_mutex.release() self.workerFIFO.pendent_tasks.release() # Release, it may be stopped def consume(self, *args): while (self.mainFIFO.tasks_in_FIFO > 0): task = self.mainFIFO.popTask() print 'Consuming:' + str(task) self.mainFIFO.runOneTask(task) # Build the main screen, with header, list, navigation and command. def buildMainScreen(self, Data): # Make header layout and add to the main. self.makeHeaderLayout() self.layout.add_widget(self.HeaderLayout) # Make list rows and add it to the middle layout self.MiddleLayout.add_widget(self.ListLayout) # Build list screen and add Middle Layout to the main layout. self.buildListScreen() self.layout.add_widget(self.MiddleLayout) # Make Console Layout and add it to the main layout self.CommandLayout = GridLayout(cols=1, row_default_height=Data.factor*30, row_force_default=True) self.makeCommandLayout(Data, 'Welcome to SPITZ Monitor') self.layout.add_widget(self.CommandLayout) self.reDrawList(Data) # Build the list screen, just updating the middle layout. def buildListScreen(self): self.MiddleLayout.clear_widgets() self.MiddleLayout.add_widget(self.ListLayout) self.MiddleLayout.add_widget(self.NavigationLayout) # Build the list screen, just updating the middle layout. def buildVMListScreen(self): self.MiddleLayout.clear_widgets() self.MiddleLayout.add_widget(self.VMListLayout) self.MiddleLayout.add_widget(self.VMNavigationLayout) # Build the log screen, just updating the middle layout. def buildLogScreen(self): self.MiddleLayout.clear_widgets() self.MiddleScroll.clear_widgets() self.LogWidget.size_hint_y = None self.LogWidget.height = max( (len(self.LogWidget._lines)+1) * self.LogWidget.line_height, self.MiddleScroll.size[1]) self.MiddleScroll.do_scroll_x = False self.MiddleScroll.add_widget(self.LogWidget) self.MiddleLayout.add_widget(self.MiddleScroll) # Build the Settings screen. def buildSettingsScreen(self): Runner.MyApp.open_settings(self.AppInstance) #self.layout.add_widget(self.sett) # Makes the layout of the list, adding the columns name, the ordering handlers and the actual page. def makeListLayout(self, Data): layout = self.ListLayout layout.clear_widgets() for col in range(len(Data.columns)): btnO = Button(text=Data.columns[col], size_hint_x=None, width=Data.wid[col]) btnO.bind(on_press=buttonOrder) layout.add_widget(btnO) upper = min(len(Data.rows), (Data.index + 1)*Data.npp) #print "upper: "+str(upper) for i in range(Data.index*Data.npp, upper): for j in range(len(Data.wid)): layout.add_widget(Button(text=str(Data.rows[i][j]), size_hint_x=None, width=Data.wid[j])) self.ListLayout = layout # Makes the buttons to navigate. Add the handler and text if there is any. def makeNavigationLayout(self, Data): layout = self.NavigationLayout layout.clear_widgets() if(Data.index > 0): btnP = Button(text="Previous", size_hint_x=None, width = Data.factor*400) btnP.bind(on_press = buttonPrev) layout.add_widget(btnP) else: layout.add_widget(Button(text="", size_hint_x=None, width = Data.factor*400)) if(len(Data.rows)>(Data.index + 1)*Data.npp): btnN = Button(text="Next", size_hint_x=None, width = Data.factor*400) btnN.bind(on_press = buttonNext) layout.add_widget(btnN) else: layout.add_widget(Button(text="", size_hint_x=None, width = Data.factor*400)) self.NavigationLayout = layout # Makes the layout of the VM list, adding the columns name, the ordering handlers and the actual page. def makeVMListLayout(self, Data): layout = self.VMListLayout layout.clear_widgets() for col in range(len(Data.VMcolumns)): btnO = Button(text=Data.VMcolumns[col], size_hint_x=None, width=Data.VMwid[col]) btnO.bind(on_press=buttonVMOrder) layout.add_widget(btnO) upper = min(len(Data.VMrows), (Data.index + 1)*Data.npp) #print "upper: "+str(upper) for i in range(Data.index*Data.npp, upper): # Create buttons. Actions buttons has actions. for j in range(len(Data.VMwid)): if j == len(Data.VMwid)-1: # Button responsible for VM action, as it has different index and action, calls partial functions. btnA = Button(text=str(Data.VMrows[i][len(Data.VMwid)-1]), size_hint_x=None, width=Data.VMwid[-1]) btnA.bind(on_press=partial(buttonSpitzAction, i, btnA.text)) layout.add_widget(btnA) elif j == len(Data.VMwid)-3: # Button responsible for VM action, as it has different index and action, calls partial functions. btnA = Button(text=str(Data.VMrows[i][len(Data.VMwid)-3]), size_hint_x=None, width=Data.VMwid[-3]) btnA.bind(on_press=partial(buttonAzureAction, i, btnA.text)) layout.add_widget(btnA) else: layout.add_widget(Button(text=str(Data.VMrows[i][j]), size_hint_x=None, width=Data.VMwid[j])) self.VMListLayout = layout # Makes the buttons to navigate the VM list. Add the handler and text if there is any. def makeVMNavigationLayout(self, Data): layout = self.VMNavigationLayout layout.clear_widgets() if(Data.index > 0): btnP = Button(text="Previous", size_hint_x=None, width = Data.factor*400) btnP.bind(on_press = VMbuttonPrev) layout.add_widget(btnP) else: layout.add_widget(Button(text="", size_hint_x=None, width = Data.factor*400)) if(len(Data.rows)>(Data.index + 1)*Data.npp): btnN = Button(text="Next", size_hint_x=None, width = Data.factor*400) btnN.bind(on_press = VMbuttonNext) layout.add_widget(btnN) else: layout.add_widget(Button(text="", size_hint_x=None, width = Data.factor*400)) self.VMNavigationLayout = layout # Makes the header layout, with the commands. def makeHeaderLayout(self): layout = self.HeaderLayout layout.clear_widgets() self.btnP = Button(text="Update", size_hint_x=None, width = self.factor*125) self.btnP.bind(on_press = buttonUpdate) layout.add_widget(self.btnP) btnSep = Button(text="", size_hint_x=None, width = self.factor*50) layout.add_widget(btnSep) self.btnLi = ToggleButton(text="List", group='menu', size_hint_x=None, width = self.factor*125, state='down') self.btnLi.bind(on_press = buttonList) layout.add_widget(self.btnLi) self.btnV = ToggleButton(text="VM Launcher", group='menu', size_hint_x=None, width = self.factor*125) self.btnV.bind(on_press = buttonVM) layout.add_widget(self.btnV) self.btnSta = ToggleButton(text="Statistics", group='menu', size_hint_x=None, width = self.factor*125) self.btnSta.bind(on_press = buttonStatistics) layout.add_widget(self.btnSta) self.btnL = ToggleButton(text="Log", group='menu', size_hint_x=None, width = self.factor*125) self.btnL.bind(on_press = buttonLog) layout.add_widget(self.btnL) self.btnS = Button(text="Settings", size_hint_x=None, width = self.factor*125) self.btnS.bind(on_press = buttonSettings) layout.add_widget(self.btnS) def makeCommandLayout(self, Data, itext): layout = self.CommandLayout layout.clear_widgets() self.commandWidget = TextInput(multiline=False) self.commandWidget.readonly = True self.commandWidget.text = itext pb = ProgressBar(max=1000) pb.value = (Data.total_compl*1000)/(int(Data.TotalTasks)) layout.add_widget(self.commandWidget) layout.add_widget(pb) #Get current time and add the message to the log pile. logmessage = datetime.now().strftime('%Y-%m-%d %H:%M:%S') logmessage = logmessage + " >>> " + itext Data.log = Data.log + "\n" + logmessage # Redraw list using current values of nodes. def reDrawList(self, Data): self.makeListLayout(Data) self.makeNavigationLayout(Data) def makeLogLayout(self, Data): self.LogWidget.readonly = True self.LogWidget.text = Data.log def screenChange(self, value, name): self.ScreenName = name if(value.state == 'normal'): value.state = 'down'
class AssetsEditorPopup(): def __init__(self, **kwargs): self.engineConfig = kwargs.get("engineConfig") self.currentAsset = kwargs.get("currentAsset") self.engineRoot = kwargs.get("engineRoot") self.assetsStore = JsonStore('projects/' + self.engineConfig.currentProjectName + '/data/assets.json') self.isFreeRigthBox = True self.box = BoxLayout(orientation="horizontal") self.leftBox = BoxLayout(orientation="vertical") self.imageResourceGUIBox = BoxLayout(orientation="vertical") if platform == 'linux': drives = psutil.disk_partitions() if platform == 'win': drives = [ '%s:' % d for d in string.ascii_uppercase if os.path.exists('%s:' % d) ] self.drivesChooseBox = BoxLayout( size_hint=(1, None), height=40, ) for item in drives: if platform == 'win': self.drivesChooseBox.add_widget( Button(text=item + '/', on_press=partial(self.setFileBrowserPath), color=(self.engineConfig.getThemeTextColor()), size_hint=(1, None), height=65, background_normal='', background_color=( self.engineConfig.getThemeCustomColor( 'engineBtnsBackground')))) print(" drive: ", item) elif platform == 'linux' or True: self.drivesChooseBox.add_widget( Button(text=item.mountpoint, on_press=partial(self.setFileBrowserPath), color=(self.engineConfig.getThemeTextColor()), size_hint=(1, None), height=65, background_normal='', background_color=( self.engineConfig.getThemeCustomColor( 'engineBtnsBackground')))) print(" drive: ", item) self.imageResourceGUIBox.add_widget(self.drivesChooseBox) if platform == 'win': self.fileBrowser = FileChooserListView( # Can be added default optimal engine config initial dir # select_string='Select', dirselect: True # path='projects/' + self.engineConfig.currentProjectName + '/data/', filters=['*.png', '*.jpg'], path=drives[1] + '/', size_hint=(1, 3), dirselect=False, on_submit=self.load_from_filechooser) elif platform == 'linux' or True: self.fileBrowser = FileChooserListView( # select_string='Select', dirselect: True # path='projects/' + self.engineConfig.currentProjectName + '/data/', filters=['*.png', '*.jpg'], path=drives[0].mountpoint + '/', size_hint=(1, 3), dirselect=True, on_submit=self.load_from_filechooser) self.imageResourceGUIBox.add_widget(self.fileBrowser) self.fileBrowser.bind(selection=partial(self.load_from_filechooser)) self.imageResourceGUIBox.add_widget( Label(text='Application assets full source path:', size_hint=(1, None), height=40, font_size=15)) self.selectedPathLabel = Label(text='...', size_hint=(1, None), height=40, font_size=9, underline=True) self.imageResourceGUIBox.add_widget(self.selectedPathLabel) self.imageResourceGUIBox.add_widget( Label(text='Application assets relative path:', size_hint=(1, None), height=40)) self.selectedRelativePathLabel = Button( text='...', size_hint=(1, None), height=40, font_size=12, underline=True, on_press=partial(self.copyToClipBoard), color=(self.engineConfig.getThemeTextColor()), background_normal='', background_color=( self.engineConfig.getThemeCustomColor('engineBtnsBackground')), ) self.imageResourceGUIBox.add_widget(self.selectedRelativePathLabel) self.assetNameGUINAme = Label( text='Name of assets reference (READ ONLY)', color=(self.engineConfig.getThemeTextColor()), font_size=15, size_hint=(1, None), height=40) self.imageResourceGUIBox.add_widget(self.assetNameGUINAme) self.assetName = Label(text='MyAssets1', color=(self.engineConfig.getThemeTextColor()), font_size=12, underline=True, size_hint=(1, None), height=40) with self.assetName.canvas.before: Color( self.engineConfig.getThemeCustomColor('warn')[0], self.engineConfig.getThemeCustomColor('warn')[1], self.engineConfig.getThemeCustomColor('warn')[2], self.engineConfig.getThemeCustomColor('warn')[3]) self.assetName.rect = Rectangle(size=self.assetName.size, pos=self.assetName.pos) def update_rect(instance, value): instance.rect.pos = instance.pos instance.rect.size = instance.size self.imageResourceGUIBox.add_widget(self.assetName) self.imageResourceGUIBox.add_widget( Button(text='Update selected image asset', color=(self.engineConfig.getThemeTextColor()), size_hint=(1, None), height=65, font_size=15, bold=True, background_normal='', background_color=(self.engineConfig.getThemeCustomColor( 'engineBtnsBackground')), on_press=partial(self.createImageAssets))) self.leftBox.add_widget( Label(text='CrossK assets editor', size_hint=(1, None), height=220, font_size=25, bold=True)) assetListHeder = BoxLayout(size_hint=(1, None), height=80) titleText = Label(text='Assets List.', color=(self.engineConfig.getThemeTextColor()), font_size=25, bold=True, padding_x=0, padding_y=0, center=(1, 1), size_hint_x=1, size_hint_y=1, height=60) with titleText.canvas.before: Color(self.engineConfig.getThemeBgSceneBtnColor()) titleText.rect = Rectangle(size=titleText.size, pos=titleText.pos) def update_rect(instance, value): instance.rect.pos = instance.pos instance.rect.size = instance.size self.leftBox.add_widget(titleText) titleText.bind(pos=update_rect, size=update_rect) headerSelector = Label( text='Selector', color=(self.engineConfig.getThemeTextColor()), font_size=15, # add bold=True, # add padding_x=0, # test padding_y=0, # test center=(1, 1), # test font_blended=True, size_hint_x=1, size_hint_y=None, height=40) with headerSelector.canvas.before: Color( self.engineConfig.getThemeTextColorByComp('background')['r'], self.engineConfig.getThemeTextColorByComp('background')['g'], self.engineConfig.getThemeTextColorByComp('background')['b']) headerSelector.rect = Rectangle(size=headerSelector.size, pos=headerSelector.pos) def update_rect(instance, value): instance.rect.pos = instance.pos instance.rect.size = instance.size headerSelector.bind(pos=update_rect, size=update_rect) assetListHeder.add_widget(headerSelector) headerPreview = Label( text='Preview', color=(self.engineConfig.getThemeTextColor()), font_size=15, # add bold=True, # add padding_x=0, # test padding_y=0, # test center=(1, 1), # test font_blended=True, size_hint_x=0.3, size_hint_y=None, height=40) with headerPreview.canvas.before: Color( self.engineConfig.getThemeTextColorByComp('background')['r'], self.engineConfig.getThemeTextColorByComp('background')['g'], self.engineConfig.getThemeTextColorByComp('background')['b']) headerPreview.rect = Rectangle(size=headerPreview.size, pos=headerPreview.pos) def update_rect(instance, value): instance.rect.pos = instance.pos instance.rect.size = instance.size headerPreview.bind(pos=update_rect, size=update_rect) assetListHeder.add_widget(headerPreview) headerDelete = Label( text='Note: No undo operation', color=(self.engineConfig.getThemeTextColor()), font_size=15, # add bold=True, # add padding_x=0, # test padding_y=0, # test center=(1, 1), # test font_blended=True, size_hint_x=1, size_hint_y=None, height=40) with headerDelete.canvas.before: Color( self.engineConfig.getThemeTextColorByComp('background')['r'], self.engineConfig.getThemeTextColorByComp('background')['g'], self.engineConfig.getThemeTextColorByComp('background')['b']) headerDelete.rect = Rectangle(size=headerDelete.size, pos=headerDelete.pos) def update_rect(instance, value): instance.rect.pos = instance.pos instance.rect.size = instance.size headerDelete.bind(pos=update_rect, size=update_rect) assetListHeder.add_widget(headerDelete) self.leftBox.add_widget(assetListHeder) loadAssetElements = self.assetsStore.get( 'assetsComponentArray')['elements'] self.sceneScroller = ScrollView(size_hint=(1, None), size=(500, 650), pos_hint={ 'center_x': 0.5, 'top': 0 }) self.selfUpdate(loadAssetElements) self.leftBox.add_widget(self.sceneScroller) fillSpace = Label(text='---', size_hint=(1, 0.3)) with fillSpace.canvas.before: Color( self.engineConfig.getThemeTextColorByComp('background')['r'], self.engineConfig.getThemeTextColorByComp('background')['g'], self.engineConfig.getThemeTextColorByComp('background')['b']) fillSpace.rect = Rectangle(size=fillSpace.size, pos=fillSpace.pos) def update_rect(instance, value): instance.rect.pos = instance.pos instance.rect.size = instance.size self.leftBox.add_widget(fillSpace) fillSpace.bind(pos=update_rect, size=update_rect) self.cancelBtn = Button( text='Cancel', color=(self.engineConfig.getThemeTextColor()), size_hint=(1, None), height=70, background_normal='', background_color=( self.engineConfig.getThemeCustomColor('engineBtnsBackground'))) self.previewBox = BoxLayout(size_hint=(1, None), height=250) self.previewPicture = AsyncImage(source="", size_hint=(1, 1)) self.previewFont = Label(size_hint=(1, 1), markup=True, font_size=50, text="Font [b]Bold[/b]!") self.previewBox.add_widget( Label(text='Preview Box', bold=True, font_size=15)) self.previewBox.add_widget(self.previewPicture) self.previewBox.add_widget(self.previewFont) self.imageResourceGUIBox.add_widget(self.previewBox) self.box.add_widget(self.leftBox) self.leftBox.add_widget(self.cancelBtn) _local = 'CrossK ' + self.engineConfig.getVersion() + ' Assets Editor' self.popup = Popup(title=_local, content=self.box, auto_dismiss=False) self.cancelBtn.bind(on_press=self.popup.dismiss) self.popup.open() def showAssetGUI(self, item, instance): if (platform == 'win'): transformPath = item['path'].replace('/', '\\') else: transformPath = item['path'] if item['type'] == 'ImageResource': if self.isFreeRigthBox == True: self.box.add_widget(self.imageResourceGUIBox) self.isFreeRigthBox = False self.assetName.text = item['name'] self.selectedPathLabel.text = item['source'] self.selectedRelativePathLabel.text = item['path'] self.previewPicture.source = transformPath self.previewFont.size_hint = (0, 0) self.previewPicture.size_hint = (1, 1) elif item['type'] == 'FontResource': if self.isFreeRigthBox == True: self.box.add_widget(self.imageResourceGUIBox) self.isFreeRigthBox = False self.assetName.text = item['name'] self.selectedPathLabel.text = item['source'] self.selectedRelativePathLabel.text = item['path'] self.previewPicture.size_hint = (0, 0) self.previewPicture.size = (5, 5) self.previewFont.text = "Font [b]Bold[/b]!" self.previewFont.size_hint = (1, 1) self.previewFont.font_name = item['path'] elif item['type'] == 'JSONResource': self.fileBrowser.filters = ["*.json"] if self.isFreeRigthBox == True: self.box.add_widget(self.imageResourceGUIBox) self.isFreeRigthBox = False self.assetName.text = item['name'] self.selectedPathLabel.text = item['source'] self.selectedRelativePathLabel.text = item['path'] self.previewPicture.size_hint = (0, 0) self.previewPicture.size = (5, 5) self.previewFont.size_hint = (1, 1) # nikola 0.5.0 localStore = JsonStore(item['path']) print(">>>>>>>>>>>>>>>" + localStore.get('name')) self.previewFont.font_size = "10" self.previewFont.text = "JSON root keys: \n " for key in localStore._data.keys(): self.previewFont.text += " " + key + "\n" # localStore.get('name') print(key) def copyToClipBoard(self, instance): Clipboard.copy(self.selectedRelativePathLabel.text) print('Copied to clipboard.') def resolvePathFolder(self): ASSETPACK_PATH = os.path.abspath( os.path.join( os.path.dirname(__file__), '../../projects/' + self.engineConfig.currentProjectName + "/data/")) if not os.path.exists(ASSETPACK_PATH): print("MAKE_ASSETPACK_PATH") os.mkdir(ASSETPACK_PATH) else: print('ASSETPACK_EXIST') def resolveAssetPathFolder(self): if len(self.fileBrowser.selection) == 0: def wtf(): print('wtf') getMessageBoxYesNo( message="Nothing to update. Please select new source file.", msgType="OK", callback=wtf) return 0 CURRENT_ASSETPACK_PATH = os.path.abspath( os.path.join( os.path.dirname(__file__), '../../projects/' + self.engineConfig.currentProjectName + "/data/" + self.assetName.text)) collectExt = '' print("Create Image Resource ->") local = self.fileBrowser.selection[0][::-1] for item in local: if item == '.': print("Create Image Resource -> Break EXT = ", collectExt) break else: collectExt += item collectExt = collectExt[::-1] print(collectExt) if not os.path.exists(CURRENT_ASSETPACK_PATH): print("MAKE ASSETS PACK DIR") os.mkdir(CURRENT_ASSETPACK_PATH) else: if self.currentAsset == None: print('current asset need load') print("SOMETHIND WRONG - ASSETS ALREADY EXIST") return None print("Assets pack write meta data.") copyfile( self.fileBrowser.selection[0], CURRENT_ASSETPACK_PATH + '/' + str(self.assetName.text) + '.' + collectExt) self.assetsStore = JsonStore( self.engineConfig.currentProjectAssetPath + '/assets.json') localElements = self.assetsStore.get( 'assetsComponentArray')['elements'] ######################## # Must be detail show if self.currentAsset != None: print('# Must be detail show') ######################## asset = { 'name': self.assetName.text, 'type': 'ImageResource', 'ext': collectExt, 'source': CURRENT_ASSETPACK_PATH + '/' + str(self.assetName.text) + '.' + collectExt, 'path': 'projects/' + self.engineConfig.currentProjectName + "/data/" + str(self.assetName.text) + "/" + str(self.assetName.text) + "." + collectExt, 'version': self.engineConfig.getVersion() } localCheckIsExist = False for _index, item in enumerate(localElements): if item['name'] == asset['name']: localCheckIsExist = True localElements[_index] = asset def catchErr1(): print("catchErr1") if localCheckIsExist == True: self.assetsStore.put('assetsComponentArray', elements=localElements) # resourceGUIContainer self.popup.dismiss() else: getMessageBoxYesNo( message='Something wrong with updating asset name => ' + asset['name'], msgType='OK', callback=catchErr1) def createImageAssets(self, instance): print("Creating first assets ... ") # resolvePathFolder self.resolvePathFolder() self.resolveAssetPathFolder() def deleteAsset(self, item, instance): self.assetsStore = JsonStore('projects/' + self.engineConfig.currentProjectName + '/data/assets.json') currElements = self.assetsStore.get('assetsComponentArray')['elements'] isDeleted = False for index, itemA in enumerate(currElements): if itemA['name'] == item['name']: currElements.pop(index) isDeleted = True self.assetsStore.put('assetsComponentArray', elements=currElements) break if isDeleted == True: self.engineRoot.resourceGUIContainer.selfUpdate() self.selfUpdate(currElements) rmtree('projects/' + self.engineConfig.currentProjectName + '/data/' + item['name']) else: getMessageBoxYesNo( message="Something wrong with delete operation.", msgType="OK", callback=wtf) def load_from_filechooser(self, instance, selectedData): # Selector if str(self.fileBrowser.selection[0]).find('.png') != -1 or str( self.fileBrowser.selection[0]).find('.jpg') != -1: print("Found!") else: print("Not found!") return None self.selectedPathLabel.text = self.fileBrowser.selection[0] self.previewPicture.source = self.fileBrowser.selection[0] def setFileBrowserPath(self, instance): self.fileBrowser.path = instance.text print('Selected:', instance.text) def selfUpdate(self, loadAssetElements): alllocalBox = BoxLayout(size_hint=(1, None), height=len(loadAssetElements) * 90, orientation='vertical') for _index, item in enumerate(loadAssetElements): localBox = BoxLayout(size_hint=(1, None), height=90, orientation='horizontal') currentColor = (self.engineConfig.getThemeBgSceneBtnColor()) if item['type'] == 'ImageResource': currentColor = (self.engineConfig.getThemeBgSceneBoxColor()) localBox.add_widget( Button(markup=True, halign="left", valign="middle", padding_x=10, font_size=15, text='[b]' + item['name'] + '[/b] [u][i]' + item['type'] + '[/i][/u]', color=self.engineConfig.getThemeTextColor(), background_normal='', background_color=currentColor, on_press=partial(self.showAssetGUI, item), size_hint=(1, None), height=90)) if item['type'] == 'ImageResource': localPrevListBox = AsyncImage(source=item['path'], size_hint=(0.4, None), height=90) with localPrevListBox.canvas.before: Color( self.engineConfig.getThemeCustomColor('background')[0], self.engineConfig.getThemeCustomColor('background')[1], self.engineConfig.getThemeCustomColor('background')[2], self.engineConfig.getThemeCustomColor('background')[3]) localPrevListBox.rect = Rectangle( size=localPrevListBox.size, pos=localPrevListBox.pos) def update_rect(instance, value): instance.rect.pos = instance.pos instance.rect.size = instance.size localPrevListBox.bind(pos=update_rect, size=update_rect) localBox.add_widget(localPrevListBox) elif item['type'] == 'FontResource': localBox.add_widget( Label(font_name=item['path'], size_hint=(0.4, None), height=90, text='Font')) elif item['type'] == 'JSONResource': localBox.add_widget( Label(size_hint=(0.4, None), height=90, text='JSON DATA')) localBox.add_widget( Button( markup=True, halign="left", valign="middle", padding_x=10, font_size=15, text='[b]Delete[/b]', color=(self.engineConfig.getThemeCustomColor("alert")), background_normal='', background_color=( self.engineConfig.getThemeCustomColor('background')), on_press=partial(self.deleteAsset, item), size_hint=(1, None), height=90)) print('ADDED ', item) alllocalBox.add_widget(localBox) self.sceneScroller.clear_widgets() self.sceneScroller.add_widget(alllocalBox)
class Screen2(Screen): def __init__(self, config_list, **kwargs): super(Screen2, self).__init__(**kwargs) self.config_list=config_list try: self.config_list[3][4] except: self.config_list[3].append([]) self.layout = FloatLayout() #self.layout.add_widget(Label(pos_hint={'center_x':0.5, 'center_y':0.9}, text='Berry Analyzer Camera - Desarrollado por Programa de Mejoramiento de Vides\nINIA La Platina, 2019', color=[1,1,1,0.65])) self.main_grid=GridLayout(cols=1, rows=5, size_hint=(1,0.7), pos_hint={'center_x':0.5, 'center_y':0.6}) self.layout.add_widget(self.main_grid) self.buttons_grid=GridLayout(cols=4, rows=1, size_hint=(1,0.2), pos_hint={'center_x':0.5, 'center_y':0.1}) self.layout.add_widget(self.buttons_grid) self.toggle=ToggleButton(text="Filtros: OFF", on_release=self.toggle_filters) self.filter_buttons=GridLayout(rows=1, cols=4,size_hint=(1,0.2), pos_hint={'center_x':0.5, 'center_y':0.1}) self.filter_buttons.add_widget(Button(text="Aplicar", on_release=self.apply_filter)) self.filter_buttons.add_widget(self.toggle) self.filter_buttons.add_widget(Button(text="Limpiar", on_release=self.apply_filter)) self.filter_buttons.add_widget(Button(text="Retroceder", on_release=self.apply_filter)) self.filter_toggle=False self.buttons_grid.add_widget(Button(text="Retroceder", on_release=self.back)) self.buttons_grid.add_widget(Button(text="Filtrar", on_release=self.show_filters)) self.buttons_grid.add_widget(Button(text="<", on_release=self.list_explore)) self.buttons_grid.add_widget(Button(text=">", on_release=self.list_explore)) self.filter_to_change=[] self.filter_layout = FloatLayout() self.filter_grid=GridLayout(cols=1, rows=1, size_hint_y=None, spacing=5) self.filter_grid.bind(minimum_height=self.filter_grid.setter('height')) self.filter_scroll=ScrollView(do_scroll_x=False, size_hint=(1, None), size=(Window.width, Window.height)) self.plant_to_change=[] self.plant_layout=FloatLayout() self.plant_grid=GridLayout(cols=1, rows=1, size_hint_y=None, spacing=5) self.plant_grid.bind(minimum_height=self.plant_grid.setter('height')) self.page_scroll = ScrollView(do_scroll_x=False, size_hint=(1, None), size=(Window.width, Window.height)) self.add_widget(self.layout) self.on_enter=self.from_zero def load_ps(self): filess=open("./local_data/local.csv", 'r') txt=filess.read() filess.close() return [n.split(',') for n in txt.split('\n') if len(n) > 0] def from_zero(self, dt=None): #self.filtered=self.load_ps() self.list_index=0 self.direction=1 self.page_scroll.clear_widgets() self.plant_grid.clear_widgets() for n in list(range(len(self.plant_to_change)))[::-1]: del(self.plant_to_change[n]) self.plant_grid.rows=1 self.plant_to_change=[] for n in range(len(self.config_list[3][0])): try: self.config_list[3][1][n] except: self.plant_to_change.append(None) continue if self.config_list[3][1][n]=="x": if self.config_list[3][2][n]=="txt": self.plant_to_change.append(TxtCat(size_hint_y=None, height=int(Window.height*0.2))) self.plant_grid.rows=self.plant_grid.rows+2 self.plant_grid.add_widget(Label(text=self.config_list[3][0][n],size_hint_y=None, height=int(Window.height*0.2))) self.plant_grid.add_widget(self.plant_to_change[-1]) elif self.config_list[3][2][n]=="log": self.plant_to_change.append(LogCat(size_hint_y=None, height=int(Window.height*0.2))) self.plant_grid.rows=self.plant_grid.rows+2 self.plant_grid.add_widget(Label(text=self.config_list[3][0][n],size_hint_y=None, height=int(Window.height*0.2))) self.plant_grid.add_widget(self.plant_to_change[-1]) elif self.config_list[3][2][n]=="cat": try: assert len(self.config_list[3][3][n])!=0 self.config_list[3][3][n].split(";") except: self.plant_to_change.append(None) continue self.plant_grid.rows=self.plant_grid.rows+2 self.plant_to_change.append(CatCat(categories=self.config_list[3][3][n].split(";"),size_hint_y=None, height=int(Window.height*0.2))) self.plant_grid.add_widget(Label(text=self.config_list[3][0][n],size_hint_y=None, height=int(Window.height*0.2))) self.plant_grid.add_widget(self.plant_to_change[-1]) pass elif self.config_list[3][2][n]=="num": self.plant_to_change.append(NumCat(size_hint_y=None, height=int(Window.height*0.2))) self.plant_grid.rows=self.plant_grid.rows+2 self.plant_grid.add_widget(Label(text=self.config_list[3][0][n],size_hint_y=None, height=int(Window.height*0.2))) self.plant_grid.add_widget(self.plant_to_change[-1]) elif self.config_list[3][2][n]=="dat": self.plant_to_change.append(DatCat(size_hint_y=None, height=int(Window.height*0.2))) self.plant_grid.rows=self.plant_grid.rows+2 self.plant_grid.add_widget(Label(text=self.config_list[3][0][n],size_hint_y=None, height=int(Window.height*0.2))) self.plant_grid.add_widget(self.plant_to_change[-1]) else: self.plant_to_change.append(None) self.plant_grid.rows=self.plant_grid.rows+2 self.plant_grid.add_widget(Label(text=" ", size_hint_y=None, height=int(Window.height*0.2))) self.plant_grid.add_widget(Label(text=" ", size_hint_y=None, height=int(Window.height*0.2))) self.page_scroll.add_widget(self.plant_grid) self.from_filter() self.load_list() def from_filter(self): self.toggle.state="normal" self.toggle_filters() self.filter_scroll.clear_widgets() self.filter_grid.clear_widgets() for n in list(range(len(self.filter_to_change)))[::-1]: del(self.filter_to_change[n]) self.filter_grid.rows=1 self.filter_to_change=[] for n in range(len(self.config_list[3][0])): try: assert len(self.config_list[3][2][n])==3 except: self.filter_to_change.append(None) continue if self.config_list[3][2][n]=="txt": self.filter_to_change.append(TxtFil(size_hint_y=None, height=int(Window.height*0.2))) self.filter_grid.rows=self.filter_grid.rows+2 self.filter_grid.add_widget(Label(text=self.config_list[3][0][n],size_hint_y=None, height=int(Window.height*0.2))) self.filter_grid.add_widget(self.filter_to_change[-1]) elif self.config_list[3][2][n]=="log": self.filter_to_change.append(LogFil(size_hint_y=None, height=int(Window.height*0.2))) self.filter_grid.rows=self.filter_grid.rows+2 self.filter_grid.add_widget(Label(text=self.config_list[3][0][n],size_hint_y=None, height=int(Window.height*0.2))) self.filter_grid.add_widget(self.filter_to_change[-1]) elif self.config_list[3][2][n]=="num": self.filter_to_change.append(NumFil(size_hint_y=None, height=int(Window.height*0.2))) self.filter_grid.rows=self.filter_grid.rows+2 self.filter_grid.add_widget(Label(text=self.config_list[3][0][n],size_hint_y=None, height=int(Window.height*0.2))) self.filter_grid.add_widget(self.filter_to_change[-1]) elif self.config_list[3][2][n]=="cat": try: assert len(self.config_list[3][3][n])!=0 self.config_list[3][3][n].split(";") except: self.filter_to_change.append(None) continue self.filter_to_change.append(CatFil(categories=self.config_list[3][3][n].split(";"),size_hint_y=None, height=int(Window.height*0.2))) self.filter_grid.rows=self.filter_grid.rows+2 self.filter_grid.add_widget(Label(text=self.config_list[3][0][n],size_hint_y=None, height=int(Window.height*0.2))) self.filter_grid.add_widget(self.filter_to_change[-1]) else: self.filter_to_change.append(None) self.filter_grid.rows=self.filter_grid.rows+2 self.filter_grid.add_widget(Label(text=" ", size_hint_y=None, height=int(Window.height*0.2))) self.filter_grid.add_widget(Label(text=" ", size_hint_y=None, height=int(Window.height*0.2))) self.filter_scroll.add_widget(self.filter_grid) def list_explore(self, dt=None): if dt.text==">": self.direction=1 elif dt.text=="<": self.direction=-1 self.load_list() def check_filter(self,entry): if self.toggle.state =="normal": return True for n in range(len(entry)): #print(entry[n], end=" ") if self.filter_to_change[n] == None: #print("None") continue if not self.filter_to_change[n].check_entry(entry[n]): #print(False) return False #print(True) return True def load_list(self): self.main_grid.clear_widgets() counter=0 found=[] while counter<5: if 1<=self.list_index+self.direction<len(self.config_list[1]): self.list_index+=self.direction #sleep(0.2) if self.check_filter(entry=self.config_list[1][self.list_index]): temp=[] for s in range(len(self.config_list[3][1])): if self.config_list[3][1][s]=="s": temp.append(self.config_list[1][self.list_index][s]) temp=".".join(temp) found.append("\n".join([temp,self.config_list[1][self.list_index][0]])) #self.main_grid.add_widget(Button(text="\n".join([temp,self.config_list[1][self.list_index][0]]), on_release=self.open_plant, background_normal="", background_color=[0,0,0,0])) counter+=1 #print("found") else: break if self.direction<0: found=found[::-1] for n in found: self.main_grid.add_widget(Button(text=n, on_release=self.open_plant, background_normal="", background_color=[0,0,0,1])) def show_filters(self, dt=None): while len(self.config_list[3][4])<len(self.config_list[3][0]): self.config_list[3][4].append("") for n in range(len(self.config_list[3][0])): if self.filter_to_change[n]==None: continue self.filter_to_change[n].load_filter(self.config_list[3][4][n]) self.clear_widgets() self.add_widget(self.filter_scroll) self.add_widget(self.filter_buttons) def toggle_filters(self,dt=None): if self.toggle.state=="down": self.toggle.text="Filtrar: ON" else: self.toggle.text="Filtrar: OFF" def open_plant(self, dt=None): number=0 for n in range(len(self.config_list[1])): if self.config_list[1][n][0]==dt.text.split("\n")[1]: number=n break counter=0 self.current_plant=number for n in range(len(self.config_list[3][0])): if self.plant_to_change[n]==None: continue try: self.config_list[1][number][n] except: continue self.plant_to_change[n].clear_final() self.plant_to_change[n].load_value(self.config_list[1][number][n]) self.clear_widgets() self.add_widget(self.page_scroll) grid=GridLayout(rows=1, cols=2,size_hint=(1,0.2), pos_hint={'center_x':0.5, 'center_y':0.1}) grid.add_widget(Button(text="Guardar", on_release=self.save_data)) grid.add_widget(Button(text="Retroceder", on_release=self.save_data)) self.add_widget(grid) def save_data(self, dt=None): if dt.text=="Guardar": self.filtered=[] for n in range(len(self.config_list[3][0])): if n == 0: self.filtered.append(self.config_list[1][self.current_plant][n]) continue if self.plant_to_change[n]==None: self.filtered.append("") else: #if self.config_list[1][self.current_plant][n]!=self.plant_to_change[n].get_value() and self.config_list[1][self.current_plant][n]!="": if self.config_list[1][self.current_plant][n]!=self.plant_to_change[n].get_value(): self.config_list[1][self.current_plant][n]=self.plant_to_change[n].get_value() self.filtered.append(self.plant_to_change[n].get_value()) else: self.filtered.append("") self.save_local() self.clear_widgets() self.add_widget(self.layout) pass def save_local(self): #remove("./local_data/"+listdir("./local_data")[0]) filess = open("./local_data/local.csv", "a") filess.write(",".join(self.filtered)+"\n") filess.close() def back(self, dt=None): self.manager.current = 'external' def apply_filter(self, dt=None): #print(self.config_list[3]) if dt.text=="Aplicar": self.toggle.state="down" self.toggle_filters() while len(self.config_list[3][4])<len(self.config_list[3][0]): self.config_list[3][4].append("") for n in range(len(self.config_list[3][0])): if self.filter_to_change[n]==None: continue self.config_list[3][4][n]=self.filter_to_change[n].get_filter() self.list_index=0 self.direction=1 self.load_list() elif dt.text=="Limpiar": self.toggle.state="normal" self.toggle_filters() while len(self.config_list[3][4])<len(self.config_list[3][0]): self.config_list[3][4].append("") for n in range(len(self.config_list[3][0])): if self.filter_to_change[n]==None: continue self.config_list[3][4][n]=self.filter_to_change[n].clean() self.config_list[3][4][n]=self.filter_to_change[n].get_filter() self.list_index=0 self.direction=1 self.load_list() else: pass print("filters",self.config_list[3][4]) self.clear_widgets() self.add_widget(self.layout)
class GpsRecordsWidget(Widget): is_screen = BooleanProperty(True) def __init__(self): super().__init__() self.widget_layout_main = FloatLayout() self.widget_layout = GridLayout(cols=2, spacing=10, size_hint_y=None, size=(Window.width, Window.height * 3)) self.pages = [] self.scrollview = ScrollView(size_hint=(1, None), size=(Window.width, Window.height), effect_cls=ScrollEffect) self.items_bind() def create_img(self, *args): #print(args) (filename, lat, lon, title, markers), count, obj = args return ImageButton(filename, lat, lon, title, markers, count, obj, source='Records/' + filename + '.png', size_hint_y=None, size=(Window.size[0] * 3 // 5, Window.size[1] * 3 // 5)) #height=Window.height//4) #allow_stretch=True, keep_ratio=False) def items_bind(self): self.widget_layout.clear_widgets() self.scrollview.clear_widgets() self.widget_layout_main.clear_widgets() sql_connection = sqlite3.connect('Records/records.db') cursor = sql_connection.cursor() cursor.execute('select datetime,lat,lon,title,markers from my_records') fetched = cursor.fetchall() (q, r), count = divmod(len(fetched), 4), 0 self.widget_layout = GridLayout( cols=2, spacing=10, size_hint_y=None, size=(Window.width, (Window.height * 3 // 5) * len(fetched) // 2 + 1)) for i in range(len(fetched)): self.widget_layout.add_widget( self.create_img(fetched[i], count, self)) self.scrollview.add_widget(self.widget_layout) self.widget_layout_main.add_widget(self.scrollview) self.bind(is_screen=self.on_is_screen) def on_is_screen(self, instance, value): if value: self.items_bind() else: self.widget_layout.clear_widgets() self.scrollview.clear_widgets() self.widget_layout_main.clear_widgets() def set_screen(self, value): self.is_screen = value
class VentasPage(BoxLayout): def __init__(self, **kwargs): super().__init__(**kwargs) self.orientation = "vertical" self.layout = GridLayout(cols=5, spacing=5, size_hint_y=None) self.rotador = ScrollView(size_hint=(1, 1), #size=(Window.width, Window.height), ) def botones_abajo(self): self.box_buttons = BoxLayout(size_hint=(1, .2)) self.but_vuelvo = Button( text="Volver", #pos_hint={"center_x": 0.1, "center_y": 0.1}, height="50dp", size_hint_y=None, #size_hint = (1,1), ) but_carrito = Button( text="Carrito", #pos_hint={"center_x": 0.1, "center_y": 0.1}, #size_hint = (1,1), height="50dp", size_hint_y=None, ) self.box_buttons.add_widget(self.but_vuelvo) self.box_buttons.add_widget(but_carrito) self.add_widget(self.box_buttons) self.but_vuelvo.bind(on_press=self.vuelvo_start) but_carrito.bind(on_press=self.voy_carrito) ############################################################################### ############################################################################### def ventas(self, codigo_cliente): self.codigo_cliente = codigo_cliente.ID self.clear_widgets() self.rotador.clear_widgets() self.layout.cols = 5 self.layout.size_hint_y = None #AGREGO LOS WIDGETS QUE VOY A USAR MAS TARDE CUANDO HAGA LA LISTA desc = Label( halign="left", #size = self.texture_size, size_hint=(.4, .3), size_hint_y=None, height=40, #text_size = self.size, ) precio = Label( halign="right", #size = self.texture_size, size_hint=(.2, .3), size_hint_y=None, height=40, #text_size = self.size, ) stock = Label( halign="right", #size = self.texture_size, size_hint=(.2, .3), size_hint_y=None, height=40, #text_size = self.size, ) cantidad = TextInput( multiline=False, readonly=False, halign="right", font_size=20, size_hint=(.1, .3), input_filter="float", write_tab="False", ) ######################################################## self.buscador = TextInput( text="", multiline=False, readonly=False, halign="left", font_size=55, size_hint=(1, .2), #input_filter = "float", write_tab="False", ) self.buscador.ID = "ventas" titulos = GridLayout(cols=5, size_hint=(1, .2)) tit1 = Label( text="Articulos", size_hint=(.4, 1), ) tit2 = Label( text="Precio", size_hint=(.2, 1), ) tit3 = Label( text="Stock", size_hint=(.2, 1), ) tit4 = Label( text="Cantidad", size_hint=(.1, 1), ) tit5 = Label( text="Agregar", size_hint=(.1, 1), ) titulos.add_widget(tit1) titulos.add_widget(tit2) titulos.add_widget(tit3) titulos.add_widget(tit4) titulos.add_widget(tit5) self.buscador.bind(text=self.on_text) self.add_widget(self.buscador) self.add_widget(titulos) # Make sure the height is such that there is something to scroll. self.layout.bind(minimum_height=self.layout.setter('height')) self.rotador.add_widget(self.layout) self.add_widget(self.rotador) self.botones_abajo() def seleccion_clientes(self, origen): self.clear_widgets() self.rotador.clear_widgets() self.lab_ask = Label(text="Seleccione Cliente:", size_hint=(1, .1)) self.add_widget(self.lab_ask) self.grid_botones = BoxLayout(size_hint=(1, .1)) self.text_busco_cli = TextInput( text="", multiline=False, readonly=False, halign="left", font_size=30, size_hint=(1, 1), #input_filter = "float", write_tab="False", ) self.grid_botones.add_widget(self.text_busco_cli) self.text_busco_cli.bind(text=self.listo_clientes) self.text_busco_cli.ID = f"{origen}" self.add_widget(self.grid_botones) self.rotador = ScrollView() self.box_text_lab = BoxLayout( orientation="vertical", size_hint=(1, .2), ) self.but_agregar_cliente = Button( text="Nuevo Cliente", size_hint=(1, 1), ) self.but_agregar_cliente.bind(on_press=self.nuevo_cliente) self.rotador.add_widget(self.layout) self.add_widget(self.rotador) self.box_text_lab.add_widget(self.but_agregar_cliente) self.add_widget(self.box_text_lab) def listo_clientes(self, instance, value): self.layout.clear_widgets() self.layout.cols = 6 self.layout.size_hint_y = 1 indice = 0 if clientes != []: for cliente in clientes: if cliente[1] != "NOMBRE" and value.upper( ) in cliente[1] and value != "": self.listado_clientes(cliente, indice, instance) indice += 1 def listado_clientes(self, cliente, indice, instance): #exec(f"self.lab_codigo_cli{indice} = Label(text=cliente[0],height = '20dp', size_hint_y=None)") exec(f"""self.lab_nombre_cli{indice} = Label(text=cliente[1], height = '20dp', size_hint_y=None, width = '260dp', size_hint_x=None, )""") #exec(f"self.lab_localidad_cli{indice} = Label(text=cliente[2],height = '20dp',size_hint_y=None)") exec(f"""self.lab_whatsapp_cli{indice} = Label(text=cliente[3], height = '20dp', size_hint_y=None, width = '100dp', size_hint_x=None, )""") exec(f"""self.lab_instagram_cli{indice} = Label(text=cliente[4], height = '20dp', size_hint_y=None, width = '100dp', size_hint_x=None, )""") exec(f"""self.lab_email_cli{indice} = Label(text=cliente[5], height = '20dp', size_hint_y=None, width = '210dp', size_hint_x=None, )""") self.bot_selec_cliente = Button( text="Selec", height="20dp", size_hint_y=None, width='50dp', size_hint_x=None, ) self.bot_selec_cliente.bind(on_press=self.sigo_con_ventas) self.bot_selec_cliente.ID = str(indice) self.bot_modif_cliente = Button( text="Modif", height="20dp", size_hint_y=None, width='50dp', size_hint_x=None, ) self.bot_modif_cliente.bind(on_press=self.modifico_cliente) self.de_donde_vengo = instance.ID self.bot_modif_cliente.ID = str(clientes.index(cliente)) #exec(f"self.layout.add_widget(self.lab_codigo_cli{indice})") exec(f"self.layout.add_widget(self.lab_nombre_cli{indice})") #exec(f"self.layout.add_widget(self.lab_localidad_cli{indice})") exec(f"self.layout.add_widget(self.lab_whatsapp_cli{indice})") exec(f"self.layout.add_widget(self.lab_instagram_cli{indice})") exec(f"self.layout.add_widget(self.lab_email_cli{indice})") self.layout.bind(minimum_height=self.layout.setter('height')) self.layout.add_widget(self.bot_selec_cliente) self.layout.add_widget(self.bot_modif_cliente) def sigo_con_ventas(self, instance): if "ventasx" in f"{self.de_donde_vengo}": irenic_app.ventas_page.informes() else: irenic_app.ventas_page.ventas(instance) def modifico_cliente(self, instance): #CODIGO,NOMBRE,LOCALIDAD,WHATSAPP,INSTAGRAM,EMAIL self.remove_widget(self.lab_ask) self.box_text_lab.clear_widgets() self.grid_botones.clear_widgets() self.layout.clear_widgets() self.layout.cols = 2 self.layout.size_hint_y = 1 label_ing = Label(text="Modifique los datos del Cliente") lab_nombre = Label(text="Nombre") self.text_nombre = TextInput( text=f"{clientes[int(instance.ID)][1]}", multiline=False, readonly=False, halign="left", size_hint=(1, .2), #input_filter = "float", write_tab="False", ) self.layout.add_widget(lab_nombre) self.layout.add_widget(self.text_nombre) lab_localidad = Label(text="Localidad") self.text_localidad = TextInput( text=f"{clientes[int(instance.ID)][2]}", multiline=False, readonly=False, halign="left", size_hint=(1, .2), #input_filter = "float", write_tab="False", ) self.layout.add_widget(lab_localidad) self.layout.add_widget(self.text_localidad) lab_whatsapp = Label(text="Whatsapp") self.text_whatsapp = TextInput( text=f"{clientes[int(instance.ID)][3]}", multiline=False, readonly=False, halign="left", size_hint=(1, .2), input_filter="float", write_tab="False", ) self.layout.add_widget(lab_whatsapp) self.layout.add_widget(self.text_whatsapp) lab_instagram = Label(text="Instagram/facebook") self.text_instagram = TextInput( text=f"{clientes[int(instance.ID)][4]}", multiline=False, readonly=False, halign="left", size_hint=(1, .2), #input_filter = "float", write_tab="False", ) self.layout.add_widget(lab_instagram) self.layout.add_widget(self.text_instagram) lab_email = Label(text="email") self.text_email = TextInput( text=f"{clientes[int(instance.ID)][5]}", multiline=False, readonly=False, halign="left", size_hint=(1, .2), #input_filter = "float", write_tab="False", ) self.layout.add_widget(lab_email) self.layout.add_widget(self.text_email) bot_guardar_prov = Button(text="Guardar") bot_guardar_prov.ID = f"modifcliente{clientes[int(instance.ID)][0]}" bot_guardar_prov.bind(on_press=self.guardo_cliente) self.grid_botones.add_widget(label_ing) self.layout.add_widget(bot_guardar_prov) return def nuevo_cliente(self, instance): #CODIGO,NOMBRE,LOCALIDAD,WHATSAPP,INSTAGRAM,EMAIL self.remove_widget(self.lab_ask) self.box_text_lab.clear_widgets() self.grid_botones.clear_widgets() self.layout.clear_widgets() self.layout.cols = 2 self.layout.size_hint_y = 1 label_ing = Label(text="Ingrese los datos del Nuevo Cliente") lab_nombre = Label(text="Nombre") self.text_nombre = TextInput( text="", multiline=False, readonly=False, halign="left", size_hint=(1, .2), #input_filter = "float", write_tab="False", ) self.layout.add_widget(lab_nombre) self.layout.add_widget(self.text_nombre) lab_localidad = Label(text="Localidad") self.text_localidad = TextInput( text="", multiline=False, readonly=False, halign="left", size_hint=(1, .2), #input_filter = "float", write_tab="False", ) self.layout.add_widget(lab_localidad) self.layout.add_widget(self.text_localidad) lab_whatsapp = Label(text="Whatsapp") self.text_whatsapp = TextInput( text="", multiline=False, readonly=False, halign="left", size_hint=(1, .2), input_filter="float", write_tab="False", ) self.layout.add_widget(lab_whatsapp) self.layout.add_widget(self.text_whatsapp) lab_instagram = Label(text="Instagram/facebook") self.text_instagram = TextInput( text="", multiline=False, readonly=False, halign="left", size_hint=(1, .2), #input_filter = "float", write_tab="False", ) self.layout.add_widget(lab_instagram) self.layout.add_widget(self.text_instagram) lab_email = Label(text="email") self.text_email = TextInput( text="", multiline=False, readonly=False, halign="left", size_hint=(1, .2), #input_filter = "float", write_tab="False", ) self.layout.add_widget(lab_email) self.layout.add_widget(self.text_email) bot_guardar_prov = Button(text="Guardar") bot_guardar_prov.ID = "cliente" bot_guardar_prov.bind(on_press=self.guardo_cliente) self.grid_botones.add_widget(label_ing) self.layout.add_widget(bot_guardar_prov) ################################################################################## ################################################################################## def informes(self): self.clear_widgets() self.box_ventas = GridLayout(cols=1, ) self.box_rankings = GridLayout(cols=1, ) bot_ventas_cli = Button(text="Ventas x Cliente", ) bot_ventas_cli.ID = "ventasxcliente" bot_ventas_fecha = Button(text="Ventas x Fecha", ) bot_ventas_fecha.ID = "ventasxfecha" bot_ventas_art = Button(text="Ventas x Articulo", ) bot_ventas_art.ID = "ventasxarticulo" bot_ventas_prov = Button(text="Ventas x Proveedor", ) bot_ventas_prov.ID = "ventasxproveedor" bot_ventas_cli.bind(on_press=self.proceso_boton_ventas) bot_ventas_art.bind(on_press=self.proceso_boton_ventas) bot_ventas_prov.bind(on_press=self.proceso_boton_ventas) bot_ventas_fecha.bind(on_press=self.proceso_boton_ventas) self.box_ventas.add_widget(bot_ventas_cli) self.box_ventas.add_widget(bot_ventas_fecha) self.box_ventas.add_widget(bot_ventas_prov) self.box_ventas.add_widget(bot_ventas_art) bot_rank_art = Button(text="Ranking x Articulo", ) bot_rank_art.ID = "rankingxarticulo" bot_rank_cli = Button(text="Ranking x Cliente", ) bot_rank_cli.ID = "rankingxcliente" bot_rank_margen = Button(text="Ranking x Margen", ) bot_rank_margen.ID = "rankingxmargen" bot_rank_art.bind(on_press=self.proceso_boton_ventas) bot_rank_cli.bind(on_press=self.proceso_boton_ventas) bot_rank_margen.bind(on_press=self.proceso_boton_ventas) self.box_rankings.add_widget(bot_rank_art) self.box_rankings.add_widget(bot_rank_cli) self.box_rankings.add_widget(bot_rank_margen) self.add_widget(self.box_ventas) self.add_widget(self.box_rankings) def proceso_boton_ventas(self, instance): #ventas x: cliente, articulo, proveedor y fecha #ranking: articulo, cliente, margen self.box_ventas.clear_widgets() self.box_rankings.clear_widgets() titulo_listado = Label( text=f"{instance.text}", height="40dp", size_hint_y=None, ) origen = instance.ID self.box_ventas.add_widget(titulo_listado) self.seleccion_clientes(origen) self.botones_abajo() ################################################################################## ################################################################################## def ingresos(self): self.clear_widgets() self.lab_ask = Label(text="Seleccione Proveedor:", size_hint=(1, .2)) self.add_widget(self.lab_ask) self.grid_botones = BoxLayout(size_hint=(1, .2)) with open("proveedores.csv") as prov: lista_proveedor = csv.reader(prov, delimiter=",") indice = 1 global prov_udtd for proveedor in lista_proveedor: if not prov_udtd: proveedores.append(proveedor) if proveedor[0] != "NOMBRE": exec(f"bot_prov{indice} = Button(text = proveedor[0],)") exec(f"self.grid_botones.add_widget(bot_prov{indice})") exec( f"bot_prov{indice}.bind(on_press= self.articulo_proveedor)" ) exec(f"bot_prov{indice}.ID = indice") indice += 1 prov_udtd = True exec(f"bot_prov{indice} = Button(text = 'Nuevo Proveedor',)") exec(f"self.grid_botones.add_widget(bot_prov{indice})") exec(f"bot_prov{indice}.bind(on_press= self.articulo_proveedor)") exec(f"bot_prov{indice}.ID = indice") self.add_widget(self.grid_botones) self.box_text_lab = BoxLayout( orientation="vertical", size_hint=(1, .2), ) self.add_widget(self.box_text_lab) self.layout = GridLayout( cols=4, spacing=5, size_hint_y=None, ) self.layout.bind(minimum_height=self.layout.setter('height')) self.rotador = ScrollView( size_hint=(1, 1), size=(Window.width, Window.height), ) self.rotador.add_widget(self.layout) self.add_widget(self.rotador) def articulo_proveedor(self, instance): #,ARTICULOS,MAYORISTA,MINORISTA,100,proveedor,margen self.grid_botones.clear_widgets() self.remove_widget(self.lab_ask) if instance.text != "Nuevo Proveedor": self.lab_prov = Label(text=instance.text) self.buscador = TextInput( text="", multiline=False, readonly=False, halign="left", font_size=30, size_hint=(1, 1), #input_filter = "float", write_tab="False", ) self.buscador.ID = "ingresos" barra_titulos_ingreso = GridLayout( cols=4, row_force_default=True, row_default_height=40, ) tit_desc = Label( text="Descripcion", size_hint=(.5, 1), ) tit_cant = Label( text="Cantidad", size_hint=(.2, 1), ) tit_precio = Label( text="Precio", size_hint=(.2, 1), ) tit_boton = Label(text="", size_hint=(.2, 1)) barra_titulos_ingreso.add_widget(tit_desc) barra_titulos_ingreso.add_widget(tit_cant) barra_titulos_ingreso.add_widget(tit_precio) barra_titulos_ingreso.add_widget(tit_boton) self.grid_botones.add_widget(self.lab_prov) self.box_text_lab.add_widget(self.buscador) self.box_text_lab.add_widget(barra_titulos_ingreso) self.buscador.bind(text=self.on_text) else: self.nuevo_proveedor() def nuevo_proveedor(self): #NOMBRE,DIRECCION,LOCALIDAD,TELEFONO,WHATSAPP,CONTACTO1,CONTACTO2 self.box_text_lab.clear_widgets() self.layout.clear_widgets() self.layout.cols = 2 self.layout.size_hint_y = 1 label_ing = Label(text="Ingrese los datos del Nuevo Proveedor") lab_nombre = Label(text="Nombre") self.text_nombre = TextInput( text="", multiline=False, readonly=False, halign="left", size_hint=(1, .2), #input_filter = "float", write_tab="False", ) self.layout.add_widget(lab_nombre) self.layout.add_widget(self.text_nombre) lab_direccion = Label(text="Direccion") self.text_direccion = TextInput( text="", multiline=False, readonly=False, halign="left", size_hint=(1, .2), #input_filter = "float", write_tab="False", ) self.layout.add_widget(lab_direccion) self.layout.add_widget(self.text_direccion) lab_localidad = Label(text="Localidad") self.text_localidad = TextInput( text="", multiline=False, readonly=False, halign="left", size_hint=(1, .2), #input_filter = "float", write_tab="False", ) self.layout.add_widget(lab_localidad) self.layout.add_widget(self.text_localidad) lab_telefono = Label(text="Telefono") self.text_telefono = TextInput( text="", multiline=False, readonly=False, halign="left", size_hint=(1, .2), input_filter="float", write_tab="False", ) self.layout.add_widget(lab_telefono) self.layout.add_widget(self.text_telefono) lab_whatsapp = Label(text="Whatsapp") self.text_whatsapp = TextInput( text="", multiline=False, readonly=False, halign="left", size_hint=(1, .2), input_filter="float", write_tab="False", ) self.layout.add_widget(lab_whatsapp) self.layout.add_widget(self.text_whatsapp) lab_contacto = Label(text="Nombre de Contacto") self.text_contacto = TextInput( text="", multiline=False, readonly=False, halign="left", size_hint=(1, .2), #input_filter = "float", write_tab="False", ) self.layout.add_widget(lab_contacto) self.layout.add_widget(self.text_contacto) lab_contacto2 = Label(text="Nombre de Contacto 2") self.text_contacto2 = TextInput( text="", multiline=False, readonly=False, halign="left", size_hint=(1, .2), #input_filter = "float", write_tab="False", ) self.layout.add_widget(lab_contacto2) self.layout.add_widget(self.text_contacto2) bot_guardar_prov = Button(text="Guardar") bot_guardar_prov.ID = "proveedor" bot_guardar_prov.bind(on_press=self.guardo_proveedor) self.grid_botones.add_widget(label_ing) self.layout.add_widget(bot_guardar_prov) def guardo_proveedor(self, instance): self.registro_prov = f"{self.text_nombre.text.upper()},{self.text_direccion.text.upper()},{self.text_localidad.text.upper()},{self.text_telefono.text},{self.text_whatsapp.text},{self.text_contacto.text.upper()},{self.text_contacto2.text.upper()}" proveedores.append(self.registro_prov.split(",")) with open("proveedores.csv", mode="w") as prov: lista_proveedor = csv.writer(prov, delimiter=",", lineterminator='\n') for proveedor in proveedores: lista_proveedor.writerow(proveedor) irenic_app.ventas_page.ingresos() irenic_app.ventas_page.botones_abajo() def guardo_cliente(self, instance): if instance.ID == "cliente": nro_codigo_cliente = int(clientes[len(clientes) - 1][0]) + 1 codigo_cliente = "0" * (7 - len(str(nro_codigo_cliente))) + str( nro_codigo_cliente) self.registro_cli = f"{codigo_cliente},{self.text_nombre.text.upper()},{self.text_localidad.text.upper()},{self.text_whatsapp.text},{self.text_instagram.text.upper()},{self.text_email.text.lower()}" clientes.append(self.registro_cli.split(",")) else: self.registro_cli = f"{instance.ID[12:]},{self.text_nombre.text.upper()},{self.text_localidad.text.upper()},{self.text_whatsapp.text},{self.text_instagram.text.upper()},{self.text_email.text.lower()}" clientes[int(instance.ID[12:])] = self.registro_cli.split(",") with open("clientes.csv", mode="w") as cli: lista_clientes = csv.writer(cli, delimiter=",", lineterminator='\n') for cliente in clientes: lista_clientes.writerow(cliente) irenic_app.ventas_page.seleccion_clientes() irenic_app.ventas_page.botones_abajo() def guardo_proveedor(self, instance): self.registro_prov = f"{self.text_nombre.text.upper()},{self.text_direccion.text.upper()},{self.text_localidad.text.upper()},{self.text_telefono.text},{self.text_whatsapp.text},{self.text_contacto.text.upper()},{self.text_contacto2.text.upper()}" proveedores.append(self.registro_prov.split(",")) with open("proveedores.csv", mode="w") as prov: lista_proveedor = csv.writer(prov, delimiter=",", lineterminator='\n') for proveedor in proveedores: lista_proveedor.writerow(proveedor) irenic_app.ventas_page.ingresos() irenic_app.ventas_page.botones_abajo() def voy_carrito(self, instance): irenic_app.carrito_page.armo_items() irenic_app.screen_manager.current = "Carrito" def vuelvo_start(self, instance): irenic_app.screen_manager.current = "Start" def on_text(self, instance, value): self.layout.clear_widgets() self.indice = 0 self.matrix_art = [] for articulo in lista: if instance.ID == "ingresos": if value.lower() in articulo[1].lower( ) and value != "" and articulo[1] != "ARTICULOS" and articulo[ 3] != "" and articulo[5] == self.lab_prov.text: self.on_text_ingresos(articulo) self.indice += 1 elif instance.ID == "ventas": if value.lower() in articulo[1].lower( ) and value != "" and articulo[1] != "ARTICULOS" and articulo[ 3] != "": self.on_text_ventas(articulo) self.indice += 1 def on_text_ventas(self, articulo): art_ind_stock = lista.index(articulo) self.desc = Label( text=articulo[1][0:30], halign="left", #size = self.texture_size, size_hint=(.4, .3), size_hint_y=None, height=40, #text_size = self.size, ) self.precio = Label( text=articulo[3], halign="right", #size = self.texture_size, size_hint=(.2, .3), size_hint_y=None, height=40, #text_size = self.size, ) self.stock = Label( text=articulo[4], halign="right", #size = self.texture_size, size_hint=(.2, .3), size_hint_y=None, height=40, ) self.var_cant = f"self.cantidad{self.indice}" asig_text = """TextInput( multiline=False, readonly=False, halign="right", font_size=20, size_hint=(.1, .3), input_filter = "int", write_tab = "False", )""" exec("%s = %s" % (self.var_cant, asig_text)) """self.cantidad = TextInput( multiline=False, readonly=False, halign="right", font_size=20, size_hint=(.1, .3), input_filter = "float", write_tab = "False", )""" var_but_agregar = """Button (text = "agregar", size_hint = (.1, .3), )""" exec(f"but_agregar{str(self.indice)} = {var_but_agregar}") if len(str(self.indice)) == 1: cod_id = f"00{self.indice}" elif len(str(self.indice)) == 2: cod_id = f"0{self.indice}" elif len(str(self.indice)) == 3: cod_id = str(self.indice) exec(f"but_agregar{str(self.indice)}.ID = 'ventas {cod_id}'") #self.matrix_art.append([self.desc.text, self.precio.text, str(art_ind_stock)]) self.matrix_art = cargo_lista_confirmacion([ self.desc.text, self.precio.text, str(art_ind_stock), self.codigo_cliente ], self.matrix_art) exec(f"but_agregar{str(self.indice)}.bind(on_press=self.agregar_art)") self.layout.add_widget(self.desc) self.layout.add_widget(self.precio) self.layout.add_widget(self.stock) exec("self.layout.add_widget(%s)" % (self.var_cant)) exec(f"self.layout.add_widget(but_agregar{str(self.indice)})") def on_text_ingresos(self, articulo): var_lab_desc_art = """Label( text = lista[lista.index(articulo)][1][0:30], halign = "left", #size = self.texture_size, size_hint=(.5, .3), size_hint_y=None, height=40,)""" exec(f"self.lab_desc_art{self.indice}= {var_lab_desc_art}") exec(f"self.layout.add_widget(self.lab_desc_art{self.indice})") exec(f"self.text_cant_art{self.indice}= TextInput(size_hint=(.2,.3))") exec(f"self.layout.add_widget(self.text_cant_art{self.indice})") exec( f"self.text_precio_art{self.indice}= TextInput(size_hint=(.2,.3))") exec(f"self.layout.add_widget(self.text_precio_art{self.indice})") var_bot_art_ing = """Button( text = "agregar", size_hint=(.2,.3), )""" exec(f"bot_art_ing{self.indice} = {var_bot_art_ing}") if len(str(self.indice)) == 1: cod_id = f"00{self.indice}" elif len(str(self.indice)) == 2: cod_id = f"0{self.indice}" elif len(str(self.indice)) == 3: cod_id = str(self.indice) exec(f"bot_art_ing{self.indice}.ID = 'ingresos{cod_id}'") exec(f"self.layout.add_widget(bot_art_ing{self.indice})") exec(f"bot_art_ing{self.indice}.bind(on_press = self.agregar_art)") exec( f"self.matrix_art = cargo_lista_confirmacion([lista.index(articulo),self.lab_desc_art{self.indice}.text], self.matrix_art)" ) def agregar_art(self, instance): ldic = locals() exec(f"info = self.agregar_art_{instance.ID[0:8].strip()}(instance)", globals(), ldic) info = ldic["info"] if info: irenic_app.carrito_page.update_info(info) irenic_app.screen_manager.current = 'Carrito' def agregar_art_ventas(self, instance): descripcion = self.matrix_art[int(instance.ID[-3:])][0] precio_unit = self.matrix_art[int(instance.ID[-3:])][1] codigo_art = self.matrix_art[int(instance.ID[-3:])][2] codigo_cli = self.matrix_art[int(instance.ID[-3:])][3] var_cantidad = f"self.cantidad{int(instance.ID[-3:])}.text" ldic = locals() exec(f"cantidad = {var_cantidad}", globals(), ldic) cantidad = ldic["cantidad"] info = "" if cantidad != "" and int(cantidad) > 0: exec(f"subtotal = int(precio_unit) * int({var_cantidad})", globals(), ldic) subtotal = ldic["subtotal"] exec( f"info = '{instance.ID[0:8].strip()},{codigo_cli},{codigo_art},#{descripcion},{precio_unit},{cantidad},{subtotal}'" ) info = ldic["info"] return info def agregar_art_ingresos(self, instance): ing_cod = self.matrix_art[int(instance.ID[-3:])][0] ing_desc = self.matrix_art[int(instance.ID[-3:])][1] ldic = locals() exec(f"ing_cant = self.text_cant_art{int(instance.ID[-3:])}.text", globals(), ldic) ing_cant = ldic["ing_cant"] exec(f"ing_precio = self.text_precio_art{int(instance.ID[-3:])}.text") ing_precio = ldic["ing_precio"] info = "" if ing_cant != "" and ing_precio != "": exec( f"info = '{instance.ID[0:8].strip()},{ing_cod},#{ing_desc},{ing_cant},{ing_precio}'" ) info = ldic["info"] return info #Clock.schedule_once(self.vuelvo_ventas, 1) def vuelvo_ventas(self, instance): irenic_app.screen_manager.current = 'Ventas'
class Info_Button(Button): """ Class Method : Custom button for Game screen mini - tutorial """ def __init__(self, parent_widget, **kwargs): """ Function Method : initialize self and class param =============================== :param parent_widget - original parent of the class - MainGame Screen """ super(Info_Button, self).__init__(**kwargs) # scrollview widget to house layout with descriptions self.scrlv_info = ScrollView(size_hint=(0.5, 0.5), pos=(parent_widget.width / 3, parent_widget.height / 3)) # original parent of the class - MainGame Screen self.parent_widget = parent_widget # border set to prevent incorrect rescalling self.border = (0, 0, 0, 0) # layout with GridLayout type to house Image descriptions with infinite height to accommodate scrlv self.layout = GridLayout(cols=1, size_hint_y=None) self.layout.bind(minimum_height=self.layout.setter('height')) def on_press(self): # sound play on button press event sound = SoundLoader.load('assets/audio/scrollview_click.mp3') sound.play() def on_release(self): # on button release event # adding city explanation images for Scrollview if no children exist for layout (user request to open sub- screen) if self.layout.children == []: self.scrlv_info.clear_widgets() self.layout.add_widget( Button(size_hint_y=None, height=500, background_normal=os.path.join('assets', 'images', '62_explanation1.png'))) self.layout.add_widget( Button(size_hint_y=None, height=500, background_normal=os.path.join('assets', 'images', '63_explanation2.png'))) self.layout.add_widget( Button(size_hint_y=None, height=500, background_normal=os.path.join('assets', 'images', '64_explanation3.png'))) self.layout.add_widget( Button(size_hint_y=None, height=800, background_normal=os.path.join('assets', 'images', '65_explanation4.png'))) self.layout.add_widget( Button(size_hint_y=None, height=600, background_normal=os.path.join('assets', 'images', '66_explanation5.png'))) self.layout.add_widget( Button(size_hint_y=None, height=800, background_normal=os.path.join('assets', 'images', '67_explanation6.png'))) self.layout.add_widget( Button(size_hint_y=None, height=500, background_normal=os.path.join('assets', 'images', '68_explanation7.png'))) self.layout.add_widget( Button(size_hint_y=None, height=500, background_normal=os.path.join('assets', 'images', '69_explanation8.png'))) self.scrlv_info.add_widget(self.layout) self.parent_widget.add_widget(self.scrlv_info) # else remove them (user cancels sub screen) else: self.parent_widget.remove_widget(self.scrlv_info) self.layout.clear_widgets() # update scrollview vertical values def scroll_change(self, scrlv, instance, value): scrlv.scroll_y = value
class ShareCourseWidget(Widget): is_screen = BooleanProperty(True) order_state = StringProperty('recommend') def __init__(self): super().__init__() self.widget_layout_main = FloatLayout() self.widget_layout = GridLayout(cols=2, spacing=20, size_hint_y=None, size=(Window.width, Window.height * 3), pos_hint={'y': .8}) self.button_box = BoxLayout(orientation='horizontal', pos_hint={'y': .9}, size_hint=(.2, .1)) self.recommend_order_button = Button( text='추천순', font_name='Fonts/NanumBarunGothic.ttf', on_release=self.recommend_order_pressed) self.date_order_button = Button(text='날짜순', font_name='Fonts/NanumBarunGothic.ttf', on_release=self.date_order_pressed) self.scrollview = ScrollView(size_hint=(1, None), size=(Window.width, Window.height), effect_cls=ScrollEffect) self.button_box.add_widget(self.recommend_order_button) self.button_box.add_widget(self.date_order_button) self.items_bind() def recommend_order_pressed(self, btn): self.order_state = 'recommend' def date_order_pressed(self, btn): self.order_state = 'date' def create_img(self, *args): (filename, lat, lon, title, markers, recommend), count, obj = args return ImageButton(filename, lat, lon, title, markers, recommend, count, obj, source='Records/' + filename + '.png', size_hint_y=None, size=(Window.size[0] * 3 // 5, Window.size[1] * 3 // 5)) def items_bind(self): self.widget_layout.clear_widgets() self.scrollview.clear_widgets() self.widget_layout_main.clear_widgets() sql_connection = sqlite3.connect('Records/records.db') cursor = sql_connection.cursor() cursor.execute( 'select datetime,lat,lon,title,markers,recommend from shared_records' ) fetched = cursor.fetchall() (q, r), count = divmod(len(fetched), 4), 0 self.widget_layout = GridLayout( cols=2, spacing=10, size_hint_y=None, size=(Window.width, (Window.height * 3 // 5) * len(fetched) // 2 + 1)) if self.order_state == 'recommend': fetched.sort(key=lambda x: x[5]) elif self.order_state == 'date': fetched.sort(key=lambda x: x[0]) for i in range(len(fetched)): self.widget_layout.add_widget( self.create_img(fetched[i], count, self)) self.scrollview.add_widget(self.widget_layout) self.widget_layout_main.add_widget(self.scrollview) self.widget_layout_main.add_widget(self.button_box) self.bind(is_screen=self.on_is_screen) self.bind(order_state=self.order_state_changed) sql_connection.close() def on_is_screen(self, instance, value): if value: self.items_bind() else: self.widget_layout.clear_widgets() self.scrollview.clear_widgets() self.widget_layout_main.clear_widgets() def set_screen(self, value): self.is_screen = value def order_state_changed(self, instance, value): self.widget_layout.clear_widgets() self.scrollview.clear_widgets() self.widget_layout_main.clear_widgets() sql_connection = sqlite3.connect('Records/records.db') cursor = sql_connection.cursor() cursor.execute('select * from shared_records') fetched = cursor.fetchall() (q, r), count = divmod(len(fetched), 4), 0 self.widget_layout = GridLayout( cols=2, spacing=10, size_hint_y=None, size=(Window.width, (Window.height * 3 // 5) * len(fetched) // 2 + 1)) if value == 'recommend': fetched.sort(key=lambda x: x[5]) elif value == 'date': fetched.sort(key=lambda x: x[0]) for i in range(len(fetched)): self.widget_layout.add_widget( self.create_img(fetched[i], count, self)) self.scrollview.add_widget(self.widget_layout) self.widget_layout_main.add_widget(self.scrollview) self.widget_layout_main.add_widget(self.button_box) sql_connection.close()
class Collection(BoxLayout): # TODO: # Connect with db # Give buttons actions (change window) # Fix sizing problem and color # Be consistent with other windows def __init__(self, **kwargs): super(Collection, self).__init__(**kwargs) self.set_contents() #Back button # btn_back = Button(text='Back', size_hint=(1, None)) # btn_back.background_color = (0.502, 0.502, 0.502, 1) ## btn_back.bind(on_press=partial(self.change_window, "Journal()")) # self.add_widget(btn_back) def set_contents(self): #Placeholder #self.entry_list = ["0227", "0228", "0229"] build_database() self.entry_list = [] self.entries = [] for entry in get_all_entries(): full_date = datetime.datetime.strptime(str(entry.time_created), "%Y-%m-%d %H:%M:%S.%f") formatted_date = '{} {} {}, {}'.format(full_date.strftime("%A"),\ full_date.strftime("%B"),\ full_date.strftime("%d"),\ full_date.year) self.entries.append(entry) self.entry_list.append(formatted_date) # print(entry.time_created) self.scrollview = ScrollView(size_hint=(None, None), size=(700, 400), pos_hint={ 'center_x': .5, 'center_y': .5 }) self.gridlayout = self.generate_entry_buttons(self.entry_list) self.scrollview.add_widget(self.gridlayout) self.add_widget(self.scrollview) global collection collection = self def generate_entry_buttons(self, entry_list): gridlayout = GridLayout(cols=1, spacing=10, size_hint_y=None) gridlayout.bind(minimum_height=gridlayout.setter('height')) #Generate a button for each entry for i in range(0, len(self.entry_list)): btn = Button(size_hint=(1, None)) btn.text = self.entry_list[i] btn.background_color = (0.278, 0.706, 0.459, 1) global given_day given_day = self.entries[i].time_created btn.bind(on_release=display_updateEntry) gridlayout.add_widget(btn) return gridlayout # def change_window(self, *args): # window = args[1] # self.clear_widgets() # self.add_widget(window) def search_entry(self, text): result = "" found = False if text != "": result = "No entry for this date." for i in range(0, len(self.entry_list)): if self.entry_list[i] == text: result = self.entry_list[i] found = True break if found: btn = Button(size_hint=(1, None)) btn.text = result btn.background_color = (0.278, 0.706, 0.459, 1) self.gridlayout.clear_widgets() self.gridlayout.add_widget(btn) else: #generate label instead label = Label(text=result) self.gridlayout.clear_widgets() self.gridlayout.add_widget(label) else: #i.e. search bar empty/cleared self.gridlayout = self.generate_entry_buttons(self.entry_list) self.scrollview.clear_widgets() self.scrollview.add_widget(self.gridlayout) return result
class FlightScreen(BaseScreen): def __init__(self, *args, **kwargs): super(FlightScreen, self).__init__(*args, **kwargs) """ Важны следующие переменные, осуществляющие возможность показа расписания: rasp_list - список полётов. формат (номер, время отправления, гейт, куда) Важно правильно(удобно) обрабатывать куда. Надо указывать обозначение из 3-х букв аэропорта, наверное. """ self.rasp_list = [('1', '13:00', 'A', 'Санкт-Петербург'), ('2', '14:00', 'B', 'Санкт-Петербург')] self.button_list = list() # Заголовок self.head = AviaLabel(size_hint=(.3, .1), font_size=25, pos_hint={ 'center_x': 0.15, 'center_y': .95 }) self.head.text = 'Flight' self.add_widget(self.head) # Окно поиска self.search = TextInput(multiline=False, size_hint=(1, 0.1), font_size=40, pos_hint={ 'center_x': .5, 'center_y': .85 }, on_text_validate=print) self.add_widget(self.search) #Элемент, осуществляющий прокрутку self.scrlV = ScrollView(do_scroll_x=False, do_scroll_y=True, size_hint=(1, .7), pos_hint={ 'center_x': .5, 'center_y': .45 }) self.add_widget(self.scrlV) # Рисуем отделяющую линию #Заполнение ScrollView self.fillScrView() def fillScrView(self): self.scrlV.clear_widgets() #Процедура осуществляет заполнение ScrollView данными о рейсах # Сетка осуществляющая возможность добавления элементов в ScrollView tableLayout = GridLayout(cols=3, spacing=1, size_hint_y=None, row_default_height=50) tableLayout.bind(minimum_height=tableLayout.setter('height')) writeHorLine(tableLayout, 0) for i in range(len(self.rasp_list)): #Номер tableLayout.add_widget( AviaLabel(size_hint_x=None, width=50, text=self.rasp_list[i][0])) #Пустой виджет, чтобы всё было красиво tableLayout.add_widget(AviaLabel()) # Время tableLayout.add_widget( AviaLabel(size_hint_x=None, width=100, text=self.rasp_list[i][1])) # Гейт tableLayout.add_widget( AviaLabel(size_hint_x=None, width=50, text=self.rasp_list[i][2])) # Куда tableLayout.add_widget( AviaLabel( #size_hint_x=None, width=100, text=self.rasp_list[i][3])) btn = Button(size_hint_x=None, width=100, text='Маршрут') btn.number = i #btnfunc = partial(self.patient_update, btn.number) #btn.bind(on_press=btnfunc) self.button_list.append(btn) tableLayout.add_widget(btn) writeHorLine(tableLayout, (i + 1) * 100) self.scrlV.add_widget(tableLayout)
class BooksListScreen(MDScreen): """Screen, contains the list of books with short information and the search bar. """ def __init__(self, **kwargs): super().__init__(**kwargs) # In this small block, books are generated from the json file. # (from the task) self.books = [] json_books = BooksProvider.load_books_from_json() for json_book in json_books: self.books.append(Book(**json_book)) add_book_button = MDFloatingActionButton( icon="plus", on_release=self.open_book_adder_screen) # Creating layout where all inner parts will be placed # (such as the foundation of the house) self.layout = MDBoxLayout(orientation="vertical") self.search_field = SearchField() # ScrollView allows to scroll list that was put inside of whis view. # If there is no ScrollView, the user will not be able to see list # items that are outside of the screen. self.scroll_view = ScrollView() # Books are put in the books_list # (the book_list is put in the scroll_view, this is realized in the # `load_books_list` method) self.load_books_list(self.books) # Search field and scroll view are put into the layout self.layout.add_widget(self.search_field) self.layout.add_widget(self.scroll_view) # And the layout is put into this screen self.add_widget(self.layout) self.add_widget(add_book_button) def load_books_list(self, books): """ Method that loads list of books to the screen. Separate method for loading the list is needed because when the book is deleted from the list, or when the user types something in searchbar, the list should be reloaded """ # Clear all elements in the scroll view # (this elements are books list items) self.scroll_view.clear_widgets() # List will contain all books mdlist = MDList() # Add books to the list one by one for book in books: list_item_widget = BookListItem(book) mdlist.add_widget(list_item_widget) # Add list to the scroll view self.scroll_view.add_widget(mdlist) def open_book_adder_screen(self, touch): """Called when the user taps on the button and releases it""" BooksTab.screens["book_adder"].load_content() BooksTab.screen_manager.transition.direction = "left" BooksTab.screen_manager.switch_to(BooksTab.screens["book_adder"])
class RecorderWidget(ScrollView): def __init__(self, *args, **kwargs): super(RecorderWidget, self).__init__(*args, **kwargs) self.first_layout = BoxLayout(orientation='vertical') self.record_layout = GridLayout(cols=1, spacing=10, size_hint_y=None) self.record_layout.bind(minimum_height=self.record_layout.setter('height')) self.list_layout = ScrollView() self.recorder = MediaRecorder() if not os.path.isdir("/sdcard/operator/recordings"): os.makedirs("/sdcard/operator/recordings") self.is_recording = False self.set_background(self.record_layout) self.set_background(self.first_layout) self.layout_gen() def set_background(self, layout): """ 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(0, 0, 0, 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 layout_gen(self): """ Generate the initial layout with the dynamic recording button. """ if not self.is_recording: rcrd_btn = Button(text="Start Recording", size_hint_y=.8) rcrd_btn.bind(on_release=lambda x: self.start()) else: rcrd_btn = Button(text="Stop Recording", size_hint_y=.2) rcrd_btn.bind(on_release=lambda x: self.stop()) list_btn = Button(text="Previous recordings", on_release=lambda x: self.prev_recordings(), size_hint_y=None, height=160) self.first_layout.clear_widgets() self.first_layout.add_widget(rcrd_btn) self.first_layout.add_widget(list_btn) self.clear_widgets() self.add_widget(self.first_layout) def init_recorder(self): """Initialize the recorder.""" storage_path = '/sdcard/operator/recordings/' + time.strftime('%Y-%m-%d-%H-%M-%S') + '.wav' self.recorder.setAudioSource(AudioSource.MIC) self.recorder.setOutputFormat(OutputFormat.THREE_GPP) self.recorder.setAudioEncoder(AudioEncoder.AMR_NB) self.recorder.setOutputFile(storage_path) self.recorder.prepare() def start(self): """Start the recorder.""" if self.is_recording: self.recorder.stop() self.recorder.reset() self.is_recording = False return self.init_recorder() self.recorder.start() self.is_recording = True self.layout_gen() toast("Recording started", True) def stop(self): """Stop the recorder.""" if not self.is_recording: return self.recorder.stop() self.recorder.reset() self.is_recording = False self.layout_gen() toast("Recording saved", True) def prev_recordings(self): """ Show a list of previous recordings. """ self.clear_widgets() self.record_layout.clear_widgets() self.list_layout.clear_widgets() #sub_layout = BoxLayout(orientation='vertical') sub_layout = GridLayout(cols=1, spacing=10, size_hint_y=None) sub_layout.bind(minimum_height=sub_layout.setter('height')) sub_layout.clear_widgets() titles = [] paths = [] for filename in os.listdir("/sdcard/operator/recordings"): if filename.endswith(".wav"): paths.append(os.path.join("/sdcard/operator/recordings/", filename)) name = filename[:-4] info = name.split('-') formatted_name = info[3] + ":" + info[4] + ":" + info[5] + " on " + info[1] + "/"+info[2] + "/" + info[0] titles.append(formatted_name) for title, path in zip(titles, paths): play_button = Button(text=title, size_hint_y=None, height=160) play_button.bind(on_release=functools.partial(self.play_prev, path)) sub_layout.add_widget(play_button) return_btn = Button(text="Previous", on_release=lambda x: self.show_menu(), size_hint_y=None, height=100) #self.list_layout.add_widget(sub_layout) self.record_layout.add_widget(sub_layout) self.record_layout.add_widget(return_btn) self.add_widget(self.record_layout) def play_prev(self, path, event): """ Play the selected recording. :param str path: The path of the .wav recording. """ sl = SoundLoader() sound = sl.load(path) sound.play() def show_menu(self): """ Shows the list of possible sounds. """ self.clear_widgets() self.record_layout.clear_widgets() self.layout_gen()
class TimetableScreen(Screen): def __init__(self, **kwargs): self.offset = 0 #offset is to generate the next/previous week's weekly schedules self.btn = [[None for _ in range(21)] for _ in range(21)] #initialize empty variables to be used by button slots Screen.__init__(self, **kwargs) self.Main = GridLayout(rows = 3) self.add_widget(self.Main) self.Dayslayout = self.create_days(self.offset) self.Buttonlayout = GridLayout() #initialize the base gridlayout for the timetable screen self.root = ScrollView() #to implement scroll view for the slots self.root.add_widget(self.Buttonlayout) #adding subsequent widgets to the scroll and grid layouts self.Main.add_widget(self.Dayslayout) self.Main.add_widget(self.root) self.popup = None def on_enter(self): self.update() def add_offset(self): #to add offset when user navigates to the next week self.offset += 1 self.update() def update(self): #to rebuild the screen widgets self.Main.clear_widgets() self.Buttonlayout.clear_widgets() self.Buttonlayout = self.create_buttons(self.offset) self.root.clear_widgets() self.root.add_widget(self.Buttonlayout) self.Dayslayout.clear_widgets() self.Dayslayout = self.create_days(self.offset) self.Main.add_widget(self.Dayslayout) self.Main.add_widget(self.root) def dec_offset(self): #to decrease offset when user navigates to previous week self.offset -= 1 self.update() def is_in_db(self, i, j): #checks if the slot at index, i,j exists in the database my_prof_slots = self.parent.dbManager.my_prof_slots slot_to_check = self.dictionary[j][i] for slot in my_prof_slots: if slot['time'] == slot_to_check['time'] and slot['date'] == slot_to_check['date']: return True return False def is_booked(self, i, j): #checks if a student has booked the available slot try: return self.dictionary[j][i]['student_id'] != 'null' except: return False def create_buttons(self, off): #to create the slot buttons which are representative of the dictionary of slots self.dictionary = GetWeek.getSlots(GetWeek.getWeek(off), self.parent.dbManager.my_prof['id']) for i in range(21): for j in range(5): for db_slot in self.parent.dbManager.my_prof_slots: local_slot = self.dictionary[j][i] if local_slot['date'] == db_slot['date'] and local_slot['time'] == db_slot['time']: self.dictionary[j][i] = db_slot ButtonLayout = GridLayout(cols=5, spacing=2, size_hint_y=None, height=21*80+22*2) for i in range(21): for j in range(5): if self.is_in_db(i,j): if self.is_booked(i,j): colorvar = GREEN #sets the slot colour to green if a student has booked it else: colorvar = YELLOW #sets the slot colour to yellow if the professor has declared his availability but is unbooked by students else: colorvar = BLUE #sets default colour to blue to represent lack of availability self.btn[j][i] = Button(text=str(self.dictionary[j][i]['time'])+'\n'+str(self.dictionary[j][i]['date']), size_hint_y=None, height=80, font_size = 18, halign='center', color = BLACK, background_color = colorvar, on_release = partial(self.select_slot, i, j), background_normal = '') ButtonLayout.add_widget(self.btn[j][i]) return ButtonLayout def create_days(self, off): #to create day labels to signify the days of the week DaysLayout = ColorGridLayout(cols = 5, spacing = 2, size_hint_y=None, width=160, color = Color(0.2,0.2,0.2,1)) mon = Label(text = 'Monday', font_size = 24) tue = Label(text = 'Tuesday', font_size = 24) wed = Label(text = 'Wednesday', font_size = 24) thu = Label(text = 'Thursday', font_size = 24) fri = Label(text = 'Friday', font_size = 24) days = [mon, tue, wed, thu, fri] nextweek = Button(text = 'Next Week', on_press = lambda x:self.add_offset()) prevweek = Button(text = 'Previous Week', on_press = lambda x:self.dec_offset()) refresh = Button(text = "Refresh", on_press = lambda x:self.refresh()) menu = Button(text = 'Menu', on_press = lambda x:self.show_menu()) legend = Button(text = 'Legend', on_press = lambda x:self.legend()) #insert buttons DaysLayout.add_widget(legend) DaysLayout.add_widget(prevweek) DaysLayout.add_widget(refresh) DaysLayout.add_widget(nextweek) DaysLayout.add_widget(menu) for day in days: DaysLayout.add_widget(day) return DaysLayout def select_slot(self, i, j, x): #if any slot is clicked, this function is called if self.is_booked(i, j): #if the slot is booked by a student current = self.dictionary[j][i] student_id = current['student_id'] student_details = self.parent.dbManager.full_db['students'][student_id] popup = Popup(title = 'Booking Details', content = Label(text = 'Time: {}\nDate: {}\nStudent ID: {}\nName: {}\nEmail: {}\nClass: {}'.format(current['time'], current['date'], current['student_id'], student_details['name'], student_details['email'], student_details['class']), font_size = 20), size_hint = (None, None), size = (350, 300)) popup.open() #pop up containing the student details who booked the selected slot elif self.is_in_db(i, j):#if a previously declared available slot is clicked, it undoes the confirmation and removes that slot from the database self.parent.dbManager.removeDBSlots(self.dictionary[j][i]) else: #if an empty slot is clicked, it is pushed to database with an UUID as the key for the slot self.dictionary[j][i]['id'] = str(uuid.uuid4()) self.parent.dbManager.updateDBSlots(self.dictionary[j][i]) self.update() def legend(self): #func to display a legend to display the differently coloured slots LegendLayout = GridLayout(rows = 2) picture = Button(background_normal = 'legend.jpg') closepopup = Button(text = 'Close', size_hint_y = (None), size = (50, 50)) LegendLayout.add_widget(picture) LegendLayout.add_widget(closepopup) popup = Popup(title = 'Legend', content = LegendLayout, auto_dismiss=False, size_hint = (None, None), size = (350, 400)) closepopup.bind(on_press=popup.dismiss) popup.open() def refresh(self): #to refresh the slots to check for updates in the slot bookings self.parent.dbManager.reloadSlots() self.update() def logout(self, instance): if self.popup != None: self.popup.dismiss() self.parent.transition = SlideTransition(direction="right") self.parent.current = "LOGIN_SCREEN" def show_menu(self): menu_layout = BoxLayout(orientation='vertical') logout = Button(text='Logout', on_press=self.logout) allocate = Button(text='Allocate Credits', on_press=self.show_allocate_credits) menu_layout.add_widget(allocate) menu_layout.add_widget(logout) self.popup = Popup(title='Menu',content=menu_layout, size_hint=(None,None), height=250, width=300) self.popup.open() #shows the popup to allow for allocation of credits def show_allocate_credits(self, instance): self.popup.dismiss() #dismiss menu allocate_layout = BoxLayout(orientation='vertical') self.student_id_text_input = TextInput(hint_text='Student ID', write_tab=False) self.amount_text_input = TextInput(hint_text='Credits Amount', write_tab=False) allocate = Button(text='Confirm', on_press=self.allocate_credits) allocate_layout.add_widget(self.student_id_text_input) allocate_layout.add_widget(self.amount_text_input) allocate_layout.add_widget(allocate) self.popup = Popup(title='Allocate Credits',content=allocate_layout, size_hint=(None,None), height=350, width=400) self.popup.open() #This is called when confirm is pressed. This function have some safety nets: # - Checks if amount is an integer # - Checks if the student exists (done in dbManager.allocate_credits) def allocate_credits(self, instance): try: amount = int(self.amount_text_input.text) except: self.show_message('Error', 'Please enter\n a valid amount\n(integers only)') return student_id = self.student_id_text_input.text success, message = self.parent.dbManager.allocate_credits(student_id, amount) if success == True: self.show_message('Success', '{} credits have\nbeen allocated to \n{}!'.format(amount, student_id)) else: self.show_message('Error', message) def show_message(self,title, message): #dismiss popup if there is one if self.popup != None: self.popup.dismiss() self.popup = Popup(title=title,content=Label(text=message), size_hint=(None,None), height=400, width=400) self.popup.open()
class ScreenBankGUI(ScreenBank): # Initialize the class. def __init__(self, Data): #Define window size. self.factor = Data.factor Config.set('graphics', 'width', Data.factor * 800) Config.set('graphics', 'height', Data.factor * 600) # Create main and middle layout self.layout = GridLayout(cols=1, row_force_default=False, height=600, width=800) self.MiddleLayout = GridLayout(cols=1, size_hint_y=11) self.MiddleScroll = ScrollView(size_hint=(1, None), size=(Data.factor * 400, Data.factor * 500), bar_width=4) self.settings_json = json.dumps([{ 'type': 'string', 'title': 'Job Manager IP', 'desc': 'Address of the JM.', 'section': 'example', 'key': 'jm_address' }, { 'type': 'numeric', 'title': 'Job Manager Port', 'desc': 'Port of the JM.', 'section': 'example', 'key': 'jm_port' }, { 'type': 'path', 'title': 'Library Path', 'desc': 'File with user functions.', 'section': 'example', 'key': 'lib_path' }, { 'type': 'numeric', 'title': 'Number of Tasks', 'desc': 'Amount of work to be done.', 'section': 'example', 'key': 'num_tasks' }]) self.settings_json2 = json.dumps([{ 'type': 'string', 'title': 'Virtual Machine IP', 'desc': 'Address of the Virtual Machine TM.', 'section': 'example', 'key': 'vm_ip' }, { 'type': 'string', 'title': 'Virtual Machine Port', 'desc': 'Port of the Virtual Machine TM.', 'section': 'example', 'key': 'vm_prt' }, { 'type': 'string', 'title': 'SSH Login', 'desc': 'Used to log in Virtual Machine TM.', 'section': 'example', 'key': 'ssh_login' }, { 'type': 'string', 'title': 'SSH Password', 'desc': 'Look behind you before typing.', 'section': 'example', 'key': 'ssh_pass' }]) self.settings_json3 = json.dumps([{ 'type': 'bool', 'title': 'SSH Port Fowarding', 'desc': 'Activate/Deactivate for connecting with Job Manager', 'section': 'example', 'key': 'ssh_pf_bool' }, { 'type': 'string', 'title': 'SSH Login', 'desc': 'Username used in SSH connection.', 'section': 'example', 'key': 'ssh_pf_login' }, { 'type': 'string', 'title': 'SSH Password', 'desc': 'Look behind you before typing.', 'section': 'example', 'key': 'ssh_pf_pass' }]) self.settings_json4 = json.dumps([{ 'type': 'string', 'title': 'Subscription ID', 'desc': 'ID obtained in Azure.', 'section': 'example', 'key': 'subscription_id' }, { 'type': 'path', 'title': 'Certificate Path', 'desc': 'Location of the path sent to Azure.', 'section': 'example', 'key': 'certificate_path' }]) # Layout that represents the list. self.ListLayout = GridLayout(cols=len(Data.columns), row_default_height=Data.factor * 30, row_force_default=True, rows=(Data.npp + 1), size_hint_y=10) self.NavigationLayout = GridLayout(cols=2, row_default_height=Data.factor * 15) # Layout that represents the VMlist.. self.VMListLayout = GridLayout(cols=len(Data.VMcolumns), row_default_height=Data.factor * 30, row_force_default=True, rows=(Data.npp + 1), size_hint_y=10) self.VMNavigationLayout = GridLayout(cols=2, row_default_height=Data.factor * 15) # Layout that represents the log self.LogWidget = TextInput(multiline=True) # Layout that represents the main Header self.HeaderLayout = GridLayout(cols=7, row_default_height=Data.factor * 15) # Name of current screen self.ScreenName = "List" # Task FIFOs self.workerFIFO = FIFO() self.mainFIFO = FIFO() #Extra Thread self.WorkerThread = threading.Thread(target=self.worker) self.WorkerThread.start() # Set consume as callback function Clock.schedule_interval(self.consume, 0.1) # Worker function. def worker(self): print 'worker' while (self.workerFIFO.task_end == False): # Check if it's over. self.workerFIFO.pendent_tasks.acquire() # Wait for tasks task = self.workerFIFO.popTask() # Pop task self.workerFIFO.runOneTask(task) # Run the task print 'Worker exited.' return # Function to kill/remove worker from tasks FIFO and exit. def quitWorker(self): self.workerFIFO.task_end = True # Mark as ended. self.workerFIFO.task_FIFO_mutex.acquire() # Add empty task self.workerFIFO.task_FIFO.append([1, None, []]) self.workerFIFO.task_FIFO_mutex.release() self.workerFIFO.pendent_tasks.release() # Release, it may be stopped def consume(self, *args): while (self.mainFIFO.tasks_in_FIFO > 0): task = self.mainFIFO.popTask() print 'Consuming:' + str(task) self.mainFIFO.runOneTask(task) # Build the main screen, with header, list, navigation and command. def buildMainScreen(self, Data): # Make header layout and add to the main. self.makeHeaderLayout() self.layout.add_widget(self.HeaderLayout) # Make list rows and add it to the middle layout self.MiddleLayout.add_widget(self.ListLayout) # Build list screen and add Middle Layout to the main layout. self.buildListScreen() self.layout.add_widget(self.MiddleLayout) # Make Console Layout and add it to the main layout self.CommandLayout = GridLayout(cols=1, row_default_height=Data.factor * 30, row_force_default=True) self.makeCommandLayout(Data, 'Welcome to SPITZ Monitor') self.layout.add_widget(self.CommandLayout) self.reDrawList(Data) # Build the list screen, just updating the middle layout. def buildListScreen(self): self.MiddleLayout.clear_widgets() self.MiddleLayout.add_widget(self.ListLayout) self.MiddleLayout.add_widget(self.NavigationLayout) # Build the list screen, just updating the middle layout. def buildVMListScreen(self): self.MiddleLayout.clear_widgets() self.MiddleLayout.add_widget(self.VMListLayout) self.MiddleLayout.add_widget(self.VMNavigationLayout) # Build the log screen, just updating the middle layout. def buildLogScreen(self): self.MiddleLayout.clear_widgets() self.MiddleScroll.clear_widgets() self.LogWidget.size_hint_y = None self.LogWidget.height = max( (len(self.LogWidget._lines) + 1) * self.LogWidget.line_height, self.MiddleScroll.size[1]) self.MiddleScroll.do_scroll_x = False self.MiddleScroll.add_widget(self.LogWidget) self.MiddleLayout.add_widget(self.MiddleScroll) # Build the Settings screen. def buildSettingsScreen(self): Runner.MyApp.open_settings(self.AppInstance) #self.layout.add_widget(self.sett) # Makes the layout of the list, adding the columns name, the ordering handlers and the actual page. def makeListLayout(self, Data): layout = self.ListLayout layout.clear_widgets() for col in range(len(Data.columns)): btnO = Button(text=Data.columns[col], size_hint_x=None, width=Data.wid[col]) btnO.bind(on_press=buttonOrder) layout.add_widget(btnO) upper = min(len(Data.rows), (Data.index + 1) * Data.npp) #print "upper: "+str(upper) for i in range(Data.index * Data.npp, upper): for j in range(len(Data.wid)): layout.add_widget( Button(text=str(Data.rows[i][j]), size_hint_x=None, width=Data.wid[j])) self.ListLayout = layout # Makes the buttons to navigate. Add the handler and text if there is any. def makeNavigationLayout(self, Data): layout = self.NavigationLayout layout.clear_widgets() if (Data.index > 0): btnP = Button(text="Previous", size_hint_x=None, width=Data.factor * 400) btnP.bind(on_press=buttonPrev) layout.add_widget(btnP) else: layout.add_widget( Button(text="", size_hint_x=None, width=Data.factor * 400)) if (len(Data.rows) > (Data.index + 1) * Data.npp): btnN = Button(text="Next", size_hint_x=None, width=Data.factor * 400) btnN.bind(on_press=buttonNext) layout.add_widget(btnN) else: layout.add_widget( Button(text="", size_hint_x=None, width=Data.factor * 400)) self.NavigationLayout = layout # Makes the layout of the VM list, adding the columns name, the ordering handlers and the actual page. def makeVMListLayout(self, Data): layout = self.VMListLayout layout.clear_widgets() for col in range(len(Data.VMcolumns)): btnO = Button(text=Data.VMcolumns[col], size_hint_x=None, width=Data.VMwid[col]) btnO.bind(on_press=buttonVMOrder) layout.add_widget(btnO) upper = min(len(Data.VMrows), (Data.index + 1) * Data.npp) #print "upper: "+str(upper) for i in range(Data.index * Data.npp, upper): # Create buttons. Actions buttons has actions. for j in range(len(Data.VMwid)): if j == len(Data.VMwid) - 1: # Button responsible for VM action, as it has different index and action, calls partial functions. btnA = Button(text=str(Data.VMrows[i][len(Data.VMwid) - 1]), size_hint_x=None, width=Data.VMwid[-1]) btnA.bind( on_press=partial(buttonSpitzAction, i, btnA.text)) layout.add_widget(btnA) elif j == len(Data.VMwid) - 3: # Button responsible for VM action, as it has different index and action, calls partial functions. btnA = Button(text=str(Data.VMrows[i][len(Data.VMwid) - 3]), size_hint_x=None, width=Data.VMwid[-3]) btnA.bind( on_press=partial(buttonAzureAction, i, btnA.text)) layout.add_widget(btnA) else: layout.add_widget( Button(text=str(Data.VMrows[i][j]), size_hint_x=None, width=Data.VMwid[j])) self.VMListLayout = layout # Makes the buttons to navigate the VM list. Add the handler and text if there is any. def makeVMNavigationLayout(self, Data): layout = self.VMNavigationLayout layout.clear_widgets() if (Data.index > 0): btnP = Button(text="Previous", size_hint_x=None, width=Data.factor * 400) btnP.bind(on_press=VMbuttonPrev) layout.add_widget(btnP) else: layout.add_widget( Button(text="", size_hint_x=None, width=Data.factor * 400)) if (len(Data.rows) > (Data.index + 1) * Data.npp): btnN = Button(text="Next", size_hint_x=None, width=Data.factor * 400) btnN.bind(on_press=VMbuttonNext) layout.add_widget(btnN) else: layout.add_widget( Button(text="", size_hint_x=None, width=Data.factor * 400)) self.VMNavigationLayout = layout # Makes the header layout, with the commands. def makeHeaderLayout(self): layout = self.HeaderLayout layout.clear_widgets() self.btnP = Button(text="Update", size_hint_x=None, width=self.factor * 125) self.btnP.bind(on_press=buttonUpdate) layout.add_widget(self.btnP) btnSep = Button(text="", size_hint_x=None, width=self.factor * 50) layout.add_widget(btnSep) self.btnLi = ToggleButton(text="List", group='menu', size_hint_x=None, width=self.factor * 125, state='down') self.btnLi.bind(on_press=buttonList) layout.add_widget(self.btnLi) self.btnV = ToggleButton(text="VM Launcher", group='menu', size_hint_x=None, width=self.factor * 125) self.btnV.bind(on_press=buttonVM) layout.add_widget(self.btnV) self.btnSta = ToggleButton(text="Statistics", group='menu', size_hint_x=None, width=self.factor * 125) self.btnSta.bind(on_press=buttonStatistics) layout.add_widget(self.btnSta) self.btnL = ToggleButton(text="Log", group='menu', size_hint_x=None, width=self.factor * 125) self.btnL.bind(on_press=buttonLog) layout.add_widget(self.btnL) self.btnS = Button(text="Settings", size_hint_x=None, width=self.factor * 125) self.btnS.bind(on_press=buttonSettings) layout.add_widget(self.btnS) def makeCommandLayout(self, Data, itext): layout = self.CommandLayout layout.clear_widgets() self.commandWidget = TextInput(multiline=False) self.commandWidget.readonly = True self.commandWidget.text = itext pb = ProgressBar(max=1000) pb.value = (Data.total_compl * 1000) / (int(Data.TotalTasks)) layout.add_widget(self.commandWidget) layout.add_widget(pb) #Get current time and add the message to the log pile. logmessage = datetime.now().strftime('%Y-%m-%d %H:%M:%S') logmessage = logmessage + " >>> " + itext Data.log = Data.log + "\n" + logmessage # Redraw list using current values of nodes. def reDrawList(self, Data): self.makeListLayout(Data) self.makeNavigationLayout(Data) def makeLogLayout(self, Data): self.LogWidget.readonly = True self.LogWidget.text = Data.log def screenChange(self, value, name): self.ScreenName = name if (value.state == 'normal'): value.state = 'down'