class Game(Screen): joystick_x = GAME.get("joystick", {}).get("x", 0.8) joystick_y = GAME.get("joystick", {}).get("y", 0.2) joystick_size = GAME.get("joystick", {}).get("size", 150) is_colliding = kp.BooleanProperty(False) # turn: last_magnitude = kp.NumericProperty(0) is_turn = kp.BooleanProperty(False) def __init__(self, **kwargs): super().__init__(**kwargs) def update(self, dt): # print("update", self.joystick.angle) self.player.update(dt) delta_magnitude = self.joystick.magnitude - self.last_magnitude if abs(delta_magnitude) == 1: self.is_turn = 1 else: self.is_turn = 0 self.last_magnitude = self.joystick.magnitude # print("delta_magnitude", delta_magnitude) signal = -1 if abs(self.joystick.angle) > 90 else 1 if self.is_turn: self.player.x += signal * self.player.agility / 5 else: delta = self.player.agility * self.joystick.magnitude * dt self.player.x += signal * delta # Borders: self.player.right = min(self.player.right, Window.width) self.player.x = max(self.player.x, 0) # update cars: self.car.y -= self.player.speed * dt if self.car.top <= 0: self.car.y = Window.height self.car.center_x = random.randint(0, Window.width) # collisions: if self.player.collide_widget(self.car): if not self.is_colliding: print("collide") self.is_colliding = True self.player.hull -= self.player.speed / 50 if self.player.hull <= 0: print("GAME OVER") self.player.new() self.car.y = Window.height self.player.speed *= 0.5 else: self.is_colliding = False
class TwitterConfig(Screen): colorInter = Properties.ListProperty([1, 1, 1, 1]) activeInter = Properties.BooleanProperty(False) halign = Properties.StringProperty('left') def __init__(self, **kwargs): super(TwitterConfig, self).__init__(**kwargs) self.pos_hint = {'center_y': 0.5, 'center_x': 0.5} def changeHalign(self, halign): self.halign = halign def saveConfig(self): #guardar las configs print(self.activeInter) dbWrapper.saveTwitter(self.activeInter, self.colorInter, self.halign) def pressedBack(self, widget): anim = Animation(pos_hint={"center_x": .5, "y": -.03}, duration=.1) anim += Animation(pos_hint={"center_x": .5, "y": 0}, duration=.1) anim.bind(on_complete=partial(self.goToMenuScreen)) anim.start(widget) def goToMenuScreen(self, widget, selected): self.saveConfig() App.get_running_app().root.transition = FadeTransition(duration=.3) App.get_running_app().root.current = "menu"
class ScatterColoredLabel(Scatter): background_color = Properties.ListProperty((0, 0, 0, 1)) visible = Properties.BooleanProperty() saveOnDBEvent = Properties.ObjectProperty() noteId = Properties.NumericProperty() text = Properties.StringProperty() def on_pos(self, instance, value): try: self.saveOnDBEvent.cancel() except: logging.info('Notes: No previous event') self.saveOnDBEvent = Clock.schedule_once(self.saveOnDB, 5) def saveOnDB(self, dt): noteToSave = Notes( _id=self.noteId, pinned=self.visible, text=self.text, posX=self.pos[0], posY=self.pos[1], scale=self.scale, rotation=self.rotation, rgb=[ self.background_color[0]*255, self.background_color[1]*255, self.background_color[2]*255, self.background_color[3], ], ) noteToSave.save() logging.info('DB: Updated note with id: ' + str(self.noteId))
class InfoDayConfig(Screen): colorHora = Properties.ListProperty([1, 1, 1, 1]) formatoHora = Properties.ListProperty(["24h", False]) colorFecha = Properties.ListProperty([1, 1, 1, 1]) formatoFecha = Properties.StringProperty("dd/mm") colorTemp = Properties.ListProperty([1, 1, 1, 1]) formatoTemp = Properties.StringProperty("metric") formatoClima = Properties.NumericProperty(2) c_id = Properties.StringProperty('6361046') activeInter = Properties.BooleanProperty(True) colorInter = Properties.ListProperty([1, 1, 1, 1]) def __init__(self, **kwargs): super(InfoDayConfig, self).__init__(**kwargs) self.pos_hint = {'center_y': 0.5, 'center_x': 0.5} self.getAllInter() def saveConfig(self): #guardar las configs if self.ids.textinput.text == "": self.c_id = self.ids.textinput.hint_text else: self.c_id = self.ids.textinput.text dbWrapper.saveHora("hora", self.formatoHora, self.colorHora) dbWrapper.saveFecha("fecha", self.formatoFecha, self.colorFecha) dbWrapper.saveTemp("temp", self.formatoTemp, self.colorTemp, self.c_id) dbWrapper.saveClima("weather", self.formatoClima, self.c_id) dbWrapper.saveInfoState(self.activeInter) dbWrapper.saveInternationalConfig("inter", self.colorInter) def getAllInter(self): datos = dbWrapper.getAllInterByMonth(str(strftime('%m'))) for j in datos: layout = BoxLayout(orientation='horizontal', size_hint_y=None, height=20, padding=[-40, 0, 0, 0]) layout.add_widget(Texto(text=str(j.dia))) layout.add_widget( Texto(text=str(j.info if len(j.info) < 25 else '...' + j.info[10:35] + '...'))) self.ids.todos.add_widget(layout) def pressedBack(self, widget): anim = Animation(pos_hint={"center_x": .5, "y": -.03}, duration=.1) anim += Animation(pos_hint={"center_x": .5, "y": 0}, duration=.1) anim.bind(on_complete=partial(self.goToMenuScreen)) anim.start(widget) def goToMenuScreen(self, widget, selected): self.saveConfig() App.get_running_app().root.transition = FadeTransition(duration=.3) App.get_running_app().root.current = "menu"
class Keybind(Button): """ Stores keybindings and manages actually sending them out of TabletKeyApp and to the next window. """ bound_keys = kp.ListProperty([]) tab_back = kp.BooleanProperty(False) position = kp.ListProperty([0, 0]) def output(self) -> dict: """ :return: A dictionary containing the vital binding properties of the Keybind so that they can be saved. """ return dict( position=self.pos, binding='+'.join(self.bound_keys), tab_back=self.tab_back ) def setup(self, name: str, binding: str, position: (list, tuple) = None, tab_back: bool = False) -> None: """ Sets a Keybind button up, or overwrites the existing properties if used on an existing Keybind object. :param name: A string, the user-supplied name of the keybinding to display on the button. :param binding: A string with each keyboard key separated by a plus (+) sign. :param position: A list or tuple, currently mostly a placeholder for when user-specified Keybind button placement is implemented. :param tab_back: A boolean, indicates whether, when this Keybind is pressed, the user wants to immediately tab back to the TabletKeyApp window. :return: None """ self.bound_keys = binding.split('+') self.tab_back = tab_back self.position = position if position is not None else [0, 0] self.text = name def send(self) -> None: """ Uses pyautogui to send the contents of the Keybind to the next window. :return: None """ pg.hotkey('alt', 'tab') # A slight delay is necessary to successfully input the # keystroke into the other window. time.sleep(0.1) pg.hotkey(*self.bound_keys) if self.tab_back: time.sleep(0.1) pg.hotkey('alt', 'tab')
class HoverBehavior(object): hovered = prop.BooleanProperty(False) hover_on_children = prop.BooleanProperty(False) border_point = prop.ObjectProperty(None) """border_point contains the last relevant point received by the Hoverable. This can be used in on_enter or on_leave in order to know where was dispatched the event. """ def __init__(self, **kwargs): self.register_event_type('on_enter') self.register_event_type('on_leave') window.Window.bind(mouse_pos=self.on_mouse_pos) super(HoverBehavior, self).__init__(**kwargs) def on_mouse_pos(self, *args): if not self.get_root_window(): return # do proceed if I'm not displayed <=> If have no parent pos = args[1] # Next line to_widget allow to compensate for relative layout inside = self.collide_point(*self.to_widget(*pos)) if self.hover_on_children: for w in self.children: #w in self.walk(restrict=True): inside |= w.collide_point(*w.to_widget(*pos)) if self.hovered == inside: # We have already done what was needed return self.border_point = pos self.hovered = inside if inside: self.dispatch('on_enter') else: self.dispatch('on_leave') def activate_hover(self): window.Window.bind(mouse_pos=self.on_mouse_pos) def deactivate_hover(self): window.Window.unbind(mouse_pos=self.on_mouse_pos) def on_enter(self): pass def on_leave(self): pass
class AbstractMenuItemHoverable(object): hovered = kp.BooleanProperty(False) def _on_hovered(self, new_hovered): if new_hovered: spacer_height = self.parent.spacer.height if self.parent.spacer else 0 self.show_submenu(self.width, self.height + spacer_height) else: self.hide_submenu()
class Sprite(Image): vel = kp.ObjectProperty(Vector(0, 0)) acc = kp.ObjectProperty(Vector(0, 0)) touch_the_ground = kp.BooleanProperty(True) last_moving = kp.StringProperty("right") have_the_key = kp.BooleanProperty(False) def __init__(self, game, source, **kwargs): super().__init__() self.source = source self.game = game self.width = kwargs.get("width", self.game.tile_size) self.height = kwargs.get("height", self.game.tile_size) self.x = kwargs.get("x", 0) self.y = kwargs.get("y", 0) index = kwargs.get("index", 1) self.game.add_widget(self, index=index) self._pos = Vector(*self.pos)
class MenuItem(widget.Widget): '''Background color, in the format (r, g, b, a).''' background_color_normal = prop.ListProperty([0.2, 0.2, 0.2, 1]) background_color_down = prop.ListProperty([0.3, 0.3, 0.3, 1]) background_color = prop.ListProperty([]) separator_color = prop.ListProperty([0.8, 0.8, 0.8, 1]) text_color_hovered = prop.ListProperty([1, 1, 1, 1]) text_color_unhovered = prop.ListProperty([.7, .7, .7, 1]) inside_group = prop.BooleanProperty(False) pass
class SmithyBox(BoxLayout): research = kp.BooleanProperty(False) def __init__(self, **kwargs): self.orientation = "vertical" super().__init__(**kwargs) Clock.schedule_once(self.update, 0) def update(self, *args): font_size = Window.width / 40 self.remove_all_widgets() self.app = App.get_running_app() for building_name, building_level in self.unit.requirements.get( "UNLOCK"): building = getattr(self.app, building_name) if building.level < building_level: text = "Requirements:\n" for building_name, building_level in self.unit.requirements.get( "UNLOCK"): text += "%s (%s)\n" % (building_name, building_level) building.bind(level=self.update) label = DarkLabel(text=text, font_size=font_size) self.add_widget(label) break else: # no break if self.research or "RESEARCH" not in self.unit.requirements: text = "Researched" label = DarkLabel(text=text, font_size=font_size) self.add_widget(label) self.image.source = "atlas://img/unit_big/unit_big/%s" % self.unit.name else: self.image.source = "atlas://img/unit_big/unit_big/%s_grey" % self.unit.name self.wood = self.unit.requirements.get("RESEARCH").get("WOOD") self.clay = self.unit.requirements.get("RESEARCH").get("CLAY") self.iron = self.unit.requirements.get("RESEARCH").get("IRON") text = "%s %s %s" % (self.wood, self.clay, self.iron) label = DarkLabel(text=text, font_size=font_size) self.add_widget(label) button = Button(text="Research") self.add_widget(button) button.bind(on_press=self.start_research) def start_research(self, *args): if self.wood < self.app.wood.current and self.clay < self.app.clay.current\ and self.iron < self.app.iron.current: self.app.wood.current -= self.wood self.app.clay.current -= self.clay self.app.iron.current -= self.iron self.research = True self.update() def remove_all_widgets(self): for widget in self.children.copy(): self.remove_widget(widget)
class GameApp(App): step_size = kp.NumericProperty(Window.height / N_OF_STEPS) debug = kp.BooleanProperty(DEBUG) def build(self): game = Game() game.frog = Player() game.new() game.add_widget(game.frog) Clock.schedule_interval(game.update, 1.0 / FPS) return game
class ColoredLabelConfig(GridLayout): editing = Properties.BooleanProperty(False) noteid = Properties.NumericProperty() pinned = Properties.BooleanProperty() bcolor = Properties.ListProperty((0, 0, 0, 1)) texto = Properties.StringProperty() def pinNote(self, noteId, pinned): ColoredLabel.visible = pinned != True self.pinned = pinned != True note = dbWrapper.findNoteById(noteId) note.pinned = pinned != True note.save() def on_editing(self, instance, value): if (value == False): nuevoTexto = self.ids.textValue.text noteToUpdate = Notes(_id=self.noteid, pinned=self.pinned, rgb=[ self.bcolor[0]*255, self.bcolor[1]*255, self.bcolor[2]*255, 1], text=nuevoTexto) noteToUpdate.save() def deleteNote(self): dbWrapper.deleteNoteById(self.noteid)
class GifConfig(ButtonBehavior, AsyncImage): imagenId = Properties.NumericProperty() pinned = Properties.BooleanProperty() delay = Properties.NumericProperty() def pinGif(self): self.pinned = not self.pinned gif = dbWrapper.findGifById(self.imagenId) gif.pinned = self.pinned gif.posX = 10 gif.posY = 10 gif.save()
class DraggableColoredLabel(DragBehavior, Label): background_color = Properties.ListProperty((0, 0, 0, 1)) visible = Properties.BooleanProperty() saveOnDBEvent = Properties.ObjectProperty() noteId = Properties.NumericProperty() def on_pos(self, instance, value): try: self.bringToFront() self.saveOnDBEvent.cancel() except: logging.info('Notes: No previous event') self.saveOnDBEvent = Clock.schedule_once(self.saveOnDB, 5) def bringToFront(self): parent = self.parent children = parent.children childOnTop = children[0] if (self != childOnTop): parent.remove_widget(self) parent.add_widget(self) def saveOnDB(self, dt): noteToSave = Notes( _id=self.noteId, pinned=self.visible, text=self.text, posX=self.pos[0], posY=self.pos[1], sizeX=self.size_hint[0], sizeY=self.size_hint[1], rgb=[ self.background_color[0]*255, self.background_color[1]*255, self.background_color[2]*255, self.background_color[3], ], ) noteToSave.save() logging.info('DB: Updated note with id: ' + str(self.noteId))
class InternationalConfig(Screen): colorInter = Properties.ListProperty([1, 1, 1, 1]) activeInter = Properties.BooleanProperty(True) def __init__(self, **kwargs): super(InternationalConfig, self).__init__(**kwargs) self.pos_hint = {'center_y': 0.5, 'center_x': 0.5} self.getAllInter() def printt(self, switch): print(switch.active) def saveConfig(self): # guardar las configs dbWrapper.saveInternationalConfig( "inter", self.colorInter if self.activeInter == False else [1, 1, 1, 0]) def getAllInter(self): datos = dbWrapper.getAllInterByMonth(str(strftime('%m'))) for j in datos: layout = BoxLayout(orientation='horizontal', size_hint_y=None, height=20, padding=[-40, 0, 0, 0]) layout.add_widget(Texto(text=str(j.dia))) layout.add_widget( Texto(text=str(j.info if len(j.info) < 25 else '...' + j.info[10:35] + '...'))) self.ids.todos.add_widget(layout) def pressedBack(self, widget): anim = Animation(pos_hint={"center_x": .5, "y": -.03}, duration=.1) anim += Animation(pos_hint={"center_x": .5, "y": 0}, duration=.1) anim.bind(on_complete=partial(self.goToMenuScreen)) anim.start(widget) def goToMenuScreen(self, widget, selected): self.saveConfig() App.get_running_app().root.transition = FadeTransition(duration=.3) App.get_running_app().root.current = "menu"
class GifConfig2(BoxLayout): imagenId = Properties.NumericProperty() pinned = Properties.BooleanProperty() delay = Properties.NumericProperty() updateListFunction = Properties.ObjectProperty() source = Properties.StringProperty() def pinGif(self): self.pinned = not self.pinned gif = dbWrapper.findGifById(self.imagenId) gif.pinned = self.pinned gif.posX = 10 gif.posY = 10 gif.save() def deleteGif(self): dbWrapper.deleteGifById(self.imagenId) self.updateListFunction()
class ClockWidget(Image): text = Properties.StringProperty('') chosenColor = Properties.ListProperty() segundos = Properties.BooleanProperty() horas = Properties.StringProperty() def on_text(self, *_): # Just get large texture:z l = Label(text=self.text) l.font_size = '1000dp' # something that'll give texture bigger than phone's screen size l.color = self.color l.texture_update() # Set it to image, it'll be scaled to image size automatically: self.texture = l.texture def __init__(self, **kwargs): super(ClockWidget, self).__init__(**kwargs) currentHora = getHora() self.chosenColor = currentHora.color self.segundos = currentHora.formato[1] self.horas = currentHora.formato[0] self.color = self.chosenColor self.text = datetime.now().strftime( self.update_secondsAndFormat(self.segundos, self.horas)) Clock.schedule_interval(self.update_time, 1) def update_time(self, *args): self.text = datetime.now().strftime( self.update_secondsAndFormat(self.segundos, self.horas)) self.color = self.chosenColor def update_secondsAndFormat(self, seconds, formato): if (seconds == True and formato == "24h"): return '%H:%M:%S' elif (seconds == True and formato == "12h"): return '%I:%M:%S %p' elif (seconds == False and formato == "24h"): return '%H:%M' else: return '%I:%M %p'
class Joystick(RelativeLayout): sticky = kp.BooleanProperty(False) # When False, the joystick will snap back to center on_touch_up. angle = kp.NumericProperty() def __init__(self, **kwargs): super().__init__(**kwargs) self.magnitude = 0 # def on_touch_down(self, *args): # # print("on_touch_down", args) def on_touch_move(self, *args): # print("on_touch_down", args) touch = args[0] # print(touch.pos, self.center) # self.stick.center = touch.pos center2touch = Vector(*touch.pos) - Vector(*self.center) # print("center2touch", center2touch) dist = center2touch.length() # print("dist", dist) self.angle = -Vector(1, 0).angle(center2touch) # print("angle", self.angle) pos2center = Vector(*self.center) - Vector(*self.pos) if dist > self.max_dist: dist = self.max_dist center2touch = center2touch.normalize() * self.max_dist self.stick.center = center2touch + pos2center self.magnitude = dist / self.max_dist # print("magnitude: %s" % (self.magnitude)) def on_touch_up(self, *args): # print("on_touch_up", args) if self.sticky: return self.stick.center = self.width / 2, self.height / 2 self.magnitude = 0
class MenuBar(box.BoxLayout): '''Background color, in the format (r, g, b, a).''' background_color = prop.ListProperty([0.2, 0.2, 0.2, 1]) separator_color = prop.ListProperty([0.8, 0.8, 0.8, 1]) selected = prop.BooleanProperty(False) def __init__(self, **kwargs): self.itemsList = [] super(MenuBar, self).__init__(**kwargs) def add_widget(self, item, index=0): if not isinstance(item, MenuItem): raise TypeError("MenuBar accepts only MenuItem widgets") super(MenuBar, self).add_widget(item, index) if index == 0: index = len(self.itemsList) self.itemsList.insert(index, item) def on_touch_down(self, touch): if self.collide_point(*touch.pos) == False: self.selected = False else: self.selected = True super(MenuBar, self).on_touch_down(touch) def on_selected(self, instance, value): for w in self.children: if isinstance(w, MenuSubmenu): if value: w.activate_hover() else: w.deactivate_hover() def close_all_menus(self): for ch in self.children: if isinstance(ch, MenuSubmenu): ch.close()
class MapWidget(Widget): draw_color = properties.ListProperty([0, 0, 0]) background = properties.ListProperty([1, 1, 1]) point_color = properties.ListProperty([0, 0, 0]) point_size = properties.ListProperty([10, 10]) draw_from_text_file = properties.BooleanProperty(False) dragging_map = properties.BooleanProperty(False) translation = properties.ListProperty([0, 0]) translation_last_point = properties.ListProperty([0, 0]) # data_file_path = properties.StringProperty() def __init__(self, **kwargs): working_dir = Path.cwd() self.data_file_path = str(Path(str(working_dir) + "/" + DATA_FILE)) self.objects = [] # Contains all objects that is drawn on the screen # Create empty file if not Path.exists(Path(self.data_file_path)): open(self.data_file_path, "w") super(MapWidget, self).__init__(**kwargs) self.bind(pos=self.resize, size=self.resize) def resize(self, *args): self.pos = self.pos self.size = self.size self.clear_canvas() if self.draw_from_text_file: self.draw_from_data_file() def on_touch_down(self, touch): if self.inside_widget(touch, "touch") and self.draw_from_text_file: self.dragging_map = True self.translation_last_point = [touch.x, touch.y] def on_touch_move(self, touch): # print("Touch: %f, %f" % (touch.x - self.center_x, touch.y - self.center_y)) if self.dragging_map: self.translation[0] += -(self.translation_last_point[0] - touch.x ) # - self.center_x self.translation[1] += -(self.translation_last_point[1] - touch.y ) #- self.center_y self.translation_last_point = [touch.x, touch.y] self.clear_canvas() if self.draw_from_text_file: self.draw_from_data_file() def on_touch_up(self, touch): if self.inside_widget(touch, "touch"): if self.dragging_map: self.dragging_map = False self.translation[0] += -(self.translation_last_point[0] - touch.x) self.translation[1] += -(self.translation_last_point[1] - touch.y) def clear_canvas(self): for obj in self.objects: self.canvas.remove(obj) self.objects.clear() if not self.dragging_map: self.draw_from_text_file = False def inside_widget(self, touch, type): bottom_left_x = self.center_x - self.width / 2 bottom_left_y = self.center_y - self.height / 2 top_right_x = self.center_x + self.width / 2 top_right_y = self.center_y + self.height / 2 if type == "touch": x = touch.pos[0] y = touch.pos[1] return x >= bottom_left_x and x <= top_right_x and y >= bottom_left_y and y <= top_right_y elif type == "pos": x = touch[0] y = touch[1] return x >= bottom_left_x and x <= top_right_x and y >= bottom_left_y and y <= top_right_y def draw_from_data_file(self): if not self.draw_from_text_file: self.draw_from_text_file = True with open(self.data_file_path, "r") as input_file: for line in input_file: line = line.rstrip() line = line.split(",") position = [ self.center_x + int(line[0]) + self.translation[0], self.center_y + int(line[1]) + self.translation[1] ] if self.inside_widget(position, "pos"): self.obj = InstructionGroup() self.obj.add(Color(*self.point_color)) self.obj.add(Ellipse(pos=position, size=self.point_size)) self.objects.append(self.obj) self.canvas.add(self.obj)
class Snake(App): sprite_size = kp.NumericProperty(SPRITE_SIZE) head = kp.ListProperty([0, 0]) snake = kp.ListProperty() length = kp.NumericProperty(LENGTH) fruit = kp.ListProperty([0, 0]) fruit_sprite = kp.ObjectProperty(Fruit) direction = kp.StringProperty(RIGHT, options=(LEFT, UP, RIGHT, DOWN)) buffer_direction = kp.StringProperty(RIGHT, options=(LEFT, UP, RIGHT, DOWN, '')) block_input = kp.BooleanProperty(False) alpha = kp.NumericProperty(0) def on_start(self): self.fruit_sprite = Fruit() self.fruit = self.new_fruit_location self.head = self.new_head_location Clock.schedule_interval(self.move, MOVESPEED) Window.bind(on_keyboard=self.key_handler) def on_fruit(self, *args): self.fruit_sprite.coord = self.fruit if not self.fruit_sprite.parent: self.root.add_widget(self.fruit_sprite) def key_handler(self, _, __, key, *____): try: self.try_change_direction(direction_keys[key]) except KeyError: pass def try_change_direction(self, new_direction): if direction_group[new_direction] != direction_group[self.direction]: if self.block_input: self.buffer_direction = new_direction else: self.direction = new_direction self.block_input = True def on_head(self, *args): self.snake = self.snake[-self.length:]+[self.head] def on_snake(self, *args): for index, coord in enumerate(self.snake): sprite = SPRITES[index] sprite.coord = coord if not sprite.parent: self.root.add_widget(sprite) @property def new_head_location(self): return [randint(2, dim - 2)for dim in[COLS, ROWS]] @property def new_fruit_location(self): while True: fruit = [randint(2, dim)for dim in[COLS, ROWS]] if fruit not in self.snake and fruit != self.fruit: return fruit def move(self, *args): self.block_input = False new_head = [sum(x) for x in zip(self.head, direction_values[self.direction])] if not self.check_in_bounds(new_head) or new_head in self.snake: return self.die() if new_head == self.fruit: self.length += 1 self.fruit = self.new_fruit_location if self.buffer_direction: self.try_change_direction(self.buffer_direction) self.buffer_direction = '' self.head = new_head def check_in_bounds(self, pos): return all(0 <= pos[x] < dim for x, dim in enumerate([COLS, ROWS])) def die(self): self.root.clear_widgets() self.alpha = ALPHA Animation(alpha=0, duration=MOVESPEED).start(self) self.snake.clear() self.length = LENGTH self.fruit = self.new_fruit_location self.head = self.new_head_location
class GlobalContainer(box.BoxLayout): graph_list = prop.ListProperty([]) active_graph = prop.ObjectProperty(None) name_manager = NameManager.Instance() show_sidepanel = prop.BooleanProperty(True) modestr = prop.StringProperty('insert') itemstr = prop.StringProperty('atom') modes = {'insert': asp.Mode.INSERT, 'select': asp.Mode.SELECT} items = { 'atom': asp.Item.ATOM, 'ellipse': asp.Item.ELLIPSE, 'rectangle': asp.Item.SQUARE } def __init__(self, **kwargs): super(GlobalContainer, self).__init__(**kwargs) self._keyboard = None self.request_keyboard() self.working_dir = './' self.tutorial = None self.popup_stack = [] window.Window.bind(on_resize=self.on_resize) if DEBUG: self.tracker = ClassTracker() self.tracker.track_object(MenuButton) self.all_objects = muppy.get_objects() def request_keyboard(self): self._keyboard = window.Window.request_keyboard( self._keyboard_release, self) self._keyboard.bind(on_key_down=self._on_keyboard_down) def _keyboard_catch(self): self._keyboard.bind(on_key_down=self._on_keyboard_down) def _keyboard_release(self): self._keyboard.unbind(on_key_down=self._on_keyboard_down) #self._keyboard = None def _on_keyboard_down(self, keyboard, keycode, text, modifiers): if keycode[1] == 'escape': base.stopTouchApp() elif keycode[1] == 'd': self.set_mode('insert') elif keycode[1] == 's': self.set_mode('select') elif keycode[1] == 'w': self.set_item('atom') elif keycode[1] == 'e': self.set_item('ellipse') elif keycode[1] == 'r': self.set_item('rectangle') elif keycode[1] == 'p': self.active_graph.show_tree(0) elif keycode[1] == 'o': self.view_symbolic_formula() elif keycode[1] == 'n': self.show_gringo_query() elif keycode[1] == 'g': self.show_save() elif keycode[1] == 'l': self.show_load() elif keycode[1] == 'y': print self.name_manager.get_all() print asp.Line.get_all_lines() elif keycode[1] == 't': self.toggle_sidepanel() elif keycode[1] == 'tab': if not self.show_sidepanel: self.toggle_sidepanel() self.ids.atom_input.focus = True elif keycode[1] == '.': if DEBUG: rb = refbrowser.InteractiveBrowser(self) rb.main() # self.all_objects = muppy.get_objects() # sum1 = summary.summarize(self.all_objects) # summary.print_(sum1) # self.tracker.create_snapshot() # self.tracker.stats.print_summary() return True def _focus_name_list(self, value): if value and (asp.AtomWidget.active_atom is not None): previous_name = asp.AtomWidget.active_atom.name for button in self.ids.name_list.children: if (button.text == previous_name) and (button.state != 'down'): button.trigger_action() elif value: if self.ids.name_list.children: self.ids.name_list.children[-1].trigger_action() else: for button in self.ids.name_list.children: if button.state == 'down': button.trigger_action() def on_resize(self, window, width, height): if self.show_sidepanel: self.ids.sidepanel.width = self.width * .15 self.active_graph.size = self.ids.stencilview.size def toggle_sidepanel(self): self.show_sidepanel = not self.show_sidepanel if self.show_sidepanel: width = self.width * .15 else: width = 0 anim.Animation(width=width, d=.15, t='out_quart').start(self.ids.sidepanel) if not self.show_sidepanel: self.ids.sidepanel.focus = False # Also release keyboard #self.update_sourcecode() def update_atom_editor(self, name): editor = self.ids.atom_editor if name == '': editor.disabled = True else: if editor.disabled: editor.disabled = False atom = self.name_manager.get(name) editor.update(atom) def update_atom(self, name, new_name='', new_hook_points=[], is_constant=False): atom = self.name_manager.get(name) if new_name <> '': atom.name = new_name if len(new_hook_points) == 4: atom.hook_points = new_hook_points # print id(atom.hook_points) atom.is_constant = is_constant def register_atom(self, name, hooks=[False, False, False, False], is_constant=False): if name == '': return children = self.ids.name_list.children new_button = None name_to_insert = name i = len(children) - 1 # If the name doesn't exist, register atom if self.name_manager.get(name) is None: self.name_manager.register(name, asp.Atom(name, hooks, is_constant)) # print id(self.name_manager.get(name).hook_points) # Insert in name_list sorted by name while i >= 0: if children[i].text < name_to_insert: #print children[i].text, '<', name_to_insert pass elif children[i].text == name_to_insert: # Already exists if children[i].state != 'down': children[i].trigger_action() return elif children[i].text > name_to_insert: #print children[i].text, '>', name_to_insert temp = children[i].text children[i].text = name_to_insert name_to_insert = temp if new_button == None: new_button = children[i] i -= 1 self.ids.name_list.add_widget(AtomSelectionButton(text=name_to_insert)) if new_button == None: new_button = children[0] if new_button.state == 'down': asp.AtomWidget.active_atom = self.name_manager.get(name) self.update_atom_editor(name) self.set_item('atom') else: new_button.trigger_action() def rename_atom(self, new_name): old_name = '' for button in self.ids.name_list.children: if button.state == 'down': old_name = button.text selected_button = button if (old_name != '') and (new_name != ''): try: atom = self.name_manager.get(old_name) exists = self.name_manager.get(new_name) assert atom is not None assert exists is None except AssertionError: #self.show_error('Name already exists.') print 'Name already exists.' return selected_button.text = new_name atom.name = new_name self.name_manager.unregister(old_name) self.name_manager.register(new_name, atom) self.update_atom_editor(new_name) def delete_atom(self): for button in self.ids.name_list.children: if button.state == 'down': self.name_manager.unregister(button.text) self.active_graph.delete_atom(button.text) asp.AtomWidget.active_atom = None self.ids.name_list.remove_widget(button) self.update_atom_editor('') def clear_atoms(self): self.ids.name_list.clear_widgets() self.name_manager.clear() self.update_atom_editor('') asp.AtomWidget.active_atom = None def new_graph(self): # TODO: Migrate to tab system asp.Line.clear_lines() self.clear_atoms() if self.active_graph is None: g = asp.RootWidget() self.graph_list.append(g) self.active_graph = g self.ids.stencilview.add_widget(g) else: self.active_graph.delete_tree() def close_graph(self): if self.active_graph is not None: asp.Line.clear_lines() self.active_graph.delete_tree() self.active_graph.delete_root() self.clear_atoms() self.graph_list.pop() self.active_graph = None def set_mode(self, mode): try: prev_mode = self.active_graph.mode new_mode = self.modes[mode] if new_mode == asp.Mode.INSERT: self.active_graph.show_hooks() else: if prev_mode == asp.Mode.INSERT: self.active_graph.hide_hooks() self.active_graph.mode = new_mode self.modestr = mode except KeyError as err: print 'ERROR: Invalid mode {0} requested.'.format(str(err)) def set_item(self, item): try: self.active_graph.item = self.items[item] self.itemstr = item except KeyError as err: print 'ERROR: Invalid item {0} requested.'.format(str(err)) except AttributeError: pass if item == 'atom': self._focus_name_list(True) else: self._focus_name_list(False) def push_popup(self, popup): self.popup_stack.append(popup) popup.open() def dismiss_popup(self): popup = self.popup_stack.pop() popup.dismiss() def show_rename_atom(self): content = TextInputDialog(caption="Enter new name", validate_callback=self.rename_atom, cancel=self.dismiss_popup) p = CustomPopup(self, title="Rename atom", content=content, size_hint=(0.4, 0.25)) self.push_popup(p) def show_load(self): content = LoadDialog(load=self.load, cancel=self.dismiss_popup) content.ids.filechooser.path = self.working_dir p = CustomPopup(self, title="Load file", content=content, size_hint=(0.9, 0.9)) self.push_popup(p) def show_save(self): content = SaveDialog(save=self.save, cancel=self.dismiss_popup) content.ids.filechooser.path = self.working_dir p = CustomPopup(self, title="Save file", content=content, size_hint=(0.9, 0.9)) self.push_popup(p) def show_export(self): content = ExportDialog(export=self.export, cancel=self.dismiss_popup) content.ids.filechooser.path = self.working_dir p = CustomPopup(self, title="Export file", content=content, size_hint=(0.9, 0.9)) self.push_popup(p) def show_gringo_query(self): caption = "Enter desired predicates separated by commas" content = TextInputDialog(caption=caption, validate_callback=self.gringo_query, dismiss_on_validate=False, focus=False, cancel=self.dismiss_popup) p = CustomPopup(self, title="Output predicates", content=content, size_hint=(0.4, 0.25)) self.push_popup(p) def show_stable_models(self, solver): models = solver.get_models() content = None if len(models) == 0: content = ErrorDialog('Unsatisfiable', cancel=self.dismiss_popup) else: solver.generate_graph(models[0]) content = StableModelDialog(solver, cancel=self.dismiss_popup) content.ids.img.reload() p = CustomPopup(self, catch_keyboard=False, title="Stable Models", content=content, size_hint=(0.9, 0.9)) self.push_popup(p) def show_error(self, err_str): content = ErrorDialog(err_str, cancel=self.dismiss_popup) p = CustomPopup(self, catch_keyboard=False, title="Error", content=content, size_hint=(0.4, 0.3)) self.push_popup(p) def show_about(self): content = AboutDialog(cancel=self.dismiss_popup) p = CustomPopup(self, catch_keyboard=False, title="About " + __title__, content=content, size_hint=(0.5, 0.5)) self.push_popup(p) def load(self, path, filename): self.close_graph() self.working_dir = path try: f = os.path.join(path, filename[0]) # Temporal line storage. Its contents are arranged as follows: # { line_id: (graph, hook_list) , ... } lines = {} with open(f, 'r') as stream: for line in stream: if line.startswith(NameParser.TOKENS['name']): name, hooks, is_constant = NameParser.parse_name(line) self.register_atom(name, hooks, is_constant) if line.startswith(NameParser.TOKENS['line']): line_id, graph = NameParser.parse_line(line) lines[line_id] = (graph, [None] * len(graph)) new_graph = lang.Builder.load_file(f) self.ids.stencilview.add_widget(new_graph) self.active_graph = new_graph #self.graph_list.pop() self.graph_list.append(new_graph) for w in self.active_graph.walk(restrict=True): if isinstance(w, asp.AtomWidget): w._deferred_init() for i in w.get_line_info(): line_id = i[0] hook_index = i[1] lines[line_id][1][hook_index] = i[2] elif isinstance(w, asp.NexusWidget): for i in w.line_info: line_id = i[0] hook_index = i[1] lines[line_id][1][hook_index] = w for line, info in lines.iteritems(): print line, info asp.Line.build_from_graph(info[0], info[1]) self.set_mode(self.modestr) self.set_item(self.itemstr) self.dismiss_popup() except (KeyboardInterrupt, SystemExit): raise except: self.dismiss_popup() self.close_graph() self.new_graph() self.show_error('Corrupted file.') def save(self, path, filename): self.working_dir = path with open(os.path.join(path, filename), 'w') as stream: stream.write('#:kivy 1.0.9\n\n') for (name, atom) in self.name_manager.get_all(): stream.write( NameParser.get_name_str(name, atom.hook_points, atom.is_constant)) for line in asp.Line.get_all_lines(): stream.write( NameParser.get_line_str(line.line_id, line.get_full_graph())) stream.write('\n') stream.write(self.active_graph.get_tree(0)) self.dismiss_popup() def export(self, path, filename): _, ext = os.path.splitext(filename) if ext == '.png': self.active_graph.export_to_png(os.path.join(path, filename)) elif ext == '.lp': rpn = self.active_graph.get_formula_RPN() constants = self.active_graph.get_constants() solver = eg_solver.Solver() solver.set_formula(rpn, constants) rules = solver.generate_asp_rules() with open(os.path.join(path, filename), 'w') as stream: for r in rules: stream.write(r) stream.write('\n') else: error_str = 'File extension not supported.' print error_str self.show_error(error_str) return self.dismiss_popup() def highlight_variables(self): self.active_graph.highlight_variables() def view_symbolic_formula(self): print self.active_graph.get_formula() def gringo_query(self, show_predicates): def generate_show_statements(predicates): pred_list = predicates.split(',') pred_list = map(lambda s: s.strip(), pred_list) n_args = (lambda name: self.name_manager.get(name).hook_points. count(True)) pred_list = [p + '/' + str(n_args(p)) for p in pred_list] show_list = ['#show {0}.'.format(p) for p in pred_list] return show_list self.dismiss_popup() rpn = self.active_graph.get_formula_RPN() rpn = norm.LIT.TRUE if rpn == '' else rpn constants = self.active_graph.get_constants() print 80 * '-' print 'RPN formula:\n', rpn solver = eg_solver.Solver() result = '' try: show_statements = [] if show_predicates: try: show_statements = generate_show_statements(show_predicates) except Exception: pass solver.set_formula(rpn, constants) result = solver.solve(show=show_statements) except norm.MalformedFormulaError: self.show_error('Malformed formula.') return except RuntimeError, e: print e self.show_error(str(e)) return self.show_stable_models(solver)
class DataManagement(MDBoxLayout): """Object of text fields and buttons for managing data""" ## Place holders \/ app = None ## Main APP reference item_data = prop.DictProperty() ## Dict of one row from database new_cls = prop.BooleanProperty() ## Bool for new item without parents view_only = prop.BooleanProperty() ## Enables/Disables text fields delete_dialog = prop.ObjectProperty() ## Delete Dialog popup object editing = prop.BooleanProperty(False) ## Enable/Disable editing mode def __init__(self,view_only=True,item_data=None,new_cls=False,**kwargs): super().__init__(**kwargs) self.app = MDApp.get_running_app() ## App object reference self.view_only = view_only self.item_data = item_data self.new_cls = new_cls self.set_fields() ## Set text field contents self.add_buttons() ## Add buttons to screen def set_fields(self): """Set rules for text fields content""" if self.view_only: ## populate fields with current database row self.populate_fields() else: ## if not view_only tests for new item if self.new_cls: ## if new item, changes label icon and adds 'None' to parent node self.ids.label_icon.icon = 'folder-plus-outline' self.ids.cls_sub.text = '[ Fundo ]' self.app.pcd_tree.disabled = True ## Locks treeview else: ## if not new item, adds current item code as item parent self.ids.cls_sub.text = self.item_data['cls_codigo'] def add_buttons(self): """Add buttons depending on view_only mode""" if self.view_only: buttons = ViewButtons(edit_code=str(self.item_data['cls_codigo'])) else: buttons = EditButtons() self.ids.btn_frame.clear_widgets() self.ids.btn_frame.add_widget(buttons) def enable_edit(self): """Enables editing of text fields""" toast(f'Editando {self.item_data["cls_nome"][:40]}{" [...]" if len(self.item_data["cls_nome"]) > 40 else ""}',1) self.ids.add_label.text = f'[b]Editando[/b] {self.item_data["cls_nome"]}' self.editing = True ## Enables editing self.view_only = False ## Disables view_only mode self.app.pcd_tree.disabled = True ## Locks treeview self.add_buttons() ## Add new buttons def populate_fields(self): """Populates text fields with current item_data data""" self.ids.add_label.text = f'Visualizando [b]{self.item_data["cls_nome"]}[/b]' self.ids.cls_nome.text = str(self.item_data['cls_nome']) self.ids.cls_codigo.text = str(self.item_data['cls_codigo']) self.ids.cls_sub.text = str(self.item_data['cls_sub']) if self.item_data['cls_sub'] != '' else '[ Fundo ]' self.ids.reg_abertura.text = str(self.item_data['reg_abertura']) self.ids.reg_desativacao.text = str(self.item_data['reg_desativacao']) self.ids.reg_reativacao.text = str(self.item_data['reg_reativacao']) self.ids.reg_mudanca_nome.text = str(self.item_data['reg_mudanca_nome']) self.ids.reg_deslocamento.text = str(self.item_data['reg_deslocamento']) self.ids.reg_extincao.text = str(self.item_data['reg_extincao']) self.ids.ativa.state = 'down' if self.item_data['cls_indicador'] == 'Ativa' else 'normal' self.ids.inativa.state = 'normal' if self.item_data['cls_indicador'] == 'Ativa' else 'down' self.ids.fase_corrente.text = str(self.item_data['fase_corrente']) self.ids.evento_fase_corrente.text = str(self.item_data['evento_fase_corrente']) self.ids.fase_intermediaria.text = str(self.item_data['fase_intermediaria']) self.ids.evento_fase_inter.text = str(self.item_data['evento_fase_inter']) self.ids.preservacao.state = 'down' if self.item_data['dest_final'] == 'Preservação' else 'normal' self.ids.eliminacao.state = 'normal' if self.item_data['dest_final'] == 'Preservação' else 'down' self.ids.reg_alteracao.text = str(self.item_data['reg_alteracao']) self.ids.observacoes.text = str(self.item_data['observacoes']) def show_delete_dialog(self): """Create and open delete dialog popup""" btn_cancel = MDFlatButton( text = 'Cancelar', theme_text_color = 'Custom', text_color = self.app.theme_cls.primary_color, on_release = lambda x: self.delete_dialog.dismiss()) btn_confirm = MDRaisedButton( text = 'Apagar', elevation = 11, on_release = lambda *x: (self.delete_item_from_db(), self.delete_dialog.dismiss())) self.delete_dialog = MDDialog( title = 'Deseja realmente apagar?', text = f'{self.item_data["cls_nome"]}', buttons = [btn_cancel,btn_confirm], auto_dismiss = False) self.delete_dialog.open() def delete_item_from_db(self): """Try deleting item from database, if successful, deletes item from treeview""" try: delete_row(self.item_data) except lib.utils.ItemHasChildren: toast('Classe possui dependentes! Impossível apagar.') else: toast(f'{self.item_data["cls_nome"][:40]}{" [...]" if len(self.item_data["cls_nome"]) > 40 else ""} apagado com sucesso!',1) self.app.root.ids.data_frame.clear_widgets() ## clear data management frame self.app.pcd_tree.delete_node_from_tree() ## delete item from treeview def text_fields_into_dict(self): """Gets data from text fields into dict :return: dict""" data = { 'parentId': self.item_data['legacyId'] if not self.new_cls else 'zero', 'cls_nome': self.ids.cls_nome.text.strip(), 'cls_codigo': self.ids.cls_codigo.text.strip(), 'cls_sub': self.ids.cls_sub.text.strip() if not self.new_cls else '', 'reg_abertura': self.ids.reg_abertura.text.strip(), 'reg_desativacao': self.ids.reg_desativacao.text.strip(), 'reg_reativacao': self.ids.reg_reativacao.text.strip(), 'reg_mudanca_nome': self.ids.reg_mudanca_nome.text.strip(), 'reg_deslocamento': self.ids.reg_deslocamento.text.strip(), 'reg_extincao': self.ids.reg_extincao.text.strip(), 'cls_indicador': 'Ativa' if self.ids.ativa.state == 'down' else 'Inativa', 'fase_corrente': self.ids.fase_corrente.text.strip(), 'evento_fase_corrente': self.ids.evento_fase_corrente.text.strip(), 'fase_intermediaria': self.ids.fase_intermediaria.text.strip(), 'evento_fase_inter': self.ids.evento_fase_inter.text.strip(), 'dest_final': 'Preservação' if self.ids.preservacao.state == 'down' else 'Eliminação', 'reg_alteracao': self.ids.reg_alteracao.text.strip(), 'observacoes': self.ids.observacoes.text.strip()} return data def insert_data_into_db(self): """Try to insert data into database, if successful regen treeview with new data""" data = self.text_fields_into_dict() ## Current item data dict parent = self.item_data if not self.new_cls else 'zero' ## set parent data if not new cls if self.ids.cls_nome.text.strip() and self.ids.cls_codigo.text.strip() != '': ## if required fields are not empty try: ## Instantiate data manager object \/ to_insert = ManageData(item_data=data,parent_data=parent) if not self.editing: to_insert.insert_into_db() ## inserts into database else: to_insert.update_db() ## updates database except: toast('Algo deu errado! Impossível salvar a Classe.') else: toast('Classe salva com sucesso!',1) self.app.root.ids.data_frame.clear_widgets() ## clear data management frame self.app.pcd_tree.regen_tree() ## Regenerates pcd treeview self.app.pcd_tree.switch_button(reset=True) ## switch toggle nodes button self.app.pcd_tree.disabled = False ## Unlocks treeview else: ## if required fields are empty toast('Campos obrigatórios estão em branco!') self.ids.cls_codigo.focus = True if self.ids.cls_codigo.text.strip() == '' else False self.ids.cls_nome.focus = True if self.ids.cls_nome.text.strip() == '' else False
class DraggableBaseWidget(ScatterLayout): dbName = Properties.StringProperty("base") do_rotation = False do_scale = False do_translation = False edit_mode = Properties.BooleanProperty(False) dbInstance = Properties.ObjectProperty() # FOR 2 SEC HOLDING heldForLongEnoughEvent = Properties.ObjectProperty() # TODO METER EL DEJAR PULSADO DOS SEGUNDOS # TODO QUE AL ENTRAR EN EDIT, SALGA UN MARQUITO Y EL ICONO DE DESPLAZAMIENTO (LAS FLECHAS EN CUATRO DIRECCIONES) # TODO QUE AL ESTAR EN EDIT, PULSAR FUERA DEL WIDGET LO GUARDE, EN VEZ DE ESPERAR POR UN DOUBLE CLICK DENTRO DEL WIDGET def __init__(self, **kwargs): super(DraggableBaseWidget, self).__init__(**kwargs) self.dbInstance = self.getInstanceFromDB() self.pos = (self.dbInstance.posX, self.dbInstance.posY) def on_edit_mode(self, instance, value): self.do_translation = (self.edit_mode, self.edit_mode) self.scale = 1 self.do_translation = value if (value): # Edit Mode activado transitionName = "in_out_quad" anim = Animation(scale=1.05, duration=.5, t=transitionName) anim += Animation(scale=.95, duration=.5, t=transitionName) anim.repeat = True anim.start(self) else: # Edit Mode desactivado self.updateInstanceOnDB() transitionName = "in_out_sine" Animation.stop_all(self) anim = Animation(scale=1.1, duration=.25, t=transitionName) anim += Animation(scale=.9, duration=.25, t=transitionName) anim += Animation(scale=1, duration=.125, t=transitionName) anim.start(self) # FOR DOUBLE TAP EDIT # def on_touch_move(self, touch): # if self.edit_mode: # return super().on_touch_move(touch) # def on_touch_down(self, touch): # if self.collide_point(touch.pos[0], touch.pos[1]) and touch.is_double_tap: # self.edit_mode = not self.edit_mode # else: # return super().on_touch_down(touch) def on_touch_up(self, touch): if (self.collide_point(touch.pos[0], touch.pos[1])): try: self.heldForLongEnoughEvent.cancel() except: pass return super().on_touch_up(touch) def on_touch_down(self, touch): if self.edit_mode: if (not self.collide_point(touch.pos[0], touch.pos[1])): self.edit_mode = False return super().on_touch_down(touch) else: if (self.collide_point(touch.pos[0], touch.pos[1])): try: self.heldForLongEnoughEvent.cancel() except: pass self.heldForLongEnoughEvent = Clock.schedule_once( self.heldForLongEnough, 1) else: return super().on_touch_down(touch) def heldForLongEnough(self, dt): self.edit_mode = True def updateInstanceOnDB(self): self.dbInstance.posX = self.pos[0] self.dbInstance.posY = self.pos[1] self.dbInstance.save() def getInstanceFromDB(self): try: instance = Draggable.objects.get(draggableName=self.dbName) except: instance = Draggable(draggableName=self.dbName, posX=self.pos[0], posY=self.pos[1]) instance.save() return instance
class ColoredLabel(Label): background_color = Properties.ListProperty((0, 0, 0, 1)) visible = Properties.BooleanProperty()
class Player(Widget): speedx = kp.NumericProperty(0) shield = kp.NumericProperty(100) alive = kp.BooleanProperty(True) lives = kp.NumericProperty(PLAYER_LIVES) hidden = kp.BooleanProperty(False) power = kp.NumericProperty(1) def __init__(self, **kwargs): super().__init__(**kwargs) self.groups = ["all_sprites"] self.keys = set() Window.bind(on_key_down=self._on_keyboard_down) Window.bind(on_key_up=self._on_keyboard_up) self.path = convert_list2path(init_path=IMG_DIR, path_list=PLAYER_PATH) self.w_hint = PLAYER_WIDTH self.h_hint = PLAYER_HEIGHT self.width = self.w_hint * Window.width self.height = self.h_hint * Window.height self.diameter = min(self.width, self.height) self.radius = self.diameter / 2 self.last_shot = time.time() with self.canvas: self.rect = Rectangle(pos=self.pos, size=self.size, source=self.path) Color(1, 1, 1, DEBUG_PLAYER_RADIUS * 0.5) self.ellipse = Ellipse(center=self.center, size=(self.diameter, self.diameter)) Color(1, 1, 1, 1) Color(1, 1, 1, DEBUG_PLAYER_RECT_HIT * 0.5) self.rect_hit = Rectangle(pos=self.pos, size=self.size) Color(1, 1, 1, 1) self.bind(pos=self.update_rect) self.new() def update_rect(self, *args): # hit box: self.ellipse.pos = (self.center_x - self.radius, self.center_y - self.radius) self.rect_hit.pos = self.pos # rect: self.rect.pos = self.pos self.rect.size = self.size def new(self): # print("new player") self.center_x = Window.width * 0.5 self.y = Window.height * PLAYER_Y self.speedx_hint = 0 self.speedy_hint = 0 self.shield = 100 self.lives = PLAYER_LIVES def _on_keyboard_down(self, *args): key = CONVERT_CODE2KEY.get(args[2]) self.keys.add(key) def _on_keyboard_up(self, *args): # print(keyboard, keycode) try: key = CONVERT_CODE2KEY.get(args[2]) self.keys.remove(key) except: pass def update(self, dt): # print("update player", self.x) self.speedx_hint = 0 if "right" in self.keys: self.speedx_hint = PLAYER_SPEED if "left" in self.keys: self.speedx_hint = -PLAYER_SPEED if "spacebar" in self.keys: self.shoot() self.x += self.speedx_hint * Window.width self.y += self.speedy_hint * Window.height if self.x < 0: self.x = 0 if self.right > Window.width: self.right = Window.width def power_up(self): self.power += 1 Clock.schedule_once(self.power_up_time_over, POWER_UP_TIME) def power_up_time_over(self, dt): self.power -= 1 def shoot(self): now = time.time() if now - self.last_shot > SHOOT_DELAY: self.last_shot = now if self.power == 1: Bullet(self.parent, self.center_x, self.top) elif self.power > 1: Bullet(self.parent, self.x, self.center_y) Bullet(self.parent, self.right, self.center_y) def lose_1_life(self): # hide the player temporarily self.hidden = True self.y -= 1000 # update player stats: self.lives -= 1 self.shield = 100 # check drawing lives: self.parent.remove_widget(self.parent.drawed_lives[-1]) self.parent.drawed_lives.pop() Clock.schedule_once(self.unhide, PLAYER_TIME_TO_UNHIDE) def unhide(self, dt): self.hidden = False print("parent", self.parent) self.center_x = self.parent.center_x self.y += 1000 def kill(self): for group_name in self.groups: group = getattr(self.parent, group_name) group.remove(self) self.parent.remove_widget(self) self.alive = False
class Game(Widget): paused = kp.BooleanProperty(False) score = kp.NumericProperty(0) explosion_over = kp.BooleanProperty(False) def __init__(self, **kwargs): self.player = Player() super().__init__(**kwargs) self.all_touchs = [] self.new() self.dir = path.dirname(__file__) self.bg = convert_list2path(init_path=IMG_DIR, path_list=BG) with self.canvas.before: self.rect = Rectangle(pos=self.pos, size=Window.size, source=self.bg) def new(self): self.score = 0 self.paused = False self.over = False self.all_sprites = [] self.bullets = [] self.mobs = [] self.power_ups = [] self.player.new() self.add_new_sprite(self.player) for _ in range(MOBS_N): Mob(self) # drawing init lives: self.drawed_lives = [] drawed_live_size = Window.width * LIVES_WIDTH, Window.height * LIVES_HEIGHT drawed_live_source = convert_list2path(init_path=IMG_DIR, path_list=PLAYER_PATH) for i in range(PLAYER_LIVES): x = Window.width * (LIVES_X + (LIVES_WIDTH + LIVES_MARGIN) * i) drawed_live_pos = x, Window.height * LIVES_Y self.drawed_lives.append(Life(*drawed_live_pos, *drawed_live_size, drawed_live_source)) self.add_widget(self.drawed_lives[-1]) def add_new_sprite(self, sprite): for group_name in sprite.groups: group = getattr(self, group_name) group.append(sprite) self.add_widget(sprite) def on_touch_down(self, touch): if self.paused: return print("on_touch_down") if len(self.all_touchs) > 0: self.player.keys.add("spacebar") self.all_touchs.append(touch) def on_touch_move(self, touch): if self.paused: return print(touch.dx) self.player.x += touch.dx def on_touch_up(self, touch): if self.paused: return print("on_touch_up") try: self.player.keys.remove("spacebar") except KeyError: pass try: self.all_touchs.remove(touch) except ValueError: pass def quit_game(self): # print("quit game") self.over = True for sprite in self.all_sprites.copy(): sprite.kill() def update(self, dt): if self.over: return False if self.paused: return self.rect.size = Window.size for sprite in self.all_sprites: sprite.update(dt) # check to see if a bullet hit a mob: hits = self.groupcollide(self.mobs, self.bullets, True, True) for hit in hits: self.score += 100 / hit.radius explosion = Explosion(center=hit.center, size=hit.size, _type="mob") self.add_widget(explosion) Mob(self) if random.random() < POWER_UP_CHANCE: power_up = PowerUp(hit.center) self.add_new_sprite(power_up) # check to see if a mob hit the player: hits = self.spritecollide(self.player, self.mobs, destroy=True, func="circular") for hit in hits: self.player.shield -= hit.radius explosion = Explosion(center=hit.center, size=hit.size, _type="mob") self.add_widget(explosion) Mob(self) if self.player.shield <= 0: self.death_explosion =\ Explosion(center=self.player.center, size=self.player.size, _type="player") self.add_widget(self.death_explosion) self.player.lose_1_life() # check to see if a player hit a powerup: hits = self.spritecollide(self.player, self.power_ups, True) for hit in hits: if hit._type == "shield": self.player.shield += random.randrange(SHIELD_MIN, SHIELD_MAX) if self.player.shield > 100: self.player.shield = 100 if hit._type == "gun": self.player.power_up() # if the player died and the explosion has finished playing: if self.player.lives == 0 and self.explosion_over: self.paused = True def spritecollide(self, sprite, group, destroy=False, func=None): def append(sprites_that_collide, sprite_i, destroy): sprites_that_collide.append(sprite_i) if destroy: sprite_i.kill() sprites_that_collide = [] for sprite_i in group: # print(sprite_i.pos, sprite_i.size) if sprite_i.collide_widget(sprite): # print("colide") if func == "circular": dist = Vector(*sprite.center).distance(Vector(*sprite_i.center)) if dist < sprite.radius + sprite_i.radius: append(sprites_that_collide, sprite_i, destroy) if not func: append(sprites_that_collide, sprite_i, destroy) return sprites_that_collide def groupcollide(self, group1, group2, destroy1=False, destroy2=False): sprites_that_collide = {} for g1_sprite in group1.copy(): for g2_sprite in group2.copy(): if g1_sprite.collide_widget(g2_sprite): if destroy1: g1_sprite.kill() if destroy2: g2_sprite.kill() try: sprites_that_collide[g1_sprite].append(g2_sprite) except: sprites_that_collide[g1_sprite] = [g2_sprite] return sprites_that_collide
class PCDTree(MDBoxLayout): """Treeview widget + buttons and dialogs manipulations refered to data""" btn_icon = prop.ListProperty(['unfold-more-horizontal','unfold-less-horizontal']) btn_text = prop.ListProperty(['Expandir Árvore', 'Retrair Árvore']) app = prop.ObjectProperty() ## Main APP reference toggled = prop.BooleanProperty(False) ## State of nodes nodes_dict = prop.DictProperty() ## All nodes instances callable via id dialog = prop.ObjectProperty() ## Search dialog search_widget = prop.ObjectProperty() ## Search dialog content instance def __init__(self, **kwargs): super().__init__(**kwargs) self.app = MDApp.get_running_app() self.populate_all_nodes() ## add nodes to the treeview self.search_widget = SearchFrame(self) ## creates search widget self.create_search_dialog() ## creates search dialog with `self.search_widget` """ Treeview methods """ def regen_tree(self): """Regenerates treeview nodes""" self.ids.treeview.root.nodes = [] ## clear nodes list self.ids.treeview.clear_widgets() ## clear nodes widgets self.toggled = False ## reset toggled state self.populate_all_nodes() ## populate treeview def _fetch_data_into_dict(self): """Fetches data from database and converts into dict returns a list with a dict for each row of the database :return: list""" query = 'SELECT * FROM PCD ORDER BY cls_codigo' data = self.app.cursor.execute(query).fetchall() description = [ col[0] for col in self.app.cursor.description ] return [ dict(zip(description,item)) for item in data ] def _create_all_nodes(self): """Generates all nodes and sorts them between parents and children, returns a tupple of (parents,children) lists :return: tupple""" self.nodes_dict = {} ## nodes instances for future reference parents = [] ## parents list children = [] ## children list data = self._fetch_data_into_dict() ## database items in dict for item in data: ## Creates treeview node object for each item in database \/ label = CustomTVLabel(text=f"{item['cls_codigo']} - {item['cls_nome']}") label.item_data = item ## add data dict to object label.bind(on_touch_down= lambda node, _: self._node_callback(node)) ## bind function ## Adding reference to dict self.nodes_dict[item['legacyId']] = label ## sorting parents and children if str(item['parentId']) == 'zero': parents.append(label) else: children.append(label) return parents,children def populate_all_nodes(self): """Populate treeview with new nodes""" parents,children = self._create_all_nodes() for parent in parents: ## add parents to tree self.ids.treeview.add_node(parent) ## adds children nodes into parents for parent in self.ids.treeview.iterate_all_nodes(): for child in children: if parent != self.ids.treeview.root: ## skip root node if child.item_data['parentId'] == parent.item_data['legacyId']: self.ids.treeview.add_node(child,parent=parent) children.remove(child) def _node_callback(self, node): """Callback for treeview nodes, checks if Form isn't already the selected node :param node: obj""" df_c = self.app.root.ids.data_frame.children if df_c and isinstance(df_c[0], DataManagement): ## Form exists if df_c[0].item_data['legacyId'] == node.item_data['legacyId']: ## Node is IN the current Form return ## Form doesn't exist or node != current node self.generate_data_frame(node) def generate_data_frame(self, node): """Creates data management obj from current node data. node = instance of selected node :param node: obj""" self.app.set_data_management_widget( view_only = True, item_data = node.item_data ) def delete_node_from_tree(self): """Delete selected node from tree""" selected_node = self.ids.treeview.get_selected_node() self.ids.treeview.remove_node(selected_node) self.nodes_dict.pop(selected_node.item_data['legacyId']) """ Buttons methods """ def toggle_all_nodes(self): """Toggles all nodes to toggled state""" for node in self.ids.treeview.iterate_all_nodes(): if node != self.ids.treeview.root: if self.toggled and node.is_open: ## close open node self.ids.treeview.toggle_node(node) if not self.toggled and not node.is_open: ## open closed nodes self.ids.treeview.toggle_node(node) ## switches toggled state \/ self.toggled = not self.toggled def switch_button(self,reset=False): """Switches tooltip and icon when pressed""" if reset: self.btn_icon = ['unfold-more-horizontal','unfold-less-horizontal'] self.btn_text = ['Expandir Árvore', 'Retrair Árvore'] else: self.btn_icon[0], self.btn_icon[1] = self.btn_icon[1], self.btn_icon[0] self.btn_text[0], self.btn_text[1] = self.btn_text[1], self.btn_text[0] """ Search dialog methods """ def create_search_dialog(self): """Creates search dialog""" if not self.dialog: self.dialog = MDDialog( title = 'Clique na Classe para encontrá-la na árvore', size_hint = (.5,.9), pos_hint = {'right': .9}, overlay_color = [0, 0, 0, .3], auto_dismiss = False, type = "custom", radius = [20,], content_cls = self.search_widget) self.dialog.bind(on_open = self.set_focus) def set_focus(self, *_): """Sets focus to text field""" self.search_widget.ids.to_search.focus = True
class NotesConfig(Screen): activeInter = Properties.BooleanProperty(True) showNotes = Properties.ObjectProperty(None) backg = Properties.ListProperty([224, 187, 228, 1]) ind = 0 def __init__(self, **kwargs): super(NotesConfig, self).__init__(**kwargs) self.pos_hint = {'center_y': 0.5, 'center_x': 0.5} self.showNotes.bind(minimum_height=self.showNotes.setter('height')) noteList = dbWrapper.getAllNotes() self.showNotesFunc(noteList) def goToMenuScreen(self, widget, selected): self.saveConfig() App.get_running_app().root.transition = FadeTransition(duration=.3) App.get_running_app().root.current = "menu" def showNotesFunc(self, noteList): for note in noteList: self.ids.showNotes.add_widget( ColoredLabelConfig(editing=False, noteid=note._id, texto=note.text, pinned=note.pinned, bcolor=(note.rgb[0] / 255, note.rgb[1] / 255, note.rgb[2] / 255, note.rgb[3]))) self.ind += 1 def writeNote(self, pinned, text, date, rgb): date = datetime.datetime.now() dbWrapper.saveNote(pinned, text, date, rgb) notas = dbWrapper.getAllNotes() nota = notas[len(notas) - 1] self.showNotesFunc([nota]) # -------------------------------- def saveConfig(self): # guardar las configs print(self.activeInter) dbWrapper.saveNoteState(self.activeInter) def pressedBack(self, widget): anim = Animation(pos_hint={"center_x": .5, "y": -.03}, duration=.1) anim += Animation(pos_hint={"center_x": .5, "y": 0}, duration=.1) anim.bind(on_complete=partial(self.goToMenuScreen)) anim.start(widget) def badAnim(self, boton): anim = Animation(backgSave=[.5, .4, .4, .2], duration=.1) anim += Animation(backgSave=[1, 1, 1, .2], duration=.1) anim.bind(on_complete=self.goTop) anim.start(boton) if self.ids.textinput.text == "": anim = Animation(canvBack=[1, 0, 0, .4], duration=.5) anim += Animation(canvBack=[1, 1, 1, .4], duration=.9) anim.start(self.ids.textinput) def goodAnim(self, boton): anim = Animation(backgSave=[1, 1, 1, .5], duration=.1) anim += Animation(backgSave=[1, 1, 1, .2], duration=.1) anim.bind(on_complete=self.goTop) anim.bind(on_complete=self.clearInputs) anim.start(boton) def goTop(self, boton, asd): anim = Animation(scroll_y=1, duration=.15) anim.start(self.ids.scrollCreateNote) def clearInputs(self, boton, asd): self.ids.textinput.text = "" def switchElegir(self, boton, asd): self.ids.panel.switch_to(self.ids.elegir)
class Game(Screen): all_crosses = kp.ListProperty() all_circles = kp.ListProperty() player = kp.StringProperty("") mob = kp.StringProperty("") game_over = kp.BooleanProperty(False) who_is_first = kp.StringProperty("mob") player_wins = kp.NumericProperty() mob_wins = kp.NumericProperty() def __init__(self, **kwargs): super().__init__() self.bind(size=self.draw_lines) self.bind(size=self.draw_crosses) self.bind(size=self.draw_circles) self.new_game() def new_game(self, *args): print("\nnew_game", args) self.all_circles = [] self.all_crosses = [] self.draw_lines() self.game_over = False self.who_is_first = "player" if self.who_is_first == "mob" else "mob" print("self.who_is_first", self.who_is_first) if self.who_is_first == "player": self.player = "cross" self.mob = "circle" elif self.who_is_first == "mob": print("is mob") self.player = "circle" self.mob = "cross" new_coord = self.calc_next_mob_coord() self.draw_symbol("mob", new_coord) print("self.player", self.player) def calc_lines(self): X = self.width Y = self.height x = X / 3 y = Y / 3 return [ [x, 0, x, Y], [2 * x, 0, 2 * x, Y], [0, y, X, y], [0, 2 * y, X, 2 * y], ] def draw_lines(self, *args): print("draw_lines()", self.size) self.canvas.clear() lines = self.calc_lines() with self.canvas: for line in lines: Line(points=line) def calc_cross(self, coord_x, coord_y): X = self.width Y = self.height x = X / 3 y = Y / 3 offset_x = coord_x * x offset_y = coord_y * y return [[offset_x, offset_y, x + offset_x, y + offset_y], [x + offset_x, offset_y, offset_x, y + offset_y]] def draw_crosses(self, *args): with self.canvas: for cross_coord in self.all_crosses: print("cross_coord", cross_coord) lines = self.calc_cross(*cross_coord) for line in lines: Line(points=line) def calc_circle(self, coord_x, coord_y): # print("calc_circle(%s, %s)" % (coord_x, coord_y)) # print(self.size) X = self.width Y = self.height x = X / 3 y = Y / 3 # print(x, y) offset_x = coord_x * x offset_y = coord_y * y return (offset_x, offset_y, x, y) def draw_circles(self, *args): print("draw_circles()", args, self.all_circles) with self.canvas: for circle_coord in self.all_circles: Line(ellipse=self.calc_circle(*circle_coord)) def calc_coord(self, pos_x, pos_y): print("calc_coord(%s, %s)" % (pos_x, pos_y)) X = self.width Y = self.height x = X / 3 y = Y / 3 coord_x = pos_x // x coord_y = pos_y // y print("X: %s Y: %s, x: %s y: %s, coord_x: %s coord_y: %s" % (X, Y, x, y, coord_x, coord_y)) if 0 <= coord_x < 3 and 0 <= coord_y < 3: return coord_x, coord_y def draw_symbol(self, who, new_coord): print("\ndraw_symbol(%s, %s)" % (who, new_coord)) symbol = getattr(self, who) if symbol == "cross": coords = self.all_crosses function = self.draw_crosses elif symbol == "circle": coords = self.all_circles function = self.draw_circles if new_coord in self.all_crosses + self.all_circles: return True coords.append(new_coord) function() if self.check_if_win_by_who(who): print("\n\n%s WIN with %s\n\n\n" % (who, symbol)) Factory.GameOverPopup(game=self, who_win=who).open() self.game_over = True if who == "player": self.player_wins += 1 else: self.mob_wins += 1 return True return False def on_touch_down(self, *args): print("on_touch_down", args[0].pos) print("self.all_circles", self.all_circles) if self.game_over: return pos = args[0].pos # Player: new_coord = self.calc_coord(*pos) if not new_coord: return print("self.player", self.player) if self.draw_symbol("player", new_coord): return # Mob: new_coord = self.calc_next_mob_coord() self.draw_symbol("mob", new_coord) def calc_next_mob_coord(self): print("calc_next_mob_coord()") avail_coords = [(x, y) for x in range(3) for y in range(3)] print("avail_coords", avail_coords) print("self.all_crosses + self.all_circles", self.all_crosses + self.all_circles) for coord in self.all_crosses + self.all_circles: print("coord", coord) avail_coords.remove(coord) print("avail_coords", avail_coords) if avail_coords: choosed_coord = random.choice(avail_coords) print("choosed_coord", choosed_coord) return choosed_coord def check_if_win_by_coords(self, coords): print("check_if_win_by_coords(%s)" % coords) all_possible_wins = [[(0, 0), (1, 1), (2, 2)], [(2, 0), (1, 1), (0, 2)], [(0, 0), (1, 0), (2, 0)], [(0, 1), (1, 1), (2, 1)], [(0, 2), (1, 2), (2, 2)], [(0, 0), (1, 0), (2, 0)], [(0, 0), (0, 1), (0, 2)], [(1, 0), (1, 1), (1, 2)], [(2, 0), (2, 1), (2, 2)]] if len(coords) < 3: return False for possible_win in all_possible_wins: # print("possible_win", possible_win) for possible_coord in possible_win: # print("possible_coord", possible_coord) # print(possible_coord not in coords, possible_coord, coords) if possible_coord not in coords: break else: # print(possible_win) return True return False def check_if_win_by_who(self, who): symbol = getattr(self, who) map_symbol = { "cross": "all_crosses", "circle": "all_circles", } coords = getattr(self, map_symbol[symbol]) return self.check_if_win_by_coords(coords)