class ClientApp(App): def build(self): # this is where the root widget goes # should be a canvas self.parent = Widget() # this is an empty holder for buttons, etc self.app = GUI() # Start the game clock (runs update function once every (1/60) seconds # Clock.schedule_interval(app.update, 1.0/60.0) self.sm = SmartStartMenu() self.sm.buildUp() def check_button(obj): # check to see which button was pressed if self.sm.buttonText == 'start': # remove menu self.parent.remove_widget(self.sm) # start the game print(' we should start the game now') Clock.unschedule(self.app.update) Clock.schedule_interval(self.app.update, 1.0/60.0) try: self.parent.remove_widget(self.aboutText) except: pass if self.sm.buttonText == 'about': self.aboutText = Label(text = 'Flappy Ship is made by Molecular Flow Games \n Check out: https://kivyspacegame.wordpress.com') self.aboutText.pos = (Window.width*0.45,Window.height*0.35) self.parent.add_widget(self.aboutText) # bind a callback function that repsonds to event 'on_button_release' by calling function check_button self.sm.bind(on_button_release = check_button) # setup listeners for smartstartmenu self.parent.add_widget(self.sm) self.parent.add_widget(self.app) # use this hierarchy to make it easy to deal w/buttons return self.parent
class ClientApp(App): def build(self): self.parent = Widget() self.app = GUI() self.sm = SmartStartMenu() self.sm.buildUp() def check_button(obj): # check to see which button was pressed if self.sm.buttonText == 'start': # remove menu self.parent.remove_widget(self.sm) # start game Clock.unschedule(self.app.update) Clock.schedule_interval(self.app.update, 1.0 / 60.0) try: self.parent.remove_widget(self.aboutText) except: pass if self.sm.buttonText == 'about': self.aboutText = Label( text=('Created by Ryan Choi, PCP Project ICS4U 2016')) self.aboutText.pos = (Window.width * 0.45, Window.height * 0.35) self.parent.add_widget(self.aboutText) self.sm.bind(on_button_release=check_button) # setup listeners for smartstartmenu self.parent.add_widget(self.sm) self.parent.add_widget(self.app) return self.parent
class ClientApp(App): def build(self): #this is where the root widget goes #should be a canvas self.parent = Widget() #this is an empty holder for buttons, etc self.app = GUI() self.sm = SmartStartMenu() self.sm.buildUp() def check_button(obj): #check to see which button was pressed if self.sm.buttonText == 'start': #remove menu self.parent.remove_widget(self.sm) #start the game print ' we should start the game now' Clock.unschedule(self.app.update) Clock.schedule_interval(self.app.update, 1.0/60.0) try: self.parent.remove_widget(self.aboutText) except: pass if self.sm.buttonText == 'about': self.aboutText = Label(text = 'Flappy Ship is made by Molecular Flow Games \n Check out: http://kivyspacegame.wordpress.com') self.aboutText.pos = (Window.width*0.45,Window.height*0.35) self.parent.add_widget(self.aboutText) #bind a callback function that repsonds to event 'on_button_release' by calling function check_button self.sm.bind(on_button_release = check_button) #setup listeners for smartstartmenu self.parent.add_widget(self.sm) self.parent.add_widget(self.app) #use this hierarchy to make it easy to deal w/buttons return self.parent
def build(self): widget = Widget() other = Widget() widget.add_widget(other) widget.remove_widget(other) return Window()
class MyAnimApp(App): def build(self): #pR = ProteinRepr('HPHPHHHHP','UDRLUDLRR',(400,400)) br = Background(10) self.parent= Widget() self.button= Button(text='Animated', font_size=14) self.button.bind(on_press=self.on_button_press) self.parent.add_widget(self.button) self.mw=myWidget() self.parent.add_widget(self.mw) self.parent.add_widget(br) return self.parent def on_button_press(self,instance): #anim = Animation(x=500, y=500, size=(100, 100), t='in_out_back') anim = Animation(size=(300, 300), color=[1.0,0,0,1], t='in_out_back') anim.bind(on_complete=self.completeAnim) #apply sequential animation #anim += Animation(pos=(200,70),t='in_out_back') #apply parallel animation #anim &= Animation(size=(100,50)) anim.start(instance) #self.mw.rect.pos=(200,100) self.mw.pos=(200,100) self.mw.color.a=0.5 def completeAnim(self, instance, value): self.parent.remove_widget(self.button)
class ClientApp(App): def build(self): self.parent = Widget() self.app = GUI() self.sm = SmartStartMenu() self.sm.buildUp() def check_button(obj): # check to see which button was pressed if self.sm.buttonText == 'start': # remove menu self.parent.remove_widget(self.sm) # start game Clock.unschedule(self.app.update) Clock.schedule_interval(self.app.update, 1.0 / 60.0) try: self.parent.remove_widget(self.aboutText) except: pass if self.sm.buttonText == 'about': self.aboutText = Label(text=('Created by Ryan Choi, PCP Project ICS4U 2016')) self.aboutText.pos = (Window.width * 0.45, Window.height * 0.35) self.parent.add_widget(self.aboutText) self.sm.bind(on_button_release=check_button) # setup listeners for smartstartmenu self.parent.add_widget(self.sm) self.parent.add_widget(self.app) return self.parent
def _remove_card_children(widget: Widget) -> List[CardWidget]: """Removes all CardWidget children of widget and returns them as a list.""" cards_children = [ child for child in widget.children if isinstance(child, CardWidget) ] for child in cards_children: widget.remove_widget(child) return cards_children
def test_parent_is_alive(): from kivy.uix.widget import Widget from kivy_garden.draggable import \ save_widget_location, restore_widget_location parent = Widget() parent.add_widget(Widget()) parent.add_widget(Widget()) w = Widget() parent.add_widget(w) parent.add_widget(Widget()) location = save_widget_location(w) assert location['index'] == 1 assert location['weak_parent']() is parent parent.remove_widget(w) restore_widget_location(w, location) assert w.parent is parent assert parent.children.index(w) == 1
def test_get_children_index(self): parent = Widget() child_1 = Widget() parent.add_widget(child_1) child_2 = Widget() parent.add_widget(child_2) child_3 = Widget() parent.add_widget(child_3) self.assertEqual(0, get_children_index(parent, parent)) self.assertEqual(1, get_children_index(parent, child_1)) self.assertEqual(2, get_children_index(parent, child_2)) self.assertEqual(3, get_children_index(parent, child_3)) self.assertIsNone(get_children_index(parent, Widget())) self.assertIsNone(get_children_index(child_2, parent)) parent.remove_widget(child_1) self.assertEqual(0, get_children_index(parent, parent)) self.assertIsNone(get_children_index(parent, child_1)) self.assertEqual(1, get_children_index(parent, child_2)) self.assertEqual(2, get_children_index(parent, child_3))
class GunApp(App): def build(self): self.parent = Widget() self.canvas = PainterWidget() self.parent.add_widget(self.canvas) self.canvas.my_init() return self.parent def create_label(self): Color(1, 1, 1, 1) self.l1 = (Label(text='You have destroyed all targets with ' + str(self.canvas.bullet_amount) + ' bullets', font_size='45px', pos=[width / 2, height / 2])) self.parent.add_widget(self.l1) self.l2 = (Label(text='Do you want to restart?', font_size='45px', pos=[width / 2, height / 2 - 50])) self.parent.add_widget(self.l2) self.b1 = (Button(text='Yes', font_size='45px', pos=[width / 2 - 70, height / 2 - 120], on_release=self.yes_handler, size=[70 * 1.5, 50 * 1.5])) self.parent.add_widget(self.b1) self.b2 = (Button(text='No', font_size='45px', pos=[width / 2 + 70, height / 2 - 120], on_release=self.no_handler, size=[70 * 1.5, 50 * 1.5])) self.parent.add_widget(self.b2) def yes_handler(self, event): self.parent.remove_widget(self.l1) self.parent.remove_widget(self.l2) self.parent.remove_widget(self.b1) self.parent.remove_widget(self.b2) self.canvas.my_init() def no_handler(self, event): quit()
def test_parent_is_dead(): import gc from kivy.uix.widget import Widget from kivy_garden.draggable import \ save_widget_location, restore_widget_location parent = Widget() parent.add_widget(Widget()) parent.add_widget(Widget()) w = Widget() parent.add_widget(w) parent.add_widget(Widget()) location = save_widget_location(w) assert location['index'] == 1 assert location['weak_parent']() is parent parent.remove_widget(w) del parent gc.collect() assert location['index'] == 1 assert location['weak_parent']() is None restore_widget_location(w, location) assert w.parent is None
class PlayGroundApp(App): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) def build(self): global label self.bl = Widget() self.layout = GridLayout(cols=20, rows=20, size=(700, 700)) self.lbl = Label(pos=(0, 700), text='GAME', font_size=30, size=(600, 70), color=[1, 1, 1, 1]) label = self.lbl for i in range(20): for j in range(20): new_botton = BOARD.list_of_buttons[i][j] self.layout.add_widget(new_botton) self.bl.add_widget(label) self.bl.add_widget( Button(pos=(600, 700), text='restart', size=(100, 70), on_press=self.restart)) self.bl.add_widget(self.layout) return self.bl def touch(instance): global BOARD global IS_GAME global label y = 19 - int(instance.y // 35) x = int(instance.x // 35) if type(BOARD.list_of_buttons[y][x]) is BombButton: IS_GAME = False if not IS_GAME: label.text = "GAMEOVER!!!" if label.text == "GAMEOVER!!!" and type( BOARD.list_of_buttons[y][x]) is BombButton: for i in range(20): for j in range(20): if type(BOARD.list_of_buttons[i][j]) is BombButton: BOARD.list_of_buttons[i][j].text = '*' BOARD.list_of_buttons[i][j].background_color = [ 1, 0, 0, 1 ] if label.text != "GAMEOVER!!!": BOARD.open((19 - int(instance.y // 35), int(instance.x // 35))) count = 0 for i in range(20): for j in range(20): if type(BOARD.list_of_buttons[i][j]) is not BombButton: if BOARD.list_of_buttons[i][j].touch: count += 1 if count == 325: label.text = "YOU WIN!!!" for i in range(20): for j in range(20): if type(BOARD.list_of_buttons[i][j]) is BombButton: BOARD.list_of_buttons[i][j].background_color = [ .16, .65, .38, 1 ] BOARD.list_of_buttons[i][j].text = '*', def restart(self, instance): global BOARD global IS_GAME global label self.bl.remove_widget(label) self.bl.remove_widget(self.layout) self.layout = GridLayout(cols=20, rows=20, size=(700, 700)) self.lbl = Label(pos=(0, 700), text='GAME', font_size=30, size=(600, 70), color=[1, 1, 1, 1]) label = self.lbl BOARD = Board() for i in range(20): for j in range(20): new_botton = BOARD.list_of_buttons[i][j] self.layout.add_widget(new_botton) self.bl.add_widget(label) self.bl.add_widget( Button(pos=(600, 700), text='restart', size=(100, 70), on_press=self.restart)) self.bl.add_widget(self.layout) label.text = "GAME" IS_GAME = True for i in range(20): for j in range(20): BOARD.list_of_buttons[i][j].text = '' BOARD.list_of_buttons[i][j].background_color = [1, 1, 1, .8] BOARD.list_of_buttons[i][j].touch = False
class WidgetTestCase(unittest.TestCase): def setUp(self): from kivy.uix.widget import Widget self.cls = Widget self.root = Widget() def test_add_remove_widget(self): root = self.root self.assertEqual(root.children, []) c1 = self.cls() root.add_widget(c1) self.assertEqual(root.children, [c1]) root.remove_widget(c1) self.assertEqual(root.children, []) def test_invalid_add_widget(self): from kivy.uix.widget import WidgetException try: # None of them should work self.root.add_widget(None) self.root.add_widget(WidgetException) self.root.add_widget(self.cls) self.fail() except WidgetException: pass def test_position(self): wid = self.root wid.x = 50 self.assertEqual(wid.x, 50) self.assertEqual(wid.pos, [50, 0]) wid.y = 60 self.assertEqual(wid.y, 60) self.assertEqual(wid.pos, [50, 60]) wid.pos = (0, 0) self.assertEqual(wid.pos, [0, 0]) self.assertEqual(wid.x, 0) self.assertEqual(wid.y, 0) def test_size(self): wid = self.root wid.width = 50 self.assertEqual(wid.width, 50) self.assertEqual(wid.size, [50, 100]) wid.height = 60 self.assertEqual(wid.height, 60) self.assertEqual(wid.size, [50, 60]) wid.size = (100, 100) self.assertEqual(wid.size, [100, 100]) self.assertEqual(wid.width, 100) self.assertEqual(wid.height, 100) def test_collision(self): wid = self.root self.assertEqual(wid.pos, [0, 0]) self.assertEqual(wid.size, [100, 100]) self.assertEqual(wid.collide_point(-1, -1), False) self.assertEqual(wid.collide_point(0, 0), True) self.assertEqual(wid.collide_point(50, 50), True) self.assertEqual(wid.collide_point(100, 100), True) self.assertEqual(wid.collide_point(200, 0), False) self.assertEqual(wid.collide_point(500, 500), False) # Currently rejected with a Shader didn't link, but work alone. @unittest.skip("Doesn't work with testsuite, but work alone") def test_export_to_png(self): from kivy.core.image import Image as CoreImage from kivy.uix.button import Button from os.path import join wid = Button(text='test', size=(200, 100), size_hint=(None, None)) self.root.add_widget(wid) tmp = mkdtemp() wid.export_to_png(join(tmp, 'a.png')) wid.export_to_png(join(tmp, 'b.png'), scale=.5) wid.export_to_png(join(tmp, 'c.png'), scale=2) CoreImage(join(tmp, 'a.png')).size == (200, 100) CoreImage(join(tmp, 'b.png')).size == (100, 50) CoreImage(join(tmp, 'c.png')).size == (400, 200) rmtree(tmp) self.root.remove_widget(wid)
class gridNeuronsWidget(Widget): def __init__(self, *args, **kwargs): Widget.__init__(self, *args, **kwargs) self.bind(pos=self.draw) self.bind(size=self.draw) self.gridLayer = BoxLayout(opacity=1) self.neuronLayer = Widget(opacity=1) self.add_widget(self.gridLayer) self.add_widget(self.neuronLayer) self._gridSize = 5 self._neuronSize = 60 self.initNeurons() def initNeurons(self): for i in range(self._gridSize + 1): for ii in range(self._gridSize + 1): n = Neuron(size=[100, 100]) NEURON_LIST.append(n) self.neuronLayer.add_widget(n) def removeNeurons(self, *args, **kwargs): for neuron in NEURON_LIST: self.neuronLayer.remove_widget(neuron) NEURON_LIST.clear() def reInitGrid(self, *args, **kwargs): _gridSize = kwargs.get('_gridSize', self._gridSize) if (_gridSize): self._gridSize = _gridSize self.removeNeurons() self.initNeurons() self.draw() def draw(self, *args, **kwargs): # method vars : _gridSize = kwargs.get('_gridSize', self._gridSize) if (_gridSize): self._gridSize = _gridSize if float(math.log(self._gridSize)) > 0: self.neuronSize = 1 / float(math.log(self._gridSize)) * 46 else: self.neuronSize = 60 GRIDWIDTH = self.size[0] GRIDHEIGHT = self.size[1] offsetY = ((GRIDWIDTH - (GRIDHEIGHT - (XMARGIN + YMARGIN))) / 2) - YMARGIN STEP = (GRIDHEIGHT - (XMARGIN + YMARGIN)) / self._gridSize with self.canvas.before: Color(*BACKGROUND_COLOR) self.bg = Rectangle(pos=self.pos, size=self.size) # GRID: self.gridLayer.canvas.clear() with self.gridLayer.canvas: Color(*GRID_COLOR) for i in range(self._gridSize): Line(points=[ XMARGIN + offsetY, YMARGIN + (i * STEP), (GRIDHEIGHT - YMARGIN) + offsetY, XMARGIN + (i * STEP) ], width=1) Line(points=[ XMARGIN + (i * STEP) + offsetY, YMARGIN, YMARGIN + (i * STEP) + offsetY, GRIDHEIGHT - XMARGIN ], width=1) if i == (self._gridSize - 1): Line(points=[ XMARGIN + offsetY, YMARGIN + ((i + 1) * STEP), (GRIDHEIGHT - YMARGIN) + offsetY, XMARGIN + ((i + 1) * STEP) ], width=1) Line(points=[ XMARGIN + ((i + 1) * STEP) + offsetY, YMARGIN, YMARGIN + ((i + 1) * STEP) + offsetY, GRIDHEIGHT - XMARGIN ], width=1) nC = 0 for i in range(self._gridSize + 1): for ii in range(self._gridSize + 1): pos = (int(XMARGIN + (i * STEP) + offsetY - self.neuronSize / 2), int((YMARGIN) + (ii * STEP)) - self.neuronSize / 2) NEURON_LIST[nC].size = [self.neuronSize, self.neuronSize] NEURON_LIST[nC].pos = pos nC += 1
class Node(Button): widget_pos = ListProperty() widget_size = ListProperty() node_center = ListProperty() def __init__(self, value, text, center, color): super().__init__() xo, yo = root.coordinates.x[0], root.coordinates.y[0] self.value = value self.coordinates = center self.visual_text = text self.visual_color = color self.r = 12.5 self.background_color = (0, 0, 0, 0) self.pos = [center[0] - self.r - xo, center[1] - self.r - yo] self.size = (2 * self.r, 2 * self.r) self.visual_widget = Widget() self.add_widget(self.visual_widget) self.visual_widget.pos = self.pos self.visual_widget.size = self.size self.apply_visual(source="circle2_normal.png", color=self.visual_color) self.edges = [] self.neighbor = [] self.press_count = -1 self.widget_pos = self.pos self.widget_size = self.size self.node_center = [center[0] - xo, center[1] - yo] self.anim_path = [] def animate(self, dt): if len(self.anim_path) != 0: self.node_center = [self.node_center[0] + self.anim_path[0][0], \ self.node_center[1] + self.anim_path[0][1]] self.anim_path.pop(0) for i in self.edges: i.update_line() else: Clock.unschedule(self.anim_scheduled) def apply_visual(self, source="circle2_normal.png", color=(202 / 255, 204 / 255, 206 / 255, 1)): self.visual_color = color col = Color(*color) self.visual_widget.canvas.add(col) circle_pos = [0, 0] self.circle_graphics = Ellipse( pos=circle_pos, size=[2 * 0.95 * self.r, 2 * 0.95 * self.r]) self.visual_widget.canvas.add(self.circle_graphics) self.node_img = Image(source=source) self.visual_widget.add_widget(self.node_img) self.node_img.pos = self.pos self.node_img.size = [2 * self.r, 2 * self.r] self.node_text = Label(text=self.visual_text, font_size=15, font_name='DejaVuSans') self.node_text.color = (1, 1, 1, 0.2) self.visual_widget.add_widget(self.node_text) self.node_text.pos = self.pos self.node_text.size = self.size def update_visual(self, source, color): self.clear_visual() self.apply_visual(source, color) def clear_visual(self): self.visual_widget.canvas.clear() self.visual_widget.remove_widget(self.node_img) self.visual_widget.remove_widget(self.node_text) def on_node_center(self, obj, value): self.pos = [value[0] - self.r, value[1] - self.r] self.widget_pos = self.pos self.circle_graphics.pos = [ self.pos[0] + 0.05 * self.r, self.pos[1] + 0.05 * self.r ] def on_widget_pos(self, obj, value): self.pos = value self.node_img.pos = value self.node_text.pos = value def on_widget_size(self, obj, value): self.size = value self.r = 0.5 * self.size[0] self.node_text.size = value @property def degree(self): return len(self.edges) def add_edge(self, edge): self.edges.append(edge) def connect_node(self, node): connected = root.axis.graph.connected_by_normal_edge([self, node]) if not connected: nodes = [self, node] line = Line(points = [nodes[0].center[0], nodes[0].center[1], \ nodes[1].center[0], nodes[1].center[1]], \ width = root.axis.graph.visual_size['lw']) color = Color(0 / 255, 150 / 255, 255 / 255, 0.5) root.axis.edge_drawer.canvas.add(color) root.axis.edge_drawer.canvas.add(line) edge_obj = NormalEdge(nodes, line, (0 / 255, 150 / 255, 255 / 255, 0.5)) nodes[0].add_edge(edge_obj) nodes[0].neighbor.append(nodes[1]) nodes[1].add_edge(edge_obj) nodes[1].neighbor.append(nodes[0]) else: pass def on_press(self): super().on_press() self.press_count *= -1 if self.press_count == 1: self.background_color = (0, 0.8, 0.9, 0.5) self.node_text.color = (1, 1, 1, 1) for i in root.axis.graph.nodes: if i != self: i.press_count = -1 i.background_color = (0, 0, 0, 0) i.node_text.color = (1, 1, 1, 0.2) root.info_label.text = "Info: " + node_info.format( self.node_text.text, self.value, self.degree, self) if len(self.anim_path) == 0: self.anim_path = animation_path() self.anim_scheduled = Clock.schedule_interval( self.animate, 1 / 60) if root.axis.connect_nodes_option == 1: if len(self.parent.a_to_b) < 2: self.parent.a_to_b.append(self) if len(self.parent.a_to_b) == 2: make_edge = not root.axis.graph.connected_by_normal_edge( self.parent.a_to_b) if not make_edge: self.parent.a_to_b.pop() root.info_label.text = "Info: " + "THESE NODES ARE ALREADY CONNECTED!" self.press_count = -1 self.background_color = (0, 0, 0, 0) self.node_text.color = (1, 1, 1, 0.2) else: nodes = self.parent.a_to_b line = Line(points = [nodes[0].center[0], nodes[0].center[1], \ nodes[1].center[0], nodes[1].center[1]], \ width = root.axis.graph.visual_size['lw']) color = Color(0 / 255, 150 / 255, 255 / 255, 0.5) root.axis.edge_drawer.canvas.add(color) root.axis.edge_drawer.canvas.add(line) edge_obj = NormalEdge( nodes, line, (0 / 255, 150 / 255, 255 / 255, 0.5)) nodes[0].add_edge(edge_obj) nodes[0].neighbor.append(nodes[1]) nodes[1].add_edge(edge_obj) nodes[1].neighbor.append(nodes[0]) for i in nodes: i.press_count = -1 i.background_color = (0, 0, 0, 0) i.node_text.color = (1, 1, 1, 0.2) self.parent.a_to_b = [] elif self.parent.connected_subgraph_option == 1: if len(self.edges) > 0: prev_subgraph = root.axis.graph.previous_selected_subgraph self.press_count = -1 self.background_color = (0, 0, 0, 0) self.node_text.color = (1, 1, 1, 0.2) if prev_subgraph != None: for i in prev_subgraph.nodes: i.background_color = (0, 0, 0, 0) i.node_text.color = (1, 1, 1, 0.2) if (not self in prev_subgraph.nodes): subgraph = root.axis.graph.find_subgraph( self.edges[0]) for i in subgraph.nodes: i.background_color = (0, 0.8, 0.9, 0.5) i.node_text.color = (1, 1, 1, 1) root.axis.graph.previous_selected_subgraph = subgraph else: root.axis.graph.previous_selected_subgraph = None else: subgraph = root.axis.graph.find_subgraph(self.edges[0]) for i in subgraph.nodes: i.background_color = (0, 0.8, 0.9, 0.5) i.node_text.color = (1, 1, 1, 1) root.axis.graph.previous_selected_subgraph = subgraph else: self.press_count = -1 self.background_color = (0, 0, 0, 0) self.node_text.color = (1, 1, 1, 0.2) elif self.parent.edit_node_option == 1: root.edit_text.text = self.visual_text else: self.background_color = (0, 0, 0, 0) self.node_text.color = (1, 1, 1, 0.2) if self.parent.connect_nodes_option == 1: if self.parent.a_to_b != []: self.parent.a_to_b.pop()
class gridNeuronsWidget(Widget): def __init__(self, *args, **kwargs): Widget.__init__(self, *args, **kwargs) # BINDERS !! self.bind(pos=self.draw) self.bind(size=self.draw) # BINDERS !! self.gridLayer = BoxLayout(opacity=1) self.neuronLayer = Widget(opacity=1) self.add_widget(self.gridLayer) self.add_widget(self.neuronLayer) self._gridSize = 1 self._neuronSize = 60 self.initNeurons() def initNeurons(self): for i in range(self._gridSize + 1): for ii in range(self._gridSize + 1): n = Neuron(size=[100, 100]) NEURON_LIST.append(n) self.neuronLayer.add_widget(n) def removeNeurons(self, *args, **kwargs): for neuron in NEURON_LIST: self.neuronLayer.remove_widget(neuron) NEURON_LIST.clear() def reInitGrid(self, *args, **kwargs): _gridSize = kwargs.get('_gridSize', self._gridSize) if (_gridSize): self._gridSize = _gridSize self.removeNeurons() self.initNeurons() self.draw() def draw(self, *args, **kwargs): # method vars : _gridSize = kwargs.get('_gridSize', self._gridSize) if (_gridSize): self._gridSize = _gridSize if float(math.log(self._gridSize)) > 0: self.neuronSize = 1 / float(math.log(self._gridSize)) * 40 else: self.neuronSize = 60 GRIDWIDTH = self.size[0] GRIDHEIGHT = self.size[1] offsetY = ((GRIDWIDTH - (GRIDHEIGHT - (XMARGIN + YMARGIN))) / 2) - YMARGIN STEP = (GRIDHEIGHT - (XMARGIN + YMARGIN)) / self._gridSize with self.canvas.before: Color(0.1, 0.1, 0.1, mode='rgb') self.bg = Rectangle(pos=self.pos, size=self.size) # GRID: self.gridLayer.canvas.clear() with self.gridLayer.canvas: Color(0.6, 0.6, 0.6, mode='rgb') for i in range(self._gridSize): Line(points=[ XMARGIN + offsetY, YMARGIN + (i * STEP), (GRIDHEIGHT - YMARGIN) + offsetY, XMARGIN + (i * STEP) ], width=1) Line(points=[ XMARGIN + (i * STEP) + offsetY, YMARGIN, YMARGIN + (i * STEP) + offsetY, GRIDHEIGHT - XMARGIN ], width=1) if i == (self._gridSize - 1): Line(points=[ XMARGIN + offsetY, YMARGIN + ((i + 1) * STEP), (GRIDHEIGHT - YMARGIN) + offsetY, XMARGIN + ((i + 1) * STEP) ], width=1) Line(points=[ XMARGIN + ((i + 1) * STEP) + offsetY, YMARGIN, YMARGIN + ((i + 1) * STEP) + offsetY, GRIDHEIGHT - XMARGIN ], width=1) print('|-----------------*-----------------|') nC = 0 for i in range(self._gridSize + 1): for ii in range(self._gridSize + 1): print('nC:' + str(nC)) print('neuronSize:' + str(self.neuronSize)) pos = (int(XMARGIN + (i * STEP) + offsetY - self.neuronSize / 2), int((YMARGIN) + (ii * STEP)) - self.neuronSize / 2) NEURON_LIST[nC].size = [self.neuronSize, self.neuronSize] NEURON_LIST[nC].pos = pos print(NEURON_LIST[nC].size) # NEURON_LIST[nC].size = (10,10) print('Will position neuron at: ' + str(pos)) nC += 1 print('|-----------------*-----------------|')
class DrawableVideo(Video): bbs = ListProperty(None) labelsColor = DictProperty(None) video_loaded = ObjectProperty(None) video_state_changed = ObjectProperty(None) add_bb = ObjectProperty(None) def __init__(self, **kwargs): super(DrawableVideo, self).__init__(**kwargs) self.activeLabel = None self.textureWidget = Widget() self.source = r'C:\bf1Movies\air.mp4' def on_size(self, instance, value): Clock.schedule_once(self.sched_on_bbs, 0) def on_norm_image_size(self, instance, value): rectPos = [(self.size[0] - self.norm_image_size[0]) / 2 + self.pos[0], (self.size[1] - self.norm_image_size[1]) / 2 + self.pos[1]] rectSize = self.norm_image_size self.textureWidget.pos = rectPos self.textureWidget.size = rectSize # print('texture size changed pos:{} , size:{}'.format(str(self.textureWidget.pos), str(self.textureWidget.size) )) def sched_on_bbs(self, dt): self.on_bbs(None, None) def on_loaded(self, inst, val): self.state = 'stop' self.video_loaded(val) rectPos = [(self.size[0] - self.norm_image_size[0]) / 2 + self.pos[0], (self.size[1] - self.norm_image_size[1]) / 2 + self.pos[1]] rectSize = self.norm_image_size self.add_widget(self.textureWidget) def on_source(self, inst, val): # when source changes the move is set to play #on_loaded should stop it right it's loaded self.state = 'play' def on_bbs(self, instance, value): # print(str(self.size)) self.textureWidget.clear_widgets() for bb in self.bbs: bbWidget = BoundingBoxWidget(labelName="") self.textureWidget.add_widget(bbWidget) bbWidget.update_bb(bb) bbWidget.set_name(bb.label) if bb.label in self.labelsColor: bbWidget.bbColor = get_color_from_hex( self.labelsColor[bb.label]) else: bbWidget.bbColor = [1, 1, 1] def on_labelsColor(self, instance, value): self.textureWidget.clear_widgets() for bb in self.bbs: bbWidget = BoundingBoxWidget(labelName="") self.textureWidget.add_widget(bbWidget) bbWidget.update_bb(bb) bbWidget.set_name(bb.label) if bb.label in self.labelsColor: bbWidget.bbColor = get_color_from_hex( self.labelsColor[bb.label]) else: bbWidget.bbColor = [1, 1, 1] def stop_pressed(self): if self.loaded is False: return self.state = 'stop' def play_pause_pressed(self): if self.loaded is False: return if self.state is 'play': self.state = 'pause' # self.ids.playPauseButton.text = 'play' elif self.state is 'pause' or self.state is 'stop': self.state = 'play' # self.ids.playPauseButton.text = 'pause' def on_touch_down(self, touch): if 'pos' not in touch.profile: return False if self.loaded is False: return False if self.textureWidget.collide_point(touch.pos[0], touch.pos[1]) is False: return False # else: # print('collide: {}, {} -> {}, {}'.format(str(self.textureWidget.pos), str(self.textureWidget.size), touch.pos[0], touch.pos[1])) if 'button' in touch.profile: isLeftButton = (touch.button == 'left') if isLeftButton: self.currentLabelLeftTop = touch.pos self.currentLabelPivot = touch.pos self.activeLabel = BoundingBoxWidget() self.textureWidget.add_widget(self.activeLabel) self.activeLabel.bbColor = get_color_from_hex(colors.YELLOW) def on_touch_move(self, touch): if self.activeLabel is None: return if 'pos' in touch.profile: if self.textureWidget.collide_point(touch.pos[0], touch.pos[1]) is False: touchX = touch.pos[0] touchY = touch.pos[1] if (touch.pos[0] < self.textureWidget.pos[0]): touchX = self.textureWidget.pos[0] elif (touch.pos[0] > self.textureWidget.pos[0] + self.textureWidget.size[0]): touchX = self.textureWidget.pos[ 0] + self.textureWidget.size[0] if (touch.pos[1] < self.textureWidget.pos[1]): touchY = self.textureWidget.pos[1] elif (touch.pos[1] > self.textureWidget.pos[1] + self.textureWidget.size[1]): touchY = self.textureWidget.pos[ 1] + self.textureWidget.size[1] touch.pos = (touchX, touchY) if self.currentLabelPivot is not None: xMin = min(self.currentLabelPivot[0], touch.pos[0]) xMax = max(self.currentLabelPivot[0], touch.pos[0]) yMin = max(self.currentLabelPivot[1], touch.pos[1]) yMax = min(self.currentLabelPivot[1], touch.pos[1]) self.currentLabelLeftTop = (xMin, yMin) self.currentLabelSize = (xMax - xMin, yMin - yMax) self.activeLabel.update(self.currentLabelLeftTop, self.currentLabelSize) def on_touch_up(self, touch): if self.activeLabel is not None: self.add_bb(self.activeLabel) self.textureWidget.remove_widget(self.activeLabel) self.currentLabelLeftTop = None self.currentLabelPivot = None self.activeLabel = None
class MagicTowerApp(App): def __init__(self): init_textures() super().__init__() def run(self): Window.size = (CELL_SIZE_RAW * (GRID_DIM + 9), CELL_SIZE_RAW * (GRID_DIM + 1)) try: super().run() except KeyboardInterrupt: pass floors.stopPreparation() def build(self): self.root = Widget() self.root.add_widget( Image(source="res/fullbg.png", allow_stretch=True, size=(CELL_SIZE * (GRID_DIM + 9), CELL_SIZE * (GRID_DIM + 1)))) self.grid = Widget(pos=(CELL_SIZE * 4.5, CELL_SIZE * 0.5)) # Cells are enlarged on each side to avoid gaps showing between the tiles self.cellDisplays = [[ TextureDisplay( pos=(self.grid.pos[0] + CELL_SIZE * col, self.grid.pos[1] + CELL_SIZE * (GRID_DIM - row - 1)), size=(CELL_SIZE, CELL_SIZE)) for col in range(GRID_DIM) ] for row in range(GRID_DIM)] for row in self.cellDisplays: for cell in row: self.grid.add_widget(cell) statusLabels = [ StatusLabel(font_size=CELL_SIZE * 0.4, halign="right", pos=(CELL_SIZE * 1.4375, CELL_SIZE * (3.71875 + GRID_DIM / 2 - 0.75 * i)), size=(CELL_SIZE * 1.96875, CELL_SIZE * 0.53125)) for i in range(4) ] for label in statusLabels: self.root.add_widget(label) keyLabels = dict( zip(KEYS, (StatusLabel(font_size=CELL_SIZE * 0.4, halign="right", pos=(CELL_SIZE * (6.40625 + GRID_DIM), CELL_SIZE * (1.625 + GRID_DIM / 2 - 0.75 * i)), size=(CELL_SIZE * 2.03125, CELL_SIZE * 0.53125)) for i in range(len(KEYS))))) for key in KEYS: self.root.add_widget(keyLabels[key]) specialItemDisplays = [[ TextureDisplay(pos=(CELL_SIZE * (0.5 + col), CELL_SIZE * (GRID_DIM / 2 - 0.25 - row)), size=(CELL_SIZE, CELL_SIZE)) for col in range(3) ] for row in range(5)] for row in specialItemDisplays: for cell in row: self.root.add_widget(cell) self.hero = Hero(self.grid, *statusLabels, keyLabels, specialItemDisplays) self.grid.add_widget(self.hero) self.spark = TextureDisplay(size=(CELL_SIZE, CELL_SIZE)) self.floorLabel = StatusLabel(font_size=CELL_SIZE * 0.5, halign="center", pos=(CELL_SIZE * 0.59375, CELL_SIZE * (4.625 + GRID_DIM / 2)), size=(CELL_SIZE * 2.8125, CELL_SIZE * 0.65625)) self.root.add_widget(self.floorLabel) self.monsterDisplay = TextureDisplay( pos=(CELL_SIZE * (6.5 + GRID_DIM), CELL_SIZE * (GRID_DIM / 2 - 1.6875)), size=(CELL_SIZE, CELL_SIZE)) self.root.add_widget(self.monsterDisplay) self.monsterTexture = SingleTexture(-1, -1) self.monsterTexture.initialize(self.monsterDisplay) self.monsterNameLabel = StatusLabel( font_size=CELL_SIZE * 0.36, halign="center", pos=(CELL_SIZE * (5.53125 + GRID_DIM), CELL_SIZE * (GRID_DIM / 2 - 2.34375)), size=(CELL_SIZE * 2.9375, CELL_SIZE * 0.53125)) self.root.add_widget(self.monsterNameLabel) monsterStatusLabels = [ StatusLabel(font_size=CELL_SIZE * 0.4, halign="right", pos=(CELL_SIZE * (6.4375 + GRID_DIM), CELL_SIZE * (GRID_DIM / 2 - 2.96875 - 0.625 * i)), size=(CELL_SIZE * 1.9375, CELL_SIZE * 0.53125)) for i in range(3) ] for label in monsterStatusLabels: self.root.add_widget(label) self.monsterHealthLabel, self.monsterAttackLabel, self.monsterDefenceLabel = monsterStatusLabels self.loading = Widget(pos=(CELL_SIZE * 4.5, CELL_SIZE * 0.5)) borderWidth = round(CELL_SIZE * 0.06) with self.loading.canvas: Color(204 / 255, 204 / 255, 204 / 255) Rectangle(pos=(self.loading.pos[0] + CELL_SIZE * (GRID_DIM / 2 - LOADING_MAX_LENGTH / 2) - borderWidth, self.loading.pos[1] + CELL_SIZE * (GRID_DIM / 2 - 0.65) - borderWidth), size=(borderWidth, CELL_SIZE * 0.5 + borderWidth * 2)) Rectangle(pos=(self.loading.pos[0] + CELL_SIZE * (GRID_DIM / 2 + LOADING_MAX_LENGTH / 2), self.loading.pos[1] + CELL_SIZE * (GRID_DIM / 2 - 0.65) - borderWidth), size=(borderWidth, CELL_SIZE * 0.5 + borderWidth * 2)) Rectangle(pos=(self.loading.pos[0] + CELL_SIZE * (GRID_DIM / 2 - LOADING_MAX_LENGTH / 2) - borderWidth, self.loading.pos[1] + CELL_SIZE * (GRID_DIM / 2 - 0.65) - borderWidth), size=(CELL_SIZE * LOADING_MAX_LENGTH + borderWidth * 2, borderWidth)) Rectangle( pos=(self.loading.pos[0] + CELL_SIZE * (GRID_DIM / 2 - LOADING_MAX_LENGTH / 2) - borderWidth, self.loading.pos[1] + CELL_SIZE * (GRID_DIM / 2 - 0.15)), size=(CELL_SIZE * LOADING_MAX_LENGTH + borderWidth * 2, borderWidth)) self.loading.add_widget( Label(text="Preparing floors...", font_size=CELL_SIZE * 0.5, color=(204 / 255, 204 / 255, 204 / 255, 1), center=(self.loading.pos[0] + CELL_SIZE * GRID_DIM / 2, self.loading.pos[1] + CELL_SIZE * (GRID_DIM / 2 + 0.4)))) self.loadingBar = ColorWidget( (204 / 255, 204 / 255, 204 / 255), pos=(self.loading.pos[0] + CELL_SIZE * (GRID_DIM / 2 - LOADING_MAX_LENGTH / 2), self.loading.pos[1] + CELL_SIZE * (GRID_DIM / 2 - 0.65))) self.loading.add_widget(self.loadingBar) self.dialog = Label(font_size=CELL_SIZE * 0.5, color=(0, 0, 0), halign="center", valign="middle", markup=True, pos=(CELL_SIZE * 5.3, CELL_SIZE * 2.5), size=(CELL_SIZE * (GRID_DIM - 1.6), CELL_SIZE * (GRID_DIM - 4))) with self.dialog.canvas.before: Color(0, 1, 1, 0.8) Rectangle(pos=self.dialog.pos, size=self.dialog.size) self.dialog.bind(on_ref_press=self.onDialogPress) self.handbook = handbook.HandbookDisplay(pos=(CELL_SIZE * 4.5, CELL_SIZE * 0.5)) return self.root def on_start(self): global _app _app = self self.blockedActions = 0 self.floorsLoading = 0 self.currentFloor = None self.highestFloor = None self.saved = True self.filepath = None self.keyboard = Window.request_keyboard(lambda: None, self.root) self.keyboard.bind(on_key_down=self.onKeyDown) self.showStartDialog() self.updateEvent = Clock.schedule_interval(self.update, 0.3) def on_stop(self): self.updateEvent.cancel() def onKeyDown(self, keyboard, keycode, text, modifiers): print("Pressed", keycode[1], ("with " + ", ".join(modifiers)) if modifiers else "") if self.dialogHotkeys != None: self.handleDialog(keycode[1]) elif self.isFree(): if keycode[1] == "down": self.interactBy(Point(1, 0)) elif keycode[1] == "up": self.interactBy(Point(-1, 0)) elif keycode[1] == "right": self.interactBy(Point(0, 1)) elif keycode[1] == "left": self.interactBy(Point(0, -1)) elif keycode[1] == "l": self.loadGame() elif keycode[1] == "s": self.saveGame() elif keycode[1] == "h": self.hero.handbook.tryUse() elif keycode[1] == "pageup": self.hero.flyingWand.tryUp() elif keycode[1] == "pagedown": self.hero.flyingWand.tryDown() elif keycode[1] == "m": self.hero.mattock.tryUse() # cheats elif keycode[1] == "a" and "alt" in modifiers: self.moveByFloors(1) elif keycode[1] == "z" and "alt" in modifiers: self.moveByFloors(-1) def onDialogPress(self, instance, value): print("Pressed ref", value) if self.dialogHotkeys != None: self.handleDialog(value) def isFree(self): return self.currentFloor != None and (not self.floorsLoading) and ( not self.blockedActions) def showStartDialog(self): text = "Magic Tower!" + LARGE_TEXT_GAP + "[ref=n][u]N[/u]ew Game[/ref]" + \ SMALL_TEXT_GAP + "[ref=l][u]L[/u]oad Game[/ref]" actions = { "n": lambda: self.newGame() or True, "l": lambda: self.loadFile() or True } self.showDialog(text, actions) def showFloor(self, floor, completion=None): self.root.remove_widget(self.grid) self.root.add_widget(self.loading) self.floorLabel.text = "Floor %d" % floor self.floorsLoading = floors.prepareFloor(floor, self.handleFloorPrepared) self.floorsLoadingCompletion = completion self.targetFloorLoading = floor self.handleFloorPrepared(0) def handleFloorPrepared(self, amount): if self.floorsLoading: self.loadingBar.resize( amount / self.floorsLoading * CELL_SIZE * LOADING_MAX_LENGTH, CELL_SIZE * 0.5) if amount == self.floorsLoading: self.root.add_widget(self.grid) self.root.remove_widget(self.loading) self.floorsLoading = 0 self.currentFloor = self.targetFloorLoading if self.currentFloor > self.highestFloor: self.highestFloor = self.currentFloor for row in range(GRID_DIM): for col in range(GRID_DIM): floors.floors[self.currentFloor][row][col].initialize( self.cellDisplays[row][col]) if self.floorsLoadingCompletion: self.floorsLoadingCompletion() self.floorsLoadingCompletion = None def update(self, dt): if not self.floorsLoading and self.currentFloor != None: for row in range(GRID_DIM): for col in range(GRID_DIM): floors.floors[self.currentFloor][row][col].update() self.hero.updateSpecials() self.monsterTexture.update() def saveGame(self): def save(path): data = { "hero": self.hero.getState(), "floors": floors.getState(), "currentFloor": self.currentFloor, "highestFloor": self.highestFloor } with gzip.open(path, "wb") as f: pickle.dump(data, f) self.filepath = path self.saved = True if self.filepath: save(self.filepath) else: self.blockActions() def saveAfterGetPath(path): save(path) self.unblockActions() saveload.showSave(saveAfterGetPath, self.unblockActions) def loadGame(self): if self.filepath: def work(): with gzip.open(self.filepath, "rb") as f: data = pickle.load(f) floors.setState(data["floors"]) self.highestFloor = data["highestFloor"] self.showFloor(data["currentFloor"]) self.hero.setState(data["hero"]) self.saved = True return True if self.saved: work() else: text = "Your current progress will be lost!\nStill loading previous save?" + LARGE_TEXT_GAP + \ "[ref=y]< Y > Yes" + " " * 21 + "[/ref]" + SMALL_TEXT_GAP + "[ref=" + REF_KEY_ANY + "]<Any> Return to game[/ref]" actions = {"y": work, REF_KEY_ANY: lambda: True} self.showDialog(text, actions) def loadFile(self): self.blockActions() def loadAfterGetPath(path): self.filepath = path self.loadGame() self.unblockActions() def loadCancel(): self.showStartDialog() self.unblockActions() saveload.showLoad(loadAfterGetPath, loadCancel) def newGame(self): floors.newState() START_FLOOR, START_ROW, START_COL = floors.START self.highestFloor = START_FLOOR self.showFloor(START_FLOOR) self.hero.newState() self.hero.setLocation(Point(START_ROW, START_COL)) self.saved = False def blockActions(self): self.blockedActions += 1 def unblockActions(self): self.blockedActions -= 1 def showSpark(self): self.spark.pos = self.hero.pos self.spark.draw(texture(24, 16)) self.grid.add_widget(self.spark) def hideSpark(self): self.grid.remove_widget(self.spark) def showMonster(self, monster): if monster: self.monsterTexture = monster.menu_texture.copy() self.monsterNameLabel.text = monster.name self.monsterHealthLabel.text = str(monster.health) self.monsterAttackLabel.text = str(monster.attack) self.monsterDefenceLabel.text = str(monster.defence) else: self.monsterTexture = SingleTexture(*EMPTY_TEXTURE) self.monsterNameLabel.text = "" self.monsterHealthLabel.text = "" self.monsterAttackLabel.text = "" self.monsterDefenceLabel.text = "" self.monsterTexture.initialize(self.monsterDisplay) def updateMonsterHealth(self, health): self.monsterHealthLabel.text = str(health) def moveByFloors(self, change): if self.currentFloor + change > 0: self.showFloor(self.currentFloor + change, lambda: self.interactAround()) def getCell(self, location, floor=None): if floor == None: return floors.floors[self.currentFloor][location.row][location.col] else: return floors.floors[floor][location.row][location.col] def setCell(self, cell, location, floor=None): if floor == None or floor == self.currentFloor: cell.initialize(self.cellDisplays[location.row][location.col]) floors.floors[self.currentFloor][location.row][location.col] = cell else: floors.floors[floor][location.row][location.col] = cell cell.placeAt(self.currentFloor if floor == None else floor, location) def interactBy(self, offset): self.hero.turnTo(offset) target = self.hero.location + offset if 0 <= target.row < GRID_DIM and 0 <= target.col < GRID_DIM: floors.floors[self.currentFloor][target.row][target.col].interact() self.saved = False def interactAround(self): for offset in (Point(r, c) for r, c in ((0, 1), (1, 0), (0, -1), (-1, 0))): target = self.hero.location + offset if 0 <= target.row < GRID_DIM and 0 <= target.col < GRID_DIM: floors.floors[self.currentFloor][target.row][ target.col].interactAround() def showDialog(self, text, hotkeys, custom=False): self.dialogHotkeys = hotkeys self.dialogCustom = custom if not custom: self.dialog.text = text self.root.add_widget(self.dialog) def handleDialog(self, key): if key in self.dialogHotkeys: action = self.dialogHotkeys[key] elif REF_KEY_ANY in self.dialogHotkeys: action = self.dialogHotkeys[REF_KEY_ANY] else: return if action(): if not self.dialogCustom: self.root.remove_widget(self.dialog) self.dialogHotkeys = None def showHandbook(self): self.handbook.show(floors.floors[self.currentFloor])
def __on_exit__(self, root_widget: Widget) -> None: root_widget.remove_widget(self.menu) self.menu.clear_widgets() self.menu.canvas.clear() self.rect = None
class gridNeuronsWidget(Widget): def __init__(self, *args, **kwargs): Widget.__init__(self, *args, **kwargs) Window.bind(mouse_pos=self.mouse_pos) self.bind(pos=self.draw) self.bind(size=self.draw) self.gridLayer = BoxLayout(opacity=1) self.neuronLayer = Widget(opacity=1) self.drawLayer = Widget(opacity=1) self.connectionsLayer = Widget(opacity=1) self.add_widget(self.gridLayer) self.add_widget(self.neuronLayer) self.add_widget(self.drawLayer) self.add_widget(self.connectionsLayer) self._gridSize = 5 self._neuronSize = 60 self.initNeurons() def addConnection(self): self.drawLayer.canvas.clear() if FROMNEURON != TARGETNEURON and TARGETNEURON != None: newCon = Connection(fromNeuron=FROMNEURON, targetNeuron=TARGETNEURON) CONNECTION_LIST.append(newCon) self.connectionsLayer.add_widget(newCon) def mouse_pos(self, window, pos): if CONNECT and DRAGGING: self.drawLine(pos) def initNeurons(self): for i in range(self._gridSize + 1): for ii in range(self._gridSize + 1): n = Neuron(size=[100, 100]) NEURON_LIST.append(n) self.neuronLayer.add_widget(n) def removeNeurons(self, *args, **kwargs): for neuron in NEURON_LIST: self.neuronLayer.remove_widget(neuron) NEURON_LIST.clear() def removeConnections(self, *args, **kwargs): for connection in CONNECTION_LIST: self.connectionsLayer.remove_widget(connection) CONNECTION_LIST.clear() def reInitGrid(self, *args, **kwargs): _gridSize = kwargs.get('_gridSize', self._gridSize) if (_gridSize): self._gridSize = _gridSize self.removeNeurons() self.initNeurons() self.removeConnections() self.draw() def clearConnection(self, *args, **kwargs): self.removeConnections() self.draw() def drawLine(self, mPos): self.drawLayer.canvas.clear() with self.drawLayer.canvas: Color(1, 1, 1, 1) Line(points=[DRAG_START[0], DRAG_START[1], mPos[0], mPos[1]], width=0.8) def draw(self, *args, **kwargs): # method vars : _gridSize = kwargs.get('_gridSize', self._gridSize) if (_gridSize): self._gridSize = _gridSize if float(math.log(self._gridSize)) > 0: self.neuronSize = 1 / float(math.log(self._gridSize)) * 46 else: self.neuronSize = 60 GRIDWIDTH = self.size[0] GRIDHEIGHT = self.size[1] offsetY = ((GRIDWIDTH - (GRIDHEIGHT - (XMARGIN + YMARGIN))) / 2) - YMARGIN STEP = (GRIDHEIGHT - (XMARGIN + YMARGIN)) / self._gridSize with self.canvas.before: Color(*BACKGROUND_COLOR) self.bg = Rectangle(pos=self.pos, size=self.size) # GRID: self.gridLayer.canvas.clear() with self.gridLayer.canvas: Color(*GRID_COLOR) for i in range(self._gridSize): Line(points=[ XMARGIN + offsetY, YMARGIN + (i * STEP), (GRIDHEIGHT - YMARGIN) + offsetY, XMARGIN + (i * STEP) ], width=1) Line(points=[ XMARGIN + (i * STEP) + offsetY, YMARGIN, YMARGIN + (i * STEP) + offsetY, GRIDHEIGHT - XMARGIN ], width=1) if i == (self._gridSize - 1): Line(points=[ XMARGIN + offsetY, YMARGIN + ((i + 1) * STEP), (GRIDHEIGHT - YMARGIN) + offsetY, XMARGIN + ((i + 1) * STEP) ], width=1) Line(points=[ XMARGIN + ((i + 1) * STEP) + offsetY, YMARGIN, YMARGIN + ((i + 1) * STEP) + offsetY, GRIDHEIGHT - XMARGIN ], width=1) # Update Neurons: nC = 0 for i in range(self._gridSize + 1): for ii in range(self._gridSize + 1): pos = (int(XMARGIN + (i * STEP) + offsetY - self.neuronSize / 2), int((YMARGIN) + (ii * STEP)) - self.neuronSize / 2) NEURON_LIST[nC].size = [self.neuronSize, self.neuronSize] NEURON_LIST[nC].pos = pos nC += 1 # Connections: # Draw order is important Grid->Neurons->Connections for connection in CONNECTION_LIST: connection.draw()
class ClientApp(App): def build(self): self.parent = Widget() self.sm = StartMenu() self.sm.buildUp() self.bm = BoardMenu() self.lm = LevelMenu() self.cl = CustomLevel() #Checking which button was pressed and acting accordinly on customlevel menu. def check_custlevel_button(obj): if self.cl.buttonText == 'Ok': self.de = CardDesk() self.de.set_bounds(self.cl.custom_row, self.cl.custom_column) self.de.buildUp() self.parent.remove_widget(self.cl) self.bm.buildUp() self.parent.add_widget(self.bm) self.parent.add_widget(self.de) print ' we should start the game now custom' if self.cl.buttonText == 'Cancel': self.parent.remove_widget(self.cl) self.parent.add_widget(self.sm) print 'Cancel' # Checking which button was pressed and acting accordinly on level menu. def check_level_button(obj): if self.lm.buttonText == 'Easy': self.parent.remove_widget(self.lm) self.de = CardDesk() self.de.set_bounds(3, 4) self.bm.buildUp() self.parent.add_widget(self.bm) self.de.buildUp() self.parent.add_widget(self.de) print ' we should start the game now easy' if self.lm.buttonText == 'Medium': self.parent.remove_widget(self.lm) self.de = CardDesk() self.de.set_bounds(4, 5) self.bm.buildUp() self.parent.add_widget(self.bm) self.de.buildUp() self.parent.add_widget(self.de) print ' we should start the game now medium' if self.lm.buttonText == 'Hard': self.parent.remove_widget(self.lm) self.de = CardDesk() self.de.set_bounds(5, 6) self.bm.buildUp() self.parent.add_widget(self.bm) self.de.buildUp() self.parent.add_widget(self.de) print ' we should start the game now hard' if self.lm.buttonText == 'Custom': self.parent.remove_widget(self.lm) self.parent.add_widget(self.cl) self.cl.buildUp() print ' we should start the game now custom' if self.lm.buttonText == 'Cancel': self.parent.remove_widget(self.lm) self.parent.add_widget(self.sm) print 'Cancel' # Checking which button was pressed and acting accordinly on board menu. def check_board_button(obj): # check to see which button was pressed if self.bm.buttonText == 'Exit': self.parent.remove_widget(self.bm) self.parent.remove_widget(self.de) self.parent.add_widget(self.sm) print ' Exit' # Checking which button was pressed and acting accordinly on start menu. def check_start_button(obj): # check to see which button was pressed if self.sm.buttonText == 'Start': self.parent.remove_widget(self.sm) self.parent.add_widget(self.lm) self.lm.buildUp() if self.sm.buttonText == 'Settings': self.parent.remove_widget(self.sm) print ' Score table' if self.sm.buttonText == 'Exit': self.parent.remove_widget(self.parent) App.get_running_app().stop() print ' Exit' #Event sending: self.sm.bind(on_button_release=check_start_button) self.lm.bind(on_button_release=check_level_button) self.cl.bind(on_button_release=check_custlevel_button) self.bm.bind(on_button_release=check_board_button) self.parent.add_widget(self.sm) return self.parent
class WidgetTestCase(unittest.TestCase): def setUp(self): from kivy.uix.widget import Widget self.cls = Widget self.root = Widget() def test_add_remove_widget(self): root = self.root self.assertEqual(root.children, []) c1 = self.cls() root.add_widget(c1) self.assertEqual(root.children, [c1]) root.remove_widget(c1) self.assertEqual(root.children, []) def test_invalid_add_widget(self): from kivy.uix.widget import WidgetException try: # None of them should work self.root.add_widget(None) self.root.add_widget(WidgetException) self.root.add_widget(self.cls) self.fail() except WidgetException: pass def test_position(self): wid = self.root wid.x = 50 self.assertEqual(wid.x, 50) self.assertEqual(wid.pos, [50, 0]) wid.y = 60 self.assertEqual(wid.y, 60) self.assertEqual(wid.pos, [50, 60]) wid.pos = (0, 0) self.assertEqual(wid.pos, [0, 0]) self.assertEqual(wid.x, 0) self.assertEqual(wid.y, 0) def test_size(self): wid = self.root wid.width = 50 self.assertEqual(wid.width, 50) self.assertEqual(wid.size, [50, 100]) wid.height = 60 self.assertEqual(wid.height, 60) self.assertEqual(wid.size, [50, 60]) wid.size = (100, 100) self.assertEqual(wid.size, [100, 100]) self.assertEqual(wid.width, 100) self.assertEqual(wid.height, 100) def test_collision(self): wid = self.root self.assertEqual(wid.pos, [0, 0]) self.assertEqual(wid.size, [100, 100]) self.assertEqual(wid.collide_point(-1, -1), False) self.assertEqual(wid.collide_point(0, 0), True) self.assertEqual(wid.collide_point(50, 50), True) self.assertEqual(wid.collide_point(100, 100), True) self.assertEqual(wid.collide_point(200, 0), False) self.assertEqual(wid.collide_point(500, 500), False) # Currently rejected with a Shader didn't link, but work alone. @unittest.skip("Doesn't work with testsuite, but work alone") def test_export_to_png(self): from kivy.core.image import Image as CoreImage from kivy.uix.button import Button from os.path import join wid = Button(text='test', size=(200, 100), size_hint=(None, None)) self.root.add_widget(wid) tmp = mkdtemp() wid.export_to_png(join(tmp, 'a.png')) wid.export_to_png(join(tmp, 'b.png'), scale=.5) wid.export_to_png(join(tmp, 'c.png'), scale=2) self.assertEqual(CoreImage(join(tmp, 'a.png')).size, (200, 100)) self.assertEqual(CoreImage(join(tmp, 'b.png')).size, (100, 50)) self.assertEqual(CoreImage(join(tmp, 'c.png')).size, (400, 200)) rmtree(tmp) self.root.remove_widget(wid)
def __on_exit__(self, root_widget: Widget) -> None: root_widget.remove_widget(self.layout)
class cWidgetScrollList(cWidgetPicture): """ WikiDoc:Doc WikiDoc:Context:Widgets WikiDoc:Page:Widgets-SCROLLLIST WikiDoc:TOCTitle:ScrollList = ScrollList = The scrolllist widget is a container widget to place lines of widget in a scrollable widget The scrolllist widget is based on the picture widget, please use the documentation for the common attributes To Identify the the source widget in actions triggered by widgets in the scroll list: The "SCROLLLISTVALUE" value is added to the action pars which refers to the widget text The "SCROLLLISTINDEX" index is added to the action pars which refers to the line order, eg: "0" is the first line in the list The "SCROLLLISTVARINDEX" index is added to the action pars which refers to the index number of the vararray The list of lines within the container is build from the vararry of minimum one widget within the line definition. So, one widget must have a caption with an array variable You can place all kind of widgets (with the exception of dropdowns in a row/line of the container All widgets got an index "[x]" added to the widget name, to manage them thought the actions The following attributes are additional attributes to common picture attributes <div style="overflow:auto; "> {| class="wikitable" ! align="left" | Attribute ! align="left" | Description |- |type |fixed: needs to be "SCROLLCONTAINER". Capital letters! |- |container |A string, which identifies the container AND all elements to place into the row of the container. If blank, a random value is used |- |rowheight |The rowheigth of a full line within the container: The line definition (all widgets in a line) must fir the this number |}</div> Below you see an example for a container definition <div style="overflow-x: auto;"><syntaxhighlight lang="xml"> <element name='Anchor1' type='ANCHOR' posx='%2' posy='%20' width='%30' height='%60' > <elements> <element name="ScrollBox Left" type="SCROLLLIST" picturenormal="background boxes" container="container_1" rowheight="%25" /> <element name='Anchor1 Inner' type='ANCHOR' height='%25' > <element name="First Button" type="BUTTON" posx="left" posy="top" height="%100" width="%40" picturenormal='button wide*' container="container_1" caption="First Button" action="Show Page" actionpars='{"pagename":"Page_Main"}' /> <element name="Second Button Top" type="BUTTON" posx="right" posy="top" height="%50" width="%60" picturenormal="button wide*" container="container_1" caption="$var(scrollcontent_button1_text[])" action="Show Page" actionpars='{"pagename":"Page_Main"}' /> <element name="Second Button Down" type="BUTTON" posx="right" posy="bottom" height="%50" width="%60" picturenormal="button wide*" container="container_1" caption="$var(scrollcontent_button2_text[])" action="Show Page" actionpars='{"pagename":"Page_Main"}' /> </element> </elements> </element> </syntaxhighlight></div> A second example with automated container assignment <div style="overflow-x: auto;"><syntaxhighlight lang="xml"> </syntaxhighlight></div> WikiDoc:End """ # noinspection PyUnusedLocal def __init__(self,**kwargs): super().__init__() self.oObjectContent:Union[FloatLayout,None] = None self.oObjectScroll:Union[ScrollView,None] = None self.uRowHeightInit:str = u'' self.iRowHeightScreen:int = 0 self.iRowHeight:int = 0 self.iNumRows:int = 0 self.aListChilds:List[cWidgetBase] = [] self.aChilds:List[cWidgetBase] = [] def InitWidgetFromXml(self,*,oXMLNode:Element,oParentScreenPage:cScreenPage, uAnchor:str) -> bool: """ Reads further Widget attributes from a xml node """ self.uRowHeightInit = GetXMLTextAttribute(oXMLNode=oXMLNode,uTag="rowheight",bMandatory=True,vDefault="%20") return super().InitWidgetFromXml(oXMLNode=oXMLNode,oParentScreenPage=oParentScreenPage ,uAnchor=uAnchor) def Create(self,oParent:Widget) -> bool: """ creates the Widget """ aChilds:List[cWidgetBase] aChilds:cWidgetBase aCaptions:List[str] self.iNumRows = 1 if super().Create(oParent): self.CreateScrollList() return True return False def GetChilds(self) -> List[cWidgetBase]: aRet:List[cWidgetBase] = [] # in case of recreation: Lets add the childs to the list of Screenpage widgets for oChild in self.aChilds: self.oParentScreenPage.RegisterWidget(oWidget=oChild) # and remove the from the local list del self.aChilds[:] # save a copy of the screenpage widgets locally and mark them for deletion for oWidget in self.oParentScreenPage.dWidgetsID.values(): if oWidget.uContainer==self.uContainer and oWidget!=self: aRet.append(oWidget) self.aChilds.append(copy(oWidget)) self.oParentScreenPage.aErrorWidgets.append(oWidget) return aRet def GetCaptions(self,aChilds:List[cWidgetBase]) -> List[List[Tuple[str,str]]]: aCaptions:List[List[Tuple[str,str]]] = [] aTmp:List[Tuple] tItem: Tuple aChildCaptions: List[Tuple[str, str]] for oChild in aChilds: aChildCaptions = [] if hasattr(oChild,'uOrgCaption'): if oChild.uOrgCaption.endswith("[])"): aTmp = Var_GetArrayEx(uVarName=oChild.uOrgCaption[5:-1], iLevel=1, bSort=False) for tItem in aTmp: aChildCaptions.append((u"$var(" + tItem[0] + ")",tItem[1])) self.iNumRows = max(self.iNumRows, len(aChildCaptions)) aCaptions.append(aChildCaptions) return aCaptions def CreateScrollList(self): aChilds:List[cWidgetBase] = self.GetChilds() aCaptions:List[List[Tuple[str,str]]] = self.GetCaptions(aChilds) self.iRowHeight = self.CalculateHeight(uHeight=self.uRowHeightInit, iAnchorHeight=self.iAnchorHeight) self.iRowHeightScreen = self.iRowHeight / self.oDef.fRationY self.oObjectScroll = ScrollView(size=self.oObject.size, pos=self.oObject.pos, do_scroll_x=False, scroll_type=['bars', 'content'], size_hint=(1, None), bar_width='10dp') self.oObjectContent = Widget(size=(self.oObject.width, self.iRowHeightScreen * self.iNumRows), size_hint=(1, None)) self.oObject.add_widget(self.oObjectScroll) self.oObjectScroll.add_widget(self.oObjectContent) self.CreateChilds(aChilds, aCaptions) def DeleteScrollList(self): self.DeleteChilds() self.oObjectScroll.remove_widget(self.oObjectContent) self.oObject.remove_widget(self.oObjectScroll) def CreateChilds(self,aChilds:List[cWidgetBase],aCaptions:List[List[Tuple[str,str]]]): iIndex:int iSubIndex: int yPos:int iAdd:int uVarIndex:str dTmpdActionPars:Dict = {} for u in range(self.iNumRows): iIndex = 0 uVarIndex = u'' # by purpose, we don't set it by child, we use the last known index, in case we have widgets without vars eg Buttons for oChild in aChilds: if hasattr(oChild,"dActionPars"): dTmpdActionPars = CopyDict(oChild.dActionPars) oTmpChild = copy(oChild) oTmpChild.uName = "%s[%s]" % (oTmpChild.uName, str(u)) oTmpChild.iHeightInit = self.iRowHeight * (oChild.iHeightInit/oChild.iAnchorHeight) oTmpChild.iPosXInit = oTmpChild.iPosXInit - self.iPosXInit oTmpChild.iGapY = (self.iPosY *-1) + (self.iRowHeightScreen * (u + 0)) if isinstance(oChild,cWidgetSwitch): if oTmpChild.uDestVar: oTmpChild.uDestVar=oTmpChild.uDestVar+"_"+str(u) if len(aCaptions[iIndex]) > u: if hasattr(oTmpChild,"uCaption"): oTmpChild.uOrgCaption = aCaptions[iIndex][u][0] oTmpChild.uCaption = ReplaceVars(aCaptions[iIndex][u][0]) uVarIndex = ReplaceVars(aCaptions[iIndex][u][1]) oTmpChild.Create(self.oObjectContent) if hasattr(oTmpChild,"dActionPars"): try: oTmpChild.dActionPars["SCROLLLISTVALUE"] = oTmpChild.oObject.text except: oTmpChild.dActionPars["SCROLLLISTVALUE"] = "" oTmpChild.dActionPars["SCROLLLISTINDEX"] = str(u) oTmpChild.dActionPars["SCROLLLISTVARINDEX"] = uVarIndex self.aListChilds.append(oTmpChild) self.oParentScreenPage.aAddWidgets.append(oTmpChild) oChild.dActionPars=dTmpdActionPars iIndex += 1 def DeleteChilds(self): for oChild in self.aListChilds: self.oObjectContent.remove_widget(oChild.oObject) oChild.oObject = None self.oParentScreenPage.RemoveWidget(oWidget=oChild) del self.aListChilds[:] self.iNumRows = 0 def UpdateWidget(self) -> None: super().UpdateWidget() if self.oObjectScroll is not None: self.DeleteScrollList() self.CreateScrollList() self.oParentScreenPage.PostHandleErrorWidgets() return def EnableWidget(self, *, bEnable:bool) -> bool: super(cWidgetScrollList, self).EnableWidget(bEnable=bEnable) if self.oObjectScroll: if bEnable: self.oObjectScroll.opacity=1 else: self.oObjectScroll.opacity=0 return self.bIsEnabled
class Bar(FloatLayout): objects = DictProperty( {} ) app = ObjectProperty(None) apps = DictProperty( {} ) element_size = ObjectProperty( (70,70) ) spacing = NumericProperty(10) sorting_condition = StringProperty( 'app_type' ) def __init__(self,**kwargs): super(Bar,self).__init__(**kwargs) self.apps = self.app.field.init_apps() self.size_hint = (None,1) #self.width = 135 self.padding_left = int((self.width - self.element_size[0])/2) self.geometry_squares = {} self.images = {} self.sorting = [] #self.scroll = ScrollView( size_hint = (None, None), width = 130, height = 1000 ) #self.add_widget(self.scroll) self.layout = Widget(size_hint = (None, None), width = 130, height = 2000 ) #size_hint=(None, None), width = 130, height = 1500) # size_hint = (1,1) )#self.add_widget(self.layout) self.add_widget(self.layout) self.draw_empty_squares() self.sort() self.fill() #self.resort('title') self.leave_app_button = SuperButton(background_normal = 'style/bar/slider-picto-type-off.png',background_down = 'style/bar/slider-picto-type-on.png', size = (30,30), pos_hint = (None,0.95), x = 0 ) self.leave_app_button.bind(on_press = self.app.appview.leave_current_app) def clear(self): for i in self.children : self.remove_widget(i) def sort(self): #list of app keys in order condition = self.sorting_condition self.sorting = self.apps.keys() if condition == 'title': l = [] for i,val in self.apps.iteritems(): t = val['title'] l.append( [t,i] ) elif condition == 'app_type': l = [] for i,val in self.apps.iteritems(): t = val['app_type'] l.append( [t,i] ) else : return l.sort() #print l sorting = [] counter =0 for i in l: if counter in [7,14,21,28]: #button sorting.append( 'b' ) sorting.append( i[1] ) counter +=1 self.sorting = sorting def resort(self,condition): self.sorting_condition = condition self.sort() #self.clear() #animate icons now gs = self.geometry_squares for key,val in gs.iteritems() : im_key = self.sorting[int(key)] if not im_key == 'b': #exception for buttons #get destination gs center = val.center a = Animation(center = center) im = self.images[ str(im_key) ] im.initial_center = center a.start( im ) #im.pos = center def fill(self): #print 'apps' #print self.apps gs = self.geometry_squares s = self.sorting counter = 0 for key,val in self.apps.iteritems() : #get destination gs g = gs[ str( s.index(key) ) ] center = g.center pos = g.pos self.add_app(key,val,center,pos) counter +=1 #add sorting buttons counter = 0 for key in s : if key == "b": self.add_button(counter) counter +=1 def add_button(self, place): pos = self.geometry_squares[str(place)].pos buttons = GridLayout(cols=2, row_force_default=True, row_default_height=self.element_size[1]*0.5, size = self.element_size, pos = pos, spacing = 3 ) but1 = SuperButton(background_normal = 'style/bar/slider-picto-type-off.png',background_down = 'style/bar/slider-picto-type-on.png') but1.bind(on_press = self.sort_by_app_type) but2 = Button(background_normal = 'style/bar/slider-picto-ABC-off.png',background_down = 'style/bar/slider-picto-ABC-on.png') but2.bind(on_press = self.sort_by_title) but3 = Button(background_normal = 'style/bar/slider-picto-90-off.png',background_down = 'style/bar/slider-picto-90-on.png') but3.bind(on_press = self.rotate_images) but4 = Button(background_normal = 'style/bar/slider-picto-preSet-off.png',background_down = 'style/bar/slider-picto-preSet-on.png') buttons.add_widget(but1) buttons.add_widget(but2) buttons.add_widget(but3) buttons.add_widget(but4) self.layout.add_widget(buttons) def sort_by_app_type(self,a): self.resort('app_type') def sort_by_title(self,a): self.resort('title') def rotate_images(self,a): for i,val in self.images.iteritems(): val.rotation = val.rotation + 90 def add_app(self, key, app, center, pos): # Nop. self.images[key] = BarImage( source= str(app["image_path"]) , app =self.app, bar=self, key=key, pos =pos, initial_center = center, size = self.element_size ) if key in self.app.field.squares.keys() : self.images[key].opacify() if self.app.field.geometry["vertical"] == "True": self.images[key].rotation += 270 self.layout.add_widget(self.images[key]) def draw_empty_squares(self): apps = self.apps m = self.spacing#self.app.field.style['geometry_square_margin'] padding_left = self.padding_left max = len(apps) #leave space for buttons r = max/7 max +=int(r) for i in xrange(0,max): self.geometry_squares[str(i)] = GeometrySquare( geometry_id = i, pos = (padding_left,m+(self.element_size[1]+m)*i), size = self.element_size, layout_type = "icon", do_scale = False, do_rotation = False, do_translation = False, auto_bring_to_front = False ) self.layout.add_widget( self.geometry_squares[str(i)] ) def put_on_field(self, key, touch): self.app.field.add_app(key, touch) def on_image_touch_down(self, touch, key): squares = self.app.field.squares if not key in squares.keys() : return if self.app.appview.position_left == False: if touch.is_double_tap : square = self.app.field.squares[key] square.launch(1) else : #check if already on field self.app.field.shake_square( touch,key,10) def show_leave_app_button(self): return self.layout.add_widget( self.leave_app_button ) def hide_leave_app_button(self): return self.layout.remove_widget( self.leave_app_button ) def opacify(self): squares = self.app.field.squares.keys() for key,item in self.images.iteritems() : if key in squares : item.opacify() def unopacify(self): for key,item in self.images.iteritems() : item.unopacify()
class WidgetTestCase(unittest.TestCase): def setUp(self): from kivy.uix.widget import Widget self.cls = Widget self.root = Widget() def test_add_remove_widget(self): root = self.root self.assertEqual(root.children, []) c1 = self.cls() root.add_widget(c1) self.assertEqual(root.children, [c1]) root.remove_widget(c1) self.assertEqual(root.children, []) def test_invalid_add_widget(self): from kivy.uix.widget import WidgetException try: # None of them should work self.root.add_widget(None) self.root.add_widget(WidgetException) self.root.add_widget(self.cls) self.fail() except WidgetException: pass def test_position(self): wid = self.root wid.x = 50 self.assertEqual(wid.x, 50) self.assertEqual(wid.pos, [50, 0]) wid.y = 60 self.assertEqual(wid.y, 60) self.assertEqual(wid.pos, [50, 60]) wid.pos = (0, 0) self.assertEqual(wid.pos, [0, 0]) self.assertEqual(wid.x, 0) self.assertEqual(wid.y, 0) def test_size(self): wid = self.root wid.width = 50 self.assertEqual(wid.width, 50) self.assertEqual(wid.size, [50, 100]) wid.height = 60 self.assertEqual(wid.height, 60) self.assertEqual(wid.size, [50, 60]) wid.size = (100, 100) self.assertEqual(wid.size, [100, 100]) self.assertEqual(wid.width, 100) self.assertEqual(wid.height, 100) def test_collision(self): wid = self.root self.assertEqual(wid.pos, [0, 0]) self.assertEqual(wid.size, [100, 100]) self.assertEqual(wid.collide_point(-1, -1), False) self.assertEqual(wid.collide_point(0, 0), True) self.assertEqual(wid.collide_point(50, 50), True) self.assertEqual(wid.collide_point(100, 100), True) self.assertEqual(wid.collide_point(200, 0), False) self.assertEqual(wid.collide_point(500, 500), False) def test_export_to_png(self): from kivy.core.image import Image as CoreImage from kivy.uix.button import Button from os.path import join wid = Button(text='test', size=(200, 100), size_hint=(None, None)) self.root.add_widget(wid) with TemporaryDirectory() as tmp: wid.export_to_png(join(tmp, 'a.png')) wid.export_to_png(join(tmp, 'b.png'), scale=.5) wid.export_to_png(join(tmp, 'c.png'), scale=2) CoreImage(join(tmp, 'a.png')).size == (200, 100) CoreImage(join(tmp, 'b.png')).size == (100, 50) CoreImage(join(tmp, 'c.png')).size == (400, 200) self.root.remove_widget(wid)
class CustomMenu(Widget): background='./imageAssets/sgegsgegsegs.jpg' preview_max_size=[Window.width*0.6,Window.height*0.6] preview_height=Window.height*0.35 #====== customizableNumber=len(ArtInfo.artist_names) #Must be at least 1 #============================================================ preview_min_space=Window.width*0.05 frame_t=0.01 animating_speed=1500 max_speed=5000 #Max speed at which stage selection widget moves. Should be larger than animating speed if max_speed<animating_speed: max_speed=animating_speed swipe_resistance=1.5 #The higher, the harder it is to shift the image. 1 is normal. Must be positive shift_speed=Window.width lock_opacity=0.8 lock_image='./imageAssets/locked.png' def __init__(self,Supreme_class,**kwargs): super(CustomMenu,self).__init__(**kwargs) self.supreme=Supreme_class def init1(self,dt): self.add_widget(cropFit(self.background,Window.width,Window.height,0,0)) self.preview=Widget() self.orix=[] ori_mid=Window.width*0.5 self.ori_mid=[ori_mid] if store.exists('custom0'): imageStr=store.get('custom0')['imageStr'] else: imageStr='./imageAssets/puzzles/1.jpg' #Change image format here try: preview=ratioFit(imageStr,self.preview_max_size[0],self.preview_max_size[1]) except: print('Image is missing!') path='./imageAssets/puzzles/1.jpg' #Change image format here store.put('custom0',imageStr=path) preview=ratioFit(path,self.preview_max_size[0],self.preview_max_size[1]) xPos=(Window.width-preview.get_size()[0])/2 self.orix.append(xPos) preview.setPos(xPos,self.preview_height) self.preview.add_widget(preview) self.preview_widget=[preview] self.space=self.preview_max_size[0]+self.preview_min_space xPos=(Window.width-self.preview_max_size[0])/2 self.index=0 #This instance will be used for different purpose later try: self.loading_increment=float(self.supreme.menu.loading_points[self.supreme.menu.loading_point_index+2]-\ self.supreme.menu.loading_points[self.supreme.menu.loading_point_index+1])/\ float(self.customizableNumber-1) Clock.schedule_once(partial(self.supreme.menu.update_progress,\ self.supreme.menu.loading_point(),partial(self.init2,ori_mid)),0) except: self.add_widget(self.preview) self.supreme.menu.loading_point() Clock.schedule_once(partial(self.supreme.menu.update_progress,\ self.supreme.menu.loading_point(),self.init3),0) def init2(self,ori_mid,dt): self.index+=1 ori_mid+=self.space self.ori_mid.append(ori_mid) tmpString='custom'+str(self.index) if store.exists(tmpString): imageStr=store.get(tmpString)['imageStr'] else: imageStr='./imageAssets/puzzles/'+str(self.index+1)+'.jpg' #Change image format here try: preview=ratioFit(imageStr,self.preview_max_size[0],self.preview_max_size[1]) except: print('Image is missing!') path='./imageAssets/puzzles/'+str(self.index+1)+'.jpg' #Change image format here store.put(tmpString,imageStr=path) preview=ratioFit(path,self.preview_max_size[0],self.preview_max_size[1]) xPos=ori_mid-float(preview.get_size()[0])/2. self.orix.append(xPos) preview.setPos(xPos,self.preview_height) self.preview.add_widget(preview) self.preview_widget.append(preview) if self.index==self.customizableNumber-1: self.add_widget(self.preview) Clock.schedule_once(partial(self.supreme.menu.update_progress,\ self.supreme.menu.loading_point(),self.init3),0) else: Clock.schedule_once(partial(self.supreme.menu.update_progress,\ self.supreme.menu.loading_points[self.supreme.menu.loading_point_index]+\ self.index*self.loading_increment,partial(self.init2,ori_mid)),0) def init3(self,dt): self.right_limit=Window.width-float(self.preview_widget[0].get_size()[0])/2. self.left_limit=-float(self.preview_widget[self.customizableNumber-1].get_size()[0])/2. self.preview_y_range=(self.preview_height,self.preview_height+self.preview_max_size[1]) self.preview_clicked=False self.mid_x=Window.width/2. self.index=0 self.animating=False self.postpone=[] self.selectedImageList=[] Clock.schedule_once(partial(self.supreme.menu.update_progress,\ self.supreme.menu.loading_point(),self.init4),0) def init4(self,dt): if not level.exists('level'): level.put('level',level=0) self.current_level=current_level=level.get('level')['level'] self.lock_preview_widget=[] self.lock_preview=Widget() for index in range(self.customizableNumber-1,level.get('level')['level'],-1): locking=cropFit(self.lock_image,self.preview_widget[index].get_size()[0],self.preview_widget[index].get_size()[1]) locking.opacity=self.lock_opacity self.lock_preview_widget.append(locking) self.lock_preview.add_widget(locking) Clock.schedule_once(partial(self.supreme.menu.update_progress, self.supreme.menu.loading_point(),self.init5),0) def init5(self,dt): self.add_widget(self.lock_preview) self.lock_screen_adjust() for index in range(0,self.customizableNumber): self.postpone.append(False) self.selectedImageList.append('') self.extra_move=0 Clock.schedule_once(partial(self.supreme.menu.update_progress,\ self.supreme.menu.loading_point(),self.init_last_stage),0) def init_last_stage(self,dt): self.supreme.last_stage() self.add_widget(self.buttons_generator()) Clock.schedule_once(partial(self.supreme.menu.update_progress, self.supreme.menu.loading_point(),self.supreme.supreme_chain_3),0) def clear_init_instances(self): #del self.supreme try: del self.loading_increment except: pass def buttons_generator(self): box=BoxLayout(orientation='vertical') box.size=(Window.width,self.preview_height) box.pos=(0,0) box.spacing=self.preview_height*0.02 box.padding=[Window.width*0.2,self.preview_height*0.05,Window.width*0.2,self.preview_height*0.05] btn=Button(text='Stage Select') btn.bind(on_release=self.stage_select_btn) box.add_widget(btn) btn=Button(text='Customize') btn.bind(on_release=self.customize_btn) box.add_widget(btn) btn=Button(text='Return to menu') btn.bind(on_release=self.return_to_menu_btn) box.add_widget(btn) return box def stage_select_btn(self,instance): #============================================================================================================================================= #============================================================================================================================================= if JsonStore('levelCacche.json').get('level')['level']<self.index: try: self.locked_pop.open() except: self.locked_pop=self.locked_pop_up() self.locked_pop.open() return self.supreme.customSaveStr='custom'+str(self.index) if self.postpone[self.index]: self.postpone[self.index]=False try: saved=JsonStore('puzzledCacche.json').get(self.supreme.customSaveStr) self.supreme.customGameList[self.index]=CustomGameOn(self.selectedImageList[self.index], self.index,1, ArtInfo.splitter[self.index][0], ArtInfo.splitter[self.index][1], saved['arrangement'],saved['blank']) except: self.supreme.customGameList[self.index]=CustomGameOn(self.selectedImageList[self.index], self.index,1, ArtInfo.splitter[self.index][0], ArtInfo.splitter[self.index][1]) JsonStore('puzzledCacche.json').put(self.supreme.customSaveStr,arrangement=self.supreme.customGameList[self.index].puzzle.tiles, blank=self.supreme.customGameList[self.index].puzzle.blank) elif self.supreme.customGameList[self.index]==None: if JsonStore('puzzledCacche.json').exists(self.supreme.customSaveStr): saved=JsonStore('puzzledCacche.json').get(self.supreme.customSaveStr) self.supreme.customGameList[self.index]=CustomGameOn(JsonStore('imageCacche.json').get(self.supreme.customSaveStr)['imageStr'], self.index,1, ArtInfo.splitter[self.index][0], ArtInfo.splitter[self.index][1], saved['arrangement'],saved['blank']) elif JsonStore('imageCacche.json').exists(self.supreme.customSaveStr): image=JsonStore('imageCacche.json').get(self.supreme.customSaveStr)['imageStr'] self.supreme.customGameList[self.index]=CustomGameOn(image,self.index,1, ArtInfo.splitter[self.index][0], ArtInfo.splitter[self.index][1]) else: image_str='./imageAssets/puzzles/'+str(self.index+1)+'.jpg' #Change image format here self.supreme.customGameList[self.index]=CustomGameOn(image_str,self.index,1, ArtInfo.splitter[self.index][0], ArtInfo.splitter[self.index][1]) if not JsonStore('imageCacche.json').exists(self.supreme.customSaveStr): JsonStore('imageCacche.json').put(self.supreme.customSaveStr,imageStr=image_str) self.supreme.screen='custom puzzle' self.supreme.clear_widgets() self.supreme.add_widget(self.supreme.customGameList[self.index]) if JsonStore('stageCacche.json').get('current_stage')['stage']!=self.index: if platform=='android': if not JsonStore('adCacche.json').exists('ad_count'): JsonStore('adCacche.json').put('ad_count',ad_count=0) #THE FOLLOWING IN NOT NECESSARY IF THE GAME IS INITIALZED IN THIS TURN self.supreme.customGameList[self.index].ad_count=JsonStore('adCacche.json').get('ad_count')['ad_count'] JsonStore('stageCacche.json').put('current_stage',stage=self.index) #============================================================================================================================================= #============================================================================================================================================= def customize_btn(self,instance): if JsonStore('levelCacche.json').get('level')['level']<self.index: try: self.locked_pop.open() except: self.locked_pop=self.locked_pop_up() self.locked_pop.open() else: from kivy.app import App #MAYBE IT CAN BE BETTER THE OTHER WAY? App.get_running_app().show_file_options() def return_to_menu_btn(self,instance): self.supreme.remove_widget(self) self.supreme.add_widget(self.supreme.menu) self.supreme.screen='menu' def handle_on_touch_move(self,x): if self.preview_clicked: displacement=x-self.touch_down current_x1=self.orix[0]+displacement if current_x1>=self.right_limit: return current_x=self.orix[self.customizableNumber-1]+displacement if current_x<=self.left_limit: return self.preview_widget[0].setPos(current_x1+self.extra_move,self.preview_height) self.preview_widget[self.customizableNumber-1].setPos(current_x+self.extra_move,self.preview_height) for index in range(1,self.customizableNumber-1): self.preview_widget[index].setPos(self.orix[index]+displacement+self.extra_move,self.preview_height) #= #= self.x_previous=self.x_current self.x_current=x self.t_previous=self.t_current self.t_current=time.time() #= self.lock_screen_adjust() def handle_on_touch_down(self,x,y): if y>=self.preview_y_range[0] and y<=self.preview_y_range[1]: if self.animating: Clock.unschedule(self.animate) self.animating=False self.extra_move=self.preview_widget[0].pos[0]-self.orix[0] #return elif self.extra_move!=0: self.extra_move=0 self.preview_clicked=True self.touch_down=x self.x_previous=x self.x_current=x self.t_current=time.time() def handle_on_touch_up(self,x): if self.preview_clicked: self.preview_clicked=False print('moving now') #= displacement=self.x_current-self.x_previous print(displacement) print('extra move='+str(self.extra_move)) print('displacement='+str(displacement)) if displacement==0.: if self.extra_move==0: return print('where at') time_difference=self.t_current-self.t_previous if time_difference!=0: self.velocity=displacement/(self.t_current-self.t_previous) else: if displacement>0: self.velocity=self.max_speed elif displacement<0: self.velocity=-self.max_speed elif displacement==0: self.velocity=0 if abs(self.velocity)>self.max_speed: if self.velocity>0: self.velocity=self.max_speed else: self.velocity=-self.max_speed displacement2=x-self.touch_down+self.extra_move proximity=abs(displacement2+self.ori_mid[0]-self.mid_x) self.index=0 for index in range(1,self.customizableNumber): compare=abs(displacement2+self.ori_mid[index]-self.mid_x) if compare>proximity: break else: proximity=compare self.index=index if self.velocity>self.shift_speed and self.index>0: shift_count=int((self.velocity/self.shift_speed)/self.swipe_resistance) if self.index<shift_count: shift_count=self.index self.index-=shift_count elif self.velocity<-self.shift_speed and self.index<self.customizableNumber-1: shift_count=int((-self.velocity/self.shift_speed)/self.swipe_resistance) shift_max=self.customizableNumber-self.index-1 if shift_max<shift_count: shift_count=shift_max self.index+=shift_count for index in range(0,self.customizableNumber): self.ori_mid[index]=(index-self.index)*self.space+self.mid_x xPos=self.ori_mid[index]-self.preview_widget[index].get_size()[0]/2. self.orix[index]=xPos if not self.animating: z1=xPos-self.preview_widget[index].pos[0] if z1<0: self.multiplier=-1 elif z1>0: self.multiplier=1 elif z1==0: return print('checke') indicator=self.multiplier*self.velocity if abs(self.velocity)>self.animating_speed and indicator>0: self.impose_accel=True self.stepped=0 self.accel=(self.animating_speed**2-self.velocity**2)/((self.orix[0]-self.preview_widget[0].pos[0])*2) else: self.impose_accel=False if not self.animating: Clock.schedule_interval(self.animate,self.frame_t) self.animating=True self.start=time.time() self.lock_screen_adjust() def animate(self,dt): if self.impose_accel==False: current_time=time.time() distance=self.multiplier*self.animating_speed*(current_time-self.start) self.start=current_time #Placement will result in 1 extraneous move, but time will be more accurate else: t=time.time()-self.start distance=self.velocity*t+0.5*self.accel*(t**2.)-self.stepped if distance*self.velocity>0: self.stepped+=distance else: #If widget movement reverses direction due to accel, then we have to fix it print('WARNING: distance is reversing direction!') self.impose_accel=False distance=self.multiplier*self.animating_speed*self.frame_t self.start=time.time() self.preview_widget[0].setPos(self.preview_widget[0].pos[0]+distance,self.preview_height) if (self.multiplier==1 and self.preview_widget[0].pos[0]>=self.orix[0]) or (self.multiplier==-1 and self.preview_widget[0].pos[0]<=self.orix[0]): Clock.unschedule(self.animate) self.animating=False for index in range(0,self.customizableNumber): self.preview_widget[index].setPos(self.orix[index],self.preview_height) else: for index in range(1,self.customizableNumber): self.preview_widget[index].setPos(self.preview_widget[index].pos[0]+distance,self.preview_height) self.lock_screen_adjust() def stage_readjust(self,stage): half_window=Window.width*0.5 for index in range(0,len(self.preview_widget)): current_mid=(index-stage)*self.space+half_window self.ori_mid[index]=current_mid half_width=self.preview_widget[index].get_size()[0]*0.5 xPos=current_mid-half_width self.orix[index]=xPos self.preview_widget[index].setPos(xPos,self.preview_height) self.lock_screen_adjust() def lock_screen_adjust(self): incrementing_index=-1 for index in range(self.customizableNumber-1,self.customizableNumber-len(self.lock_preview_widget)-1,-1): incrementing_index+=1 self.lock_preview_widget[incrementing_index].setPos(self.preview_widget[index].x,self.preview_widget[index].y) def update_level(self): if self.current_level<JsonStore('levelCacche.json').get('level')['level']: self.current_level+=1 self.level_up() def level_up(self): if self.customizableNumber-1==self.index: return current_lv=level.get('level')['level'] level.put('level',level=current_lv+1) index=len(self.lock_preview_widget)-1 to_be_removed=self.lock_preview_widget[index] self.lock_preview.remove_widget(to_be_removed) self.lock_preview_widget.remove(to_be_removed) print('LEVELING UP!!!') def _customize(self,path): self.selectedImageList[self.index]=path self.postpone[self.index]=True string='custom'+str(self.index) store.put(string,imageStr=path) self.preview.remove_widget(self.preview_widget[self.index]) tmpWidget=ratioFit(path,self.preview_max_size[0],self.preview_max_size[1]) tmpWidget.setPos(self.mid_x-tmpWidget.get_size()[0]/2.,self.preview_height) self.orix[self.index]=tmpWidget.pos[0] self.ori_mid[self.index]=self.mid_x self.preview.add_widget(tmpWidget) self.preview_widget[self.index]=tmpWidget def locked_pop_up(self): #A LOT OF LITERAL from kivy.uix.label import Label myBox=BoxLayout() myBox.orientation='vertical' myLabel=Label() myLabel.text='Clear previous stage\nto unlock this level' myLabel.valign='middle' myLabel.halign='center' button=Button() button.text='Dismiss' button.size_hint_y=0.3 myBox.add_widget(myLabel) myBox.add_widget(button) popUp=Popup() popUp.title='Level locked' popUp.content=myBox popUp.size_hint=(0.7,0.5) button.bind(on_release=popUp.dismiss) return popUp
class ClientApp(App): def build(self): self.child = Supreme() self.parent = Widget() self.parent.add_widget(self.child) return self.parent def show_file_options(self): self.parent.remove_widget(self.child) self.child.screen = 'selection' try: self.parent.add_widget(self.selection_screen) except: from customizeArt import CustomizeArt self.selection_screen = CustomizeArt(self) self.parent.add_widget(self.selection_screen) def make_selection(self, path): if path == './imageAssets/puzzles/': path = path + str(self.child.customMenu.index + 1) + '.jpg' try: self.child.customMenu._customize(path) self.turn_off_selection() except: self.selection_screen.default_display() self.selection_screen.invalid_selection() def turn_off_selection(self): self.parent.remove_widget(self.selection_screen) self.parent.add_widget(self.child) self.child.screen = 'custom menu' def on_start(self): #PERHAPS THIS CAN BE PLACED UP ABOVE SIMPLY print('my platfooooooooooorm is ' + str(platform)) if displayAd: pass AdBuddiz.setPublisherKey("TEST_PUBLISHER_KEY") if platform == 'android': import android android.map_key(android.KEYCODE_BACK, 1000) android.map_key(android.KEYCODE_MENU, 1001) win = self._app_window win.bind(on_keyboard=self._key_handler) def on_pause(self): # Here you can save data if needed return True def on_resume(self): # Here you can check if any data needs replacing (usually nothing) pass def _key_handler(self, *args): key = args[1] print(key) # 1000 is "back" on Android # 27 is "escape" on computers # 1001 is "menu" on Android if key in (1000, 27): #OBVIOUSLY,WHATEVER NEEDS TO BE DONE HERE if self.child.screen == 'menu': print('exit here') self.child.menu.exit_popUp.open() elif self.child.screen == 'custom menu': self.child.clear_widgets() self.child.add_widget(self.child.menu) self.child.screen = 'menu' elif self.child.screen == 'custom puzzle': self.child.clear_widgets() self.child.add_widget(self.child.customMenu) self.child.customMenu.update_level( ) #MUST BE CALLED EVERYTIME CUSTOM MENU IS TURNED ON self.child.screen = 'custom menu' #-=- if self.child.customGameList[ self.child.customMenu.index].timer_activate: self.child.customGameList[ self.child.customMenu. index].timer_activate = 'disrupted' self.child.customGameList[ self.child.customMenu.index].stop_timer() return True elif key == 1001 or key == 49: return True