From 493b2c5dba1e3bda872e836f89dbd05cfe0539d8 Mon Sep 17 00:00:00 2001 From: Jamie Boisture Date: Mon, 08 Jun 2009 15:41:44 +0000 Subject: This is the initial commit to the Logic Circuits Activity --- diff --git a/LogicCircuitsActivity.py b/LogicCircuitsActivity.py new file mode 100755 index 0000000..93c2a11 --- /dev/null +++ b/LogicCircuitsActivity.py @@ -0,0 +1,804 @@ +#!/usr/bin/env python + +# example helloworld.py +from sugar.activity import activity +import pygtk +pygtk.require('2.0') +import gtk +import os +import time +import rsvg +import cairo + +class LogicCircuitsActivity(activity.Activity): + + def __init__(self,handle): + activity.Activity.__init__(self,handle) + self.set_title('Logic Circuits Activity') + #begin the program + self.build_GUI() + + + self.graphics = graphicsDriver() + self.mouse_move = 0 + self.clicked = 0 + self.buffer = gtk.gdk.Pixmap(self.draw_area.window, 3*self.X/4, self.Y) + self.gc = gtk.gdk.GC(self.buffer) + gtk.main() + + def delete_event(self, widget, event, data=None): + print "delete event occurred" + return False + + def destroy(self, widget, data=None): + print "destroy signal occurred" + gtk.main_quit() + + def set_placement(self, widget, data=None): + self.LightButton.set_relief(gtk.RELIEF_NORMAL) + self.AndButton.set_relief(gtk.RELIEF_NORMAL) + self.NotButton.set_relief(gtk.RELIEF_NORMAL) + self.OrButton.set_relief(gtk.RELIEF_NORMAL) + self.XorButton.set_relief(gtk.RELIEF_NORMAL) + widget.set_relief(gtk.RELIEF_NONE) + self.graphics.changeDrawingType(widget.get_label()) + + def set_connection(self, widget, data=None): + self.input_button.set_relief(gtk.RELIEF_NORMAL) + self.output_button.set_relief(gtk.RELIEF_NORMAL) + widget.set_relief(gtk.RELIEF_NONE) + self.graphics.changeConnectionType(widget.get_label()) + + + def expose(self, widget, event): + self.update() + + + def update(self,pos=(0,0)): + #update the screen + self.context = self.buffer.cairo_create() + self.context.rectangle(0, 0, + *self.draw_area.window.get_size()) + self.context.clip() + self.context.set_source_rgb(1, 1, 1) + self.context.rectangle(0, 0, *self.draw_area.window.get_size()) + self.context.fill() + self.context.set_source_rgb(0, 0, 0) + self.graphics.update(self.context,pos) + self.draw_area.window.draw_drawable(self.gc,self.buffer,0,0,0,0,-1,-1,) + + + def build_GUI(self): + #build the GUI + size= self.get_frame_dimensions() + self.X = self.window.get_screen().get_width() + self.Y = self.window.get_screen().get_height() + global X,Y + X = self.X + Y = self.Y + + self.table = gtk.Table(4,3,False) + self.table.show() + + self.draw_area = gtk.DrawingArea() + self.v = gtk.VPaned() + self.table.attach(self.v,0,3,0,3) + self.v.show() + self.v.add1(self.draw_area) + self.draw_area.set_size_request(3*self.X/4, self.Y) + self.draw_area.show() + self.draw_area.set_events(gtk.gdk.POINTER_MOTION_MASK | + gtk.gdk.BUTTON_PRESS_MASK | + gtk.gdk.KEY_PRESS_MASK | + gtk.gdk.BUTTON_RELEASE_MASK | + gtk.gdk.POINTER_MOTION_HINT_MASK ) + self.draw_area.connect("motion_notify_event", self.mouse_move) + self.draw_area.connect('button-press-event', self.mouse_press) + self.draw_area.connect('button-release-event', self.mouse_release) + self.draw_area.connect("expose_event", self.expose) + self.filechooser = gtk.FileChooserWidget(gtk.FILE_CHOOSER_ACTION_OPEN) + self.v.add2(self.filechooser) + self.filechooser.set_size_request(3*self.X/4, self.Y) + self.filechooser.connect("file-activated",self.fileChoosen) + self.filechooser.set_current_folder("saves") + self.filter = gtk.FileFilter() + self.filter.set_name("txt files") + self.filter.add_pattern("*.lc") + + self.filechooser.add_filter(self.filter) + + + + + self.Frame1 = gtk.Frame("Select an Object to Place") + self.table.attach(self.Frame1,3,4,0,1) + self.Frame1.set_size_request(self.X/4,self.Y/2) + self.Frame1.show() + + self.Frame2 = gtk.Frame("Select a Connection Type") + self.table.attach(self.Frame2,3,4,1,2) + self.Frame2.set_size_request(self.X/4,self.Y/4) + self.Frame2.show() + + self.Frame3 = gtk.Frame("Save and Load") + self.table.attach(self.Frame3,3,4,2,3) + self.Frame3.set_size_request(self.X/4,self.Y/4) + self.Frame3.show() + + self.save_table = gtk.Table(2, 3, False) + self.Frame3.add(self.save_table) + self.save_table.show() + + self.filename = gtk.Label("File Name:") + self.save_table.attach(self.filename,0,1,0,1) + self.filename.show() + + self.file_text = gtk.Entry(15) + self.save_table.attach(self.file_text,1,2,0,1) + self.file_text.show() + + self.SaveButton = gtk.Button(stock = gtk.STOCK_SAVE) + self.save_table.attach(self.SaveButton,0,2,1,2) + self.SaveButton.show() + self.SaveButton.connect("clicked", self.saveFile, None) + + self.OpenButton = gtk.Button(stock = gtk.STOCK_OPEN) + self.save_table.attach(self.OpenButton,0,2,2,3) + + self.OpenButton.show() + self.OpenButton.connect("clicked", self.loadFile, None) + + and_image = gtk.image_new_from_pixbuf(rsvg.Handle("data/AND.svg").get_pixbuf()) + not_image = gtk.image_new_from_pixbuf(rsvg.Handle("data/NOT.svg").get_pixbuf()) + or_image = gtk.image_new_from_pixbuf(rsvg.Handle("data/OR.svg").get_pixbuf()) + xor_image = gtk.image_new_from_pixbuf(rsvg.Handle("data/XOR.svg").get_pixbuf()) + light_image = gtk.image_new_from_pixbuf(rsvg.Handle("data/redlight.svg").get_pixbuf()) + + self.object_table = gtk.Table(1, 6, False) + self.Frame1.add(self.object_table) + self.object_table.show() + + self.LightButton = gtk.Button("Light") + self.AndButton = gtk.Button("And") + self.NotButton = gtk.Button("Not") + self.OrButton = gtk.Button("Or") + self.XorButton = gtk.Button("Xor") + + self.LightButton.connect("clicked", self.set_placement, None) + self.AndButton.connect("clicked", self.set_placement, None) + self.NotButton.connect("clicked", self.set_placement, None) + self.OrButton.connect("clicked", self.set_placement, None) + self.XorButton.connect("clicked", self.set_placement, None) + + self.LightButton.set_relief(gtk.RELIEF_NONE) + + self.AndButton.set_image(and_image) + self.NotButton.set_image(not_image) + self.OrButton.set_image(or_image) + self.XorButton.set_image(xor_image) + self.LightButton.set_image(light_image) + + + + self.object_table.attach(self.LightButton,0,1,1,2) + self.object_table.attach(self.AndButton,0,1,2,3) + self.object_table.attach(self.NotButton,0,1,3,4) + self.object_table.attach(self.OrButton,0,1,4,5) + self.object_table.attach(self.XorButton,0,1,5,6) + + self.LightButton.show() + self.AndButton.show() + self.NotButton.show() + self.OrButton.show() + self.XorButton.show() + + self.connection_table = gtk.Table(1,2,False) + self.Frame2.add(self.connection_table) + self.connection_table.show() + self.input_button = gtk.Button("Input") + self.output_button = gtk.Button("Output") + self.input_button.connect("clicked", self.set_connection, None) + self.output_button.connect("clicked", self.set_connection, None) + self.connection_table.attach(self.input_button,0,1,0,1) + self.connection_table.attach(self.output_button,0,1,1,2) + self.input_button.set_relief(gtk.RELIEF_NONE) + self.input_button.show() + self.output_button.show() + self.set_canvas(self.table) + self.show() + + def mouse_press(self, widget, event): + if self.clicked + .1 < time.time(): + if event.button == 1: self.graphics.button1((event.x,event.y)) + if event.button == 2: self.graphics.button2((event.x,event.y)) + if event.button == 3: self.graphics.button3((event.x,event.y)) + self.update((event.x,event.y)) + self.clicked=time.time() + + + def mouse_release(self, widget, event): + if event.button == 1: + if self.graphics.pressed != None: + self.graphics.pressed.clicked = False + self.graphics.pressed = None + + def mouse_move(self, widget, event): + if self.mouse_move == 1: + if self.graphics.pressed != None: + self.graphics.pressed.move((event.x,event.y)) + self.update((event.x,event.y)) + self.mouse_move = 0 + self.mouse_move += 1 + self.mousePositions = (event.x,event.y) + + def saveFile(self, widget, event): + text = self.file_text.get_text() + save(text) + + def loadFile(self, widget, event): + self.draw_area.hide() + self.filechooser.show() + + def fileChoosen(self, widget): + filename = widget.get_filename() + load(filename) + self.draw_area.show() + self.filechooser.hide() + + + + + +class Light: + + def __init__(self, position): + self.color = "red" + self.svg = rsvg.Handle("data/" +self.color+"light.svg") + self.pos = position + self.mousePos = (0,0) + self.clicked = False + + def change_color(self): + if self.color == "red": + self.color = "green" + elif self.color == "green": + self.color = "red" + self.update_image() + calculate() + + + def set_color(self, color): + if color == "red": + self.color = "red" + elif color == "green": + self.color = "green" + + def is_clicked(self, pos): + self.mousePos = pos + self.clicked = True + + def get(self): + if self.color == "red": + return 0 + return 1 + + def move(self, pos): + x = pos[0]-self.pos[0] + y = pos[1]-self.pos[1] + if int(x + self.pos[0]) in range(0,3*X/4): x = x + self.pos[0] + else: x = self.pos[0] + if int(y + self.pos[1]) in range(0,Y): y = y + self.pos[1] + else: y = self.pos[1] + self.pos = (x,y) + #self.mousePos = pos + for i in connections: i.update() + + + def update_image(self): + self.svg = rsvg.Handle("data/" +self.color+"light.svg") + + def draw(self, context): + context.translate(self.pos[0]-self.svg.props.width/2, self.pos[1]-self.svg.props.height/2) + self.svg.render_cairo(context) + context.translate(-1*(self.pos[0]-self.svg.props.width/2), -1*(self.pos[1]-self.svg.props.height/2)) + + + +class Circuit: + + def __init__(self, pos, max_inputs, text,input_pos, output_pos): + self.input_positions = input_pos + self.output_positions = output_pos + self.svg = rsvg.Handle("data/" +text+".svg") + self.text = text + self.pos = pos + self.inputs = [] + self.outputs = [] + self.max_inputs = max_inputs + self.clicked = False + self.mousePos = (0,0) + + def add_input(self, input_object): + if len(self.inputs) > 0 and self.inputs[0].pos[1] > input_object.pos[1]: + self.inputs = [input_object,self.inputs[0]] + else: self.inputs.append(input_object) + + def is_clicked(self, pos): + self.mousePos = pos + self.clicked = True + + def add_output(self, output_object): + self.outputs.append(output_object) + if output_object in pressing_lights: + non_pressing_lights.append(output_object) + pressing_lights.remove(output_object) + + def draw(self, context): + i = 0 + context.translate(self.pos[0]-self.svg.props.width/2, self.pos[1]-self.svg.props.height/2) + self.svg.render_cairo(context) + context.translate(-1*(self.pos[0]-self.svg.props.width/2), -1*(self.pos[1]-self.svg.props.height/2)) + context.set_source_rgb(1,0,0) + while i < len(self.inputs): + context.move_to(self.pos[0]+self.input_positions[i][0],self.pos[1]+self.input_positions[i][1]) + context.line_to(*self.inputs[i].pos) + context.stroke() + i += 1 + context.set_source_rgb(0,0,1) + for i in self.outputs: + context.move_to(self.pos[0]+self.output_positions[0],self.pos[1]+self.output_positions[1]) + context.line_to(*i.pos) + context.stroke() + + def move(self, pos): + x = pos[0]-self.mousePos[0] + y = pos[1]-self.mousePos[1] + mpx = pos[0] + mpy = pos[1] + if int(x + self.pos[0]) in range(0,3*X/4): x = x + self.pos[0] + else: + x = self.pos[0] + mpx = self.mousePos[0] + if int(y + self.pos[1]) in range(0,Y): y = y + self.pos[1] + else: + y = self.pos[1] + mpy = self.mousePos[1] + self.pos = (x,y) + self.mousePos = (mpx,mpy) + for i in connections: i.update() + + def calculate(self): + pass + + +class Not(Circuit): + + def __init__(self, pos): + Circuit.__init__(self, pos, 1, "NOT",[(-45,0)],(45,0)) + self.name = "not" + + def calculate(self): + if not self.inputs[0].get(): + self.outputs[0].set_color("green") + else: + self.outputs[0].set_color("red") + + +class And(Circuit): + + def __init__(self, pos): + Circuit.__init__(self, pos, 2, "AND", [(-45,-10),(-45,10)],(45,0)) + self.name = "and" + + def calculate(self): + if self.inputs[0].get() and self.inputs[1].get(): + self.outputs[0].set_color("green") + else: + self.outputs[0].set_color("red") + + +class Or(Circuit): + + def __init__(self, pos): + Circuit.__init__(self, pos, 2, "OR", [(-45,-10),(-45,10)],(45,0)) + self.name = "or" + + def calculate(self): + if self.inputs[0].get() or self.inputs[1].get(): + self.outputs[0].set_color("green") + else: + self.outputs[0].set_color("red") + + +class Xor(Circuit): + + def __init__(self, pos): + Circuit.__init__(self, pos, 2, "XOR", [(-45,-10),(-45,10)],(45,0)) + self.name = "xor" + + def calculate(self): + if not self.inputs[0].get() == self.inputs[1].get(): + self.outputs[0].set_color("green") + else: + self.outputs[0].set_color("red") + +class connection: + def __init__(self, circuit, light): + self.light = light + self.circuit = circuit + x1 = light.pos[0] + y1 = light.pos[1] + if self.light in self.circuit.inputs: + i = self.circuit.inputs.index(self.light) + x2 = self.circuit.pos[0]+self.circuit.input_positions[i][0] + y2 = self.circuit.pos[1]+self.circuit.input_positions[i][1] + else: + x2 = self.circuit.pos[0]+self.circuit.output_positions[0] + y2 = self.circuit.pos[1]+self.circuit.output_positions[1] + if x1-x2 == 0: + self.slope = 0 + elif x1x2: + self.range = (x2,x1) + self.slope = 1.0*(y2-y1)/(x2-x1) + self.intercept = y1 - self.slope*x1 + calculate() + + def update(self): + x1 = self.light.pos[0] + y1 = self.light.pos[1] + if self.light in self.circuit.inputs: + i = self.circuit.inputs.index(self.light) + x2 = self.circuit.pos[0]+self.circuit.input_positions[i][0] + y2 = self.circuit.pos[1]+self.circuit.input_positions[i][1] + else: + x2 = self.circuit.pos[0]+self.circuit.output_positions[0] + y2 = self.circuit.pos[1]+self.circuit.output_positions[1] + if x1-x2 == 0: + self.slope = 0 + elif x1x2: + self.range = (x2,x1) + self.slope = 1.0*(y2-y1)/(x2-x1) + self.intercept = y1 - self.slope*x1 + + + def in_range(self,x): + if x > self.range[0] and x < self.range[1]: + return True + return False + + def get_error(self, (x, y)): + return self.intercept + self.slope*x - y + + def destroy(self): + if self.light in self.circuit.inputs: + del self.circuit.inputs[self.circuit.inputs.index(self.light)] + elif self.light in self.circuit.outputs: + del self.circuit.outputs[self.circuit.outputs.index(self.light)] + del connections[connections.index(self)] + + + +def add_circuit(pos, string): + if string.lower() == "not": + circuits.append(Not(pos)) + if string.lower() == "or": + circuits.append(Or(pos)) + if string.lower() == "and": + circuits.append(And(pos)) + if string.lower() == "xor": + circuits.append(Xor(pos)) + + + +def is_over(pos, item): + if item.pos[0]-item.svg.props.width/2 < pos[0] < item.pos[0]+item.svg.props.width/2 and \ + item.pos[1]-item.svg.props.height/2 < pos[1] < item.pos[1]+item.svg.props.height/2: + return True + return False + +def connect(light, circuit): + if input_or_output == "Output": + if not circuit.outputs and light not in circuit.inputs: + connected = False + for i in circuits: + if light in i.outputs: connected = True + if not connected: + circuit.add_output(light) + connections.append(connection(circuit,light)) + elif input_or_output == "Input": + if len(circuit.inputs) != circuit.max_inputs \ + and light not in circuit.inputs and light not in circuit.outputs: + circuit.add_input(light) + connections.append(connection(circuit,light)) + + +def calculate(): + for item in xrange(55): + for i in circuits: + if i.outputs and len(i.inputs) == i.max_inputs: + i.calculate() + for i in circuits: + for item in i.outputs: + item.update_image() + + +class graphicsDriver: + def __init__(self, input_size=(900,900)): + global pressing_lights, non_pressing_lights, clock, size + global circuits, drawing, font, input_or_output, connections + size = input_size + connections = [] + pressing_lights = [] + non_pressing_lights = [] + pos = 10 + circuits = [] + drawing = "Light" + self.selected = None + input_or_output = "Input" + self.pressed = None + + def changeDrawingType(self, text): + global drawing + drawing = text + + def changeConnectionType(self, text): + global input_or_output + input_or_output = text + + + def button1(self,pos): + clicked = [] + for i in pressing_lights: + if is_over(pos, i): + i.change_color() + clicked.append(i) + + for i in non_pressing_lights: + if is_over(pos, i): + clicked.append(i) + + moused_over = False + for i in circuits: + if is_over(pos,i): + clicked.append(i) + if len(clicked) > 0: + clicked[-1].is_clicked(pos) + self.pressed = clicked[-1] + over = False + for i in circuits: + if is_over(pos,i): + over = True + for i in pressing_lights: + if is_over(pos,i): + over = True + for i in non_pressing_lights: + if is_over(pos,i): + over = True + if drawing.lower() in ("or", "and", "not", "xor"): + if not over: + add_circuit(pos, drawing) + if "light" in drawing.lower(): + if not over: + pressing_lights.append(Light(pos)) + + + def button2(self,pos): + deleted = False + for i in non_pressing_lights: + if is_over(pos, i): + del non_pressing_lights[non_pressing_lights.index(i)] + if self.selected == i: + self.selected = None + for item in circuits: + if i in item.inputs: + del item.inputs[item.inputs.index(i)] + deleted = True + if i in item.outputs: + del item.outputs[item.outputs.index(i)] + deleted = True + for i in pressing_lights: + if is_over(pos, i): + del pressing_lights[pressing_lights.index(i)] + if self.selected == i: + self.selected = None + for item in circuits: + if i in item.inputs: + del item.inputs[item.inputs.index(i)] + deleted = True + if i in item.outputs: + del item.outputs[item.outputs.index(i)] + deleted = True + for i in circuits: + if is_over(pos, i): + circuits.remove(i) + deleted = True + if self.selected == i: + self.selected = None + if not deleted: + connects = [] + for i in connections: + if i.in_range(pos[0]): + connects.append(i) + if len(connects) > 0: + closest = connects[0] + for i in connects: + if abs(i.get_error(pos)) < abs(closest.get_error(pos)): + closest = i + distance = closest.get_error(pos) + if abs(distance) < 12: + closest.destroy() + + def button3(self, pos): + over = False + for i in pressing_lights: + if is_over(pos, i): + if self.selected and self.selected in circuits: + connect(i, self.selected) + self.selected = None + elif self.selected == i: + self.selected = None + elif not self.selected: + self.selected = i + over = True + for i in non_pressing_lights: + if is_over(pos, i): + if self.selected and self.selected in circuits: + connect(i, self.selected) + self.selected = None + elif self.selected == i: + self.selected = None + elif not self.selected: + self.selected = i + over = True + for i in circuits: + if is_over(pos, i): + if self.selected in non_pressing_lights or \ + self.selected in pressing_lights and self.selected: + connect(self.selected, i) + self.selected = None + elif self.selected == i: + self.selected = None + elif not self.selected: + self.selected = i + over = True + if not over: self.selected = None + + + + def update(self, context,pos): + if self.selected: + context.set_source_rgb(1, 1, 0) + context.rectangle(self.selected.pos[0]-self.selected.svg.props.width/2-2, self.selected.pos[1]-self.selected.svg.props.height/2-2, + self.selected.svg.props.width+4,self.selected.svg.props.height+4) + context.fill() + for i in circuits: + i.draw(context) + for i in pressing_lights: + i.draw(context) + for i in non_pressing_lights: + i.draw(context) + context.set_font_size(20) + moused_over = False + context.set_source_rgb(0,0,0) + for i in circuits: + if is_over(pos,i) and not moused_over: + context.move_to(pos[0]+10,pos[1]-10) + context.show_text(i.name) + moused_over=True + + + + + + +def save(name): + if name == "": + files = [] + for i in os.listdir(os.path.join("saves", "")): + if ".lc" in i: + item = i.split(".lc")[0] + if "save" in item: + item = item.split("save")[1] + files.append(int(item)) + try: + name = "save" + str(max(files) + 1) + except: + name = "save1" + open_file = open(os.path.join("saves", name + ".lc"), "w") + list1 = {} + for i in pressing_lights: + list1[i.pos[0]] = i.pos[1] + list2 = {} + for i in non_pressing_lights: + list2[i.pos[0]] = i.pos[1] + circuit_list = "" + for i in circuits: + circuit_list += str(i.pos[0]) + ":" + str(i.pos[1]) + circuit_list += ":" + i.name + circuit_list += "," + input_connect = "" + for i in circuits: + for item in i.inputs: + input_connect += str(item.pos[0]) + ":" + \ + str(item.pos[1]) + input_connect += ";" + input_connect += str(i.pos[0])+":"+str(i.pos[1]) + input_connect += "," + output_connect = "" + for i in circuits: + for item in i.outputs: + output_connect += str(item.pos[0]) + ":" + \ + str(item.pos[1]) + output_connect += ";" + output_connect += str(i.pos[0])+":"+str(i.pos[1]) + output_connect += "," + open_file.write(str(list1) + "\n") + open_file.write(str(list2) + "\n") + open_file.write(circuit_list + "\n") + open_file.write(input_connect + "\n") + open_file.write(str(output_connect) + "\n") + + +def load(name): + global circuits, pressing_lights, non_pressing_lights, input_or_output + try: + open_file = open(os.path.join(name), "r").readlines() + except: + return + circuits = [] + pressing_lights = [] + non_pressing_lights = [] + for i in open_file[0][1:-2].split(","): + if i: + pressing_lights.append(Light((float(i.split(":")[0].strip()), + float(i.split(":")[1].strip())))) + for i in open_file[1][1:-2].split(","): + if i: + non_pressing_lights.append(Light((float(i.split(":")[0].strip()), + float(i.split(":")[1].strip())))) + for i in open_file[2].strip().split(","): + if i: + add_circuit((float(i.split(":")[0]), float(i.split(":")[1])), + i.split(":")[2]) + input_or_output = "Input" + for l in open_file[3].split(","): + i = l.strip() + if i: + for item in pressing_lights: + if item.pos == (float(i.split(";")[0].split(":")[0]), + float(i.split(";")[0].split(":")[1])): + light = item + for item in non_pressing_lights: + if item.pos == (float(i.split(";")[0].split(":")[0]), + float(i.split(";")[0].split(":")[1])): + light = item + for item in circuits: + if item.pos == (float(i.split(";")[1].split(":")[0]), + float(i.split(";")[1].split(":")[1])): + circuit = item + connect(light, circuit) + input_or_output = "Output" + for l in open_file[4].split(","): + i = l.strip() + if i: + for item in pressing_lights: + if item.pos == (float(i.split(";")[0].split(":")[0]), + float(i.split(";")[0].split(":")[1])): + light = item + for item in non_pressing_lights: + if item.pos == (float(i.split(";")[0].split(":")[0]), + float(i.split(";")[0].split(":")[1])): + light = item + for item in circuits: + if item.pos == (float(i.split(";")[1].split(":")[0]), + float(i.split(";")[1].split(":")[1])): + circuit = item + connect(light, circuit) + input_or_output = "Input" + diff --git a/LogicCircuitsActivity.pyc b/LogicCircuitsActivity.pyc new file mode 100755 index 0000000..56cfca3 --- /dev/null +++ b/LogicCircuitsActivity.pyc Binary files differ diff --git a/LogicCircuitsActivity.py~ b/LogicCircuitsActivity.py~ new file mode 100755 index 0000000..b8c2d91 --- /dev/null +++ b/LogicCircuitsActivity.py~ @@ -0,0 +1,813 @@ +#!/usr/bin/env python + +# example helloworld.py +from sugar.activity import activity +import pygtk +pygtk.require('2.0') +import gtk +import os +import time +import rsvg +import cairo +X = 1200 +Y = 900 + +class LogicCircuitsActivity(activity.Activity): + + def __init__(self,handle): + activity.Activity.__init__(self,handle) + self.set_title('Logic Circuits Activity') + #begin the program + self.build_GUI() + + + self.graphics = graphicsDriver() + self.mouse_move = 0 + self.clicked = 0 + self.buffer = gtk.gdk.Pixmap(self.draw_area.window, 900, 900) + self.gc = gtk.gdk.GC(self.buffer) + gtk.main() + + def delete_event(self, widget, event, data=None): + print "delete event occurred" + return False + + def destroy(self, widget, data=None): + print "destroy signal occurred" + gtk.main_quit() + + def set_placement(self, widget, data=None): + self.InputLightButton.set_relief(gtk.RELIEF_NORMAL) + self.OutputLightButton.set_relief(gtk.RELIEF_NORMAL) + self.AndButton.set_relief(gtk.RELIEF_NORMAL) + self.NotButton.set_relief(gtk.RELIEF_NORMAL) + self.OrButton.set_relief(gtk.RELIEF_NORMAL) + self.XorButton.set_relief(gtk.RELIEF_NORMAL) + widget.set_relief(gtk.RELIEF_NONE) + self.graphics.changeDrawingType(widget.get_label()) + + def set_connection(self, widget, data=None): + self.input_button.set_relief(gtk.RELIEF_NORMAL) + self.output_button.set_relief(gtk.RELIEF_NORMAL) + widget.set_relief(gtk.RELIEF_NONE) + self.graphics.changeConnectionType(widget.get_label()) + + + def expose(self, widget, event): + self.update() + + + def update(self,pos=(0,0)): + #update the screen + self.context = self.buffer.cairo_create() + self.context.rectangle(0, 0, + *self.draw_area.window.get_size()) + self.context.clip() + self.context.set_source_rgb(1, 1, 1) + self.context.rectangle(0, 0, *self.draw_area.window.get_size()) + self.context.fill() + self.context.set_source_rgb(0, 0, 0) + self.graphics.update(self.context,pos) + self.draw_area.window.draw_drawable(self.gc,self.buffer,0,0,0,0,-1,-1,) + + + def build_GUI(self): + #build the GUI + self.hpaned = gtk.HPaned() + + self.draw_area = gtk.DrawingArea() + self.v = gtk.VPaned() + self.hpaned.add1(self.v) + self.v.show() + self.v2 = gtk.VPaned() + self.v.add1(self.draw_area) + self.draw_area.set_size_request(3*X/4, Y) + self.draw_area.show() + self.draw_area.set_events(gtk.gdk.POINTER_MOTION_MASK | + gtk.gdk.BUTTON_PRESS_MASK | + gtk.gdk.KEY_PRESS_MASK | + gtk.gdk.BUTTON_RELEASE_MASK | + gtk.gdk.POINTER_MOTION_HINT_MASK ) + self.draw_area.connect("motion_notify_event", self.mouse_move) + self.draw_area.connect('button-press-event', self.mouse_press) + self.draw_area.connect('button-release-event', self.mouse_release) + self.draw_area.connect("expose_event", self.expose) + self.filechooser = gtk.FileChooserWidget(gtk.FILE_CHOOSER_ACTION_OPEN) + self.v.add2(self.filechooser) + self.filechooser.set_size_request(3*X/4, Y) + self.filechooser.connect("file-activated",self.fileChoosen) + self.filechooser.set_current_folder("saves") + self.filter = gtk.FileFilter() + self.filter.set_name("txt files") + self.filter.add_pattern("*.lc") + + self.filechooser.add_filter(self.filter) + + + + self.vpaned = gtk.VPaned() + self.hpaned.add2(self.vpaned) + self.vpaned.show() + + self.Frame1 = gtk.Frame("Select an Object to Place") + self.vpaned.add1(self.Frame1) + self.Frame1.show() + + self.Frame2 = gtk.Frame("Select a Connection Type") + self.vpaned2 = gtk.VPaned() + self.vpaned.add2(self.vpaned2) + self.vpaned2.show() + self.vpaned2.add1(self.Frame2) + self.Frame2.show() + + self.Frame3 = gtk.Frame("Save and Load") + self.vpaned2.add2(self.Frame3) + self.Frame3.show() + + self.save_table = gtk.Table(2, 3, False) + self.Frame3.add(self.save_table) + self.save_table.show() + + self.filename = gtk.Label("File Name:") + self.save_table.attach(self.filename,0,1,0,1) + self.filename.show() + + self.file_text = gtk.Entry(15) + self.save_table.attach(self.file_text,1,2,0,1) + self.file_text.show() + + self.SaveButton = gtk.Button(stock = gtk.STOCK_SAVE) + self.save_table.attach(self.SaveButton,0,2,1,2) + self.SaveButton.show() + self.SaveButton.connect("clicked", self.saveFile, None) + + self.OpenButton = gtk.Button(stock = gtk.STOCK_OPEN) + self.save_table.attach(self.OpenButton,0,2,2,3) + self.OpenButton.show() + self.OpenButton.connect("clicked", self.loadFile, None) + + and_image = gtk.image_new_from_pixbuf(rsvg.Handle("data/AND.svg").get_pixbuf()) + not_image = gtk.image_new_from_pixbuf(rsvg.Handle("data/NOT.svg").get_pixbuf()) + or_image = gtk.image_new_from_pixbuf(rsvg.Handle("data/OR.svg").get_pixbuf()) + xor_image = gtk.image_new_from_pixbuf(rsvg.Handle("data/XOR.svg").get_pixbuf()) + inputlight_image = gtk.image_new_from_pixbuf(rsvg.Handle("data/redlight.svg").get_pixbuf()) + outputlight_image = gtk.image_new_from_pixbuf(rsvg.Handle("data/redlight.svg").get_pixbuf()) + + self.object_table = gtk.Table(1, 6, False) + self.Frame1.add(self.object_table) + self.object_table.show() + self.object_table.set_size_request(X/4,2*Y/4) + + self.InputLightButton = gtk.Button("Input Light") + self.OutputLightButton = gtk.Button("Output Light") + self.AndButton = gtk.Button("And") + self.NotButton = gtk.Button("Not") + self.OrButton = gtk.Button("Or") + self.XorButton = gtk.Button("Xor") + + self.InputLightButton.connect("clicked", self.set_placement, None) + self.OutputLightButton.connect("clicked", self.set_placement, None) + self.AndButton.connect("clicked", self.set_placement, None) + self.NotButton.connect("clicked", self.set_placement, None) + self.OrButton.connect("clicked", self.set_placement, None) + self.XorButton.connect("clicked", self.set_placement, None) + + self.InputLightButton.set_relief(gtk.RELIEF_NONE) + + self.AndButton.set_image(and_image) + self.NotButton.set_image(not_image) + self.OrButton.set_image(or_image) + self.XorButton.set_image(xor_image) + self.InputLightButton.set_image(inputlight_image) + self.OutputLightButton.set_image(outputlight_image) + + + + self.object_table.attach(self.InputLightButton,0,1,0,1) + self.object_table.attach(self.OutputLightButton,0,1,1,2) + self.object_table.attach(self.AndButton,0,1,2,3) + self.object_table.attach(self.NotButton,0,1,3,4) + self.object_table.attach(self.OrButton,0,1,4,5) + self.object_table.attach(self.XorButton,0,1,5,6) + + self.InputLightButton.show() + self.OutputLightButton.show() + self.AndButton.show() + self.NotButton.show() + self.OrButton.show() + self.XorButton.show() + + self.connection_table = gtk.Table(1,2,False) + self.Frame2.add(self.connection_table) + self.connection_table.show() + self.connection_table.set_size_request(X/4,Y/4) + self.input_button = gtk.Button("Input") + self.output_button = gtk.Button("Output") + self.input_button.connect("clicked", self.set_connection, None) + self.output_button.connect("clicked", self.set_connection, None) + self.connection_table.attach(self.input_button,0,1,0,1) + self.connection_table.attach(self.output_button,0,1,1,2) + self.input_button.set_relief(gtk.RELIEF_NONE) + self.input_button.show() + self.output_button.show() + self.set_canvas(self.hpaned) + self.show_all() + + def mouse_press(self, widget, event): + if self.clicked + .1 < time.time(): + if event.button == 1: self.graphics.button1((event.x,event.y)) + if event.button == 2: self.graphics.button2((event.x,event.y)) + if event.button == 3: self.graphics.button3((event.x,event.y)) + self.update((event.x,event.y)) + self.clicked=time.time() + + + def mouse_release(self, widget, event): + if event.button == 1: + if self.graphics.pressed != None: + self.graphics.pressed.clicked = False + self.graphics.pressed = None + + def mouse_move(self, widget, event): + if self.mouse_move == 3: + if self.graphics.pressed != None: + self.graphics.pressed.move((event.x,event.y)) + self.update((event.x,event.y)) + self.mouse_move = 0 + self.mouse_move += 1 + self.mousePositions = (event.x,event.y) + + def saveFile(self, widget, event): + text = self.file_text.get_text() + save(text) + + def loadFile(self, widget, event): + self.draw_area.hide() + self.filechooser.show() + + def fileChoosen(self, widget): + filename = widget.get_filename() + load(filename) + self.draw_area.show() + self.filechooser.hide() + + + + + +class Light: + + def __init__(self, position): + self.color = "red" + self.svg = rsvg.Handle("data/" +self.color+"light.svg") + self.pos = position + self.mousePos = (0,0) + self.clicked = False + + def change_color(self): + if self.color == "red": + self.color = "green" + elif self.color == "green": + self.color = "red" + self.update_image() + calculate() + + + def set_color(self, color): + if color == "red": + self.color = "red" + elif color == "green": + self.color = "green" + + def is_clicked(self, pos): + self.mousePos = pos + self.clicked = True + + def get(self): + if self.color == "red": + return 0 + return 1 + + def move(self, pos): + x = pos[0]-self.pos[0] + y = pos[1]-self.pos[1] + if int(x + self.pos[0]) in range(0,900): x = x + self.pos[0] + else: x = self.pos[0] + if int(y + self.pos[1]) in range(0,900): y = y + self.pos[1] + else: y = self.pos[1] + self.pos = (x,y) + #self.mousePos = pos + for i in connections: i.update() + + + def update_image(self): + self.svg = rsvg.Handle("data/" +self.color+"light.svg") + + def draw(self, context): + context.translate(self.pos[0]-self.svg.props.width/2, self.pos[1]-self.svg.props.height/2) + self.svg.render_cairo(context) + context.translate(-1*(self.pos[0]-self.svg.props.width/2), -1*(self.pos[1]-self.svg.props.height/2)) + + + +class Circuit: + + def __init__(self, pos, max_inputs, text,input_pos, output_pos): + self.input_positions = input_pos + self.output_positions = output_pos + self.svg = rsvg.Handle("data/" +text+".svg") + self.text = text + self.pos = pos + self.inputs = [] + self.outputs = [] + self.max_inputs = max_inputs + self.clicked = False + self.mousePos = (0,0) + + def add_input(self, input_object): + if len(self.inputs) > 0 and self.inputs[0].pos[1] > input_object.pos[1]: + self.inputs = [input_object,self.inputs[0]] + else: self.inputs.append(input_object) + + def is_clicked(self, pos): + self.mousePos = pos + self.clicked = True + + def add_output(self, output_object): + self.outputs.append(output_object) + + + def draw(self, context): + i = 0 + context.translate(self.pos[0]-self.svg.props.width/2, self.pos[1]-self.svg.props.height/2) + self.svg.render_cairo(context) + context.translate(-1*(self.pos[0]-self.svg.props.width/2), -1*(self.pos[1]-self.svg.props.height/2)) + context.set_source_rgb(1,0,0) + while i < len(self.inputs): + context.move_to(self.pos[0]+self.input_positions[i][0],self.pos[1]+self.input_positions[i][1]) + context.line_to(*self.inputs[i].pos) + context.stroke() + i += 1 + context.set_source_rgb(0,0,1) + for i in self.outputs: + context.move_to(self.pos[0]+self.output_positions[0],self.pos[1]+self.output_positions[1]) + context.line_to(*i.pos) + context.stroke() + + def move(self, pos): + x = pos[0]-self.mousePos[0] + y = pos[1]-self.mousePos[1] + mpx = pos[0] + mpy = pos[1] + if int(x + self.pos[0]) in range(0,900): x = x + self.pos[0] + else: + x = self.pos[0] + mpx = self.mousePos[0] + if int(y + self.pos[1]) in range(0,900): y = y + self.pos[1] + else: + y = self.pos[1] + mpy = self.mousePos[1] + self.pos = (x,y) + self.mousePos = (mpx,mpy) + for i in connections: i.update() + + def calculate(self): + pass + + +class Not(Circuit): + + def __init__(self, pos): + Circuit.__init__(self, pos, 1, "NOT",[(-45,0)],(45,0)) + self.name = "not" + + def calculate(self): + if not self.inputs[0].get(): + self.outputs[0].set_color("green") + else: + self.outputs[0].set_color("red") + + +class And(Circuit): + + def __init__(self, pos): + Circuit.__init__(self, pos, 2, "AND", [(-45,-10),(-45,10)],(45,0)) + self.name = "and" + + def calculate(self): + if self.inputs[0].get() and self.inputs[1].get(): + self.outputs[0].set_color("green") + else: + self.outputs[0].set_color("red") + + +class Or(Circuit): + + def __init__(self, pos): + Circuit.__init__(self, pos, 2, "OR", [(-45,-10),(-45,10)],(45,0)) + self.name = "or" + + def calculate(self): + if self.inputs[0].get() or self.inputs[1].get(): + self.outputs[0].set_color("green") + else: + self.outputs[0].set_color("red") + + +class Xor(Circuit): + + def __init__(self, pos): + Circuit.__init__(self, pos, 2, "XOR", [(-45,-10),(-45,10)],(45,0)) + self.name = "xor" + + def calculate(self): + if not self.inputs[0].get() == self.inputs[1].get(): + self.outputs[0].set_color("green") + else: + self.outputs[0].set_color("red") + +class connection: + def __init__(self, circuit, light): + self.light = light + self.circuit = circuit + x1 = light.pos[0] + y1 = light.pos[1] + if self.light in self.circuit.inputs: + i = self.circuit.inputs.index(self.light) + x2 = self.circuit.pos[0]+self.circuit.input_positions[i][0] + y2 = self.circuit.pos[1]+self.circuit.input_positions[i][1] + else: + x2 = self.circuit.pos[0]+self.circuit.output_positions[0] + y2 = self.circuit.pos[1]+self.circuit.output_positions[1] + if x1-x2 == 0: + self.slope = 0 + elif x1x2: + self.range = (x2,x1) + self.slope = 1.0*(y2-y1)/(x2-x1) + self.intercept = y1 - self.slope*x1 + calculate() + + def update(self): + x1 = self.light.pos[0] + y1 = self.light.pos[1] + if self.light in self.circuit.inputs: + i = self.circuit.inputs.index(self.light) + x2 = self.circuit.pos[0]+self.circuit.input_positions[i][0] + y2 = self.circuit.pos[1]+self.circuit.input_positions[i][1] + else: + x2 = self.circuit.pos[0]+self.circuit.output_positions[0] + y2 = self.circuit.pos[1]+self.circuit.output_positions[1] + if x1-x2 == 0: + self.slope = 0 + elif x1x2: + self.range = (x2,x1) + self.slope = 1.0*(y2-y1)/(x2-x1) + self.intercept = y1 - self.slope*x1 + + + def in_range(self,x): + if x > self.range[0] and x < self.range[1]: + return True + return False + + def get_error(self, (x, y)): + return self.intercept + self.slope*x - y + + def destroy(self): + if self.light in self.circuit.inputs: + del self.circuit.inputs[self.circuit.inputs.index(self.light)] + elif self.light in self.circuit.outputs: + del self.circuit.outputs[self.circuit.outputs.index(self.light)] + del connections[connections.index(self)] + + + +def add_circuit(pos, string): + if string.lower() == "not": + circuits.append(Not(pos)) + if string.lower() == "or": + circuits.append(Or(pos)) + if string.lower() == "and": + circuits.append(And(pos)) + if string.lower() == "xor": + circuits.append(Xor(pos)) + + + +def is_over(pos, item): + if item.pos[0]-item.svg.props.width/2 < pos[0] < item.pos[0]+item.svg.props.width/2 and \ + item.pos[1]-item.svg.props.height/2 < pos[1] < item.pos[1]+item.svg.props.height/2: + return True + return False + +def connect(light, circuit): + if input_or_output == "Output": + if not circuit.outputs and light not in circuit.inputs: + connected = False + for i in circuits: + if light in i.outputs: connected = True + if not connected: + circuit.add_output(light) + connections.append(connection(circuit,light)) + elif input_or_output == "Input": + if len(circuit.inputs) != circuit.max_inputs \ + and light not in circuit.inputs and light not in circuit.outputs: + circuit.add_input(light) + connections.append(connection(circuit,light)) + + +def calculate(): + for item in xrange(55): + for i in circuits: + if i.outputs and len(i.inputs) == i.max_inputs: + i.calculate() + for i in circuits: + for item in i.outputs: + item.update_image() + + +class graphicsDriver: + def __init__(self, input_size=(900,900)): + global pressing_lights, non_pressing_lights, clock, size + global circuits, drawing, font, input_or_output, connections + size = input_size + connections = [] + pressing_lights = [] + non_pressing_lights = [] + pos = 10 + circuits = [] + drawing = "Input Light" + self.selected = None + input_or_output = "Input" + self.pressed = None + + def changeDrawingType(self, text): + global drawing + drawing = text + + def changeConnectionType(self, text): + global input_or_output + input_or_output = text + + + def button1(self,pos): + clicked = [] + for i in pressing_lights: + if is_over(pos, i): + i.change_color() + clicked.append(i) + + for i in non_pressing_lights: + if is_over(pos, i): + clicked.append(i) + + moused_over = False + for i in circuits: + if is_over(pos,i): + clicked.append(i) + if len(clicked) > 0: + clicked[-1].is_clicked(pos) + self.pressed = clicked[-1] + over = False + for i in circuits: + if is_over(pos,i): + over = True + for i in pressing_lights: + if is_over(pos,i): + over = True + for i in non_pressing_lights: + if is_over(pos,i): + over = True + if drawing.lower() in ("or", "and", "not", "xor"): + temp = Not(pos) + if not over: + add_circuit(temp.pos, drawing) + if "light" in drawing.lower(): + temp = Light(pos) + if not over: + if "input" in drawing.lower(): + pressing_lights.append(temp) + elif "output" in drawing.lower(): + non_pressing_lights.append(temp) + + + def button2(self,pos): + deleted = False + for i in non_pressing_lights: + if is_over(pos, i): + del non_pressing_lights[non_pressing_lights.index(i)] + if self.selected == i: + self.selected = None + for item in circuits: + if i in item.inputs: + del item.inputs[item.inputs.index(i)] + deleted = True + if i in item.outputs: + del item.outputs[item.outputs.index(i)] + deleted = True + for i in pressing_lights: + if is_over(pos, i): + del pressing_lights[pressing_lights.index(i)] + if self.selected == i: + self.selected = None + for item in circuits: + if i in item.inputs: + del item.inputs[item.inputs.index(i)] + deleted = True + if i in item.outputs: + del item.outputs[item.outputs.index(i)] + deleted = True + for i in circuits: + if is_over(pos, i): + circuits.remove(i) + deleted = True + if self.selected == i: + self.selected = None + if not deleted: + connects = [] + for i in connections: + if i.in_range(pos[0]): + connects.append(i) + if len(connects) > 0: + closest = connects[0] + for i in connects: + if abs(i.get_error(pos)) < abs(closest.get_error(pos)): + closest = i + distance = closest.get_error(pos) + if abs(distance) < 12: + closest.destroy() + + def button3(self, pos): + over = False + for i in pressing_lights: + if is_over(pos, i): + if self.selected and self.selected in circuits: + connect(i, self.selected) + self.selected = None + elif self.selected == i: + self.selected = None + elif not self.selected: + self.selected = i + over = True + for i in non_pressing_lights: + if is_over(pos, i): + if self.selected and self.selected in circuits: + connect(i, self.selected) + self.selected = None + elif self.selected == i: + self.selected = None + elif not self.selected: + self.selected = i + over = True + for i in circuits: + if is_over(pos, i): + if self.selected in non_pressing_lights or \ + self.selected in pressing_lights and self.selected: + connect(self.selected, i) + self.selected = None + elif self.selected == i: + self.selected = None + elif not self.selected: + self.selected = i + over = True + if not over: self.selected = None + + + + def update(self, context,pos): + if self.selected: + context.set_source_rgb(1, 1, 0) + context.rectangle(self.selected.pos[0]-self.selected.svg.props.width/2-2, self.selected.pos[1]-self.selected.svg.props.height/2-2, + self.selected.svg.props.width+4,self.selected.svg.props.height+4) + context.fill() + for i in circuits: + i.draw(context) + for i in pressing_lights: + i.draw(context) + for i in non_pressing_lights: + i.draw(context) + context.set_font_size(20) + moused_over = False + context.set_source_rgb(0,0,0) + for i in circuits: + if is_over(pos,i) and not moused_over: + context.move_to(pos[0]+10,pos[1]-10) + context.show_text(i.name) + moused_over=True + + + + + + +def save(name): + if name == "": + files = [] + for i in os.listdir(os.path.join("saves", "")): + if ".lc" in i: + item = i.split(".lc")[0] + if "save" in item: + item = item.split("save")[1] + files.append(int(item)) + try: + name = "save" + str(max(files) + 1) + except: + name = "save1" + open_file = open(os.path.join("saves", name + ".lc"), "w") + list1 = {} + for i in pressing_lights: + list1[i.pos[0]] = i.pos[1] + list2 = {} + for i in non_pressing_lights: + list2[i.pos[0]] = i.pos[1] + circuit_list = "" + for i in circuits: + circuit_list += str(i.pos[0]) + ":" + str(i.pos[1]) + circuit_list += ":" + i.name + circuit_list += "," + input_connect = "" + for i in circuits: + for item in i.inputs: + input_connect += str(item.pos[0]) + ":" + \ + str(item.pos[1]) + input_connect += ";" + input_connect += str(i.pos[0])+":"+str(i.pos[1]) + input_connect += "," + output_connect = "" + for i in circuits: + for item in i.outputs: + output_connect += str(item.pos[0]) + ":" + \ + str(item.pos[1]) + output_connect += ";" + output_connect += str(i.pos[0])+":"+str(i.pos[1]) + output_connect += "," + open_file.write(str(list1) + "\n") + open_file.write(str(list2) + "\n") + open_file.write(circuit_list + "\n") + open_file.write(input_connect + "\n") + open_file.write(str(output_connect) + "\n") + + +def load(name): + global circuits, pressing_lights, non_pressing_lights, input_or_output + try: + open_file = open(os.path.join(name), "r").readlines() + except: + return + circuits = [] + pressing_lights = [] + non_pressing_lights = [] + for i in open_file[0][1:-2].split(","): + if i: + pressing_lights.append(Light((float(i.split(":")[0].strip()), + float(i.split(":")[1].strip())))) + for i in open_file[1][1:-2].split(","): + if i: + non_pressing_lights.append(Light((float(i.split(":")[0].strip()), + float(i.split(":")[1].strip())))) + for i in open_file[2].strip().split(","): + if i: + add_circuit((float(i.split(":")[0]), float(i.split(":")[1])), + i.split(":")[2]) + input_or_output = "Input" + for l in open_file[3].split(","): + i = l.strip() + if i: + for item in pressing_lights: + if item.pos == (float(i.split(";")[0].split(":")[0]), + float(i.split(";")[0].split(":")[1])): + light = item + for item in non_pressing_lights: + if item.pos == (float(i.split(";")[0].split(":")[0]), + float(i.split(";")[0].split(":")[1])): + light = item + for item in circuits: + if item.pos == (float(i.split(";")[1].split(":")[0]), + float(i.split(";")[1].split(":")[1])): + circuit = item + connect(light, circuit) + input_or_output = "Output" + for l in open_file[4].split(","): + i = l.strip() + if i: + for item in pressing_lights: + if item.pos == (float(i.split(";")[0].split(":")[0]), + float(i.split(";")[0].split(":")[1])): + light = item + for item in non_pressing_lights: + if item.pos == (float(i.split(";")[0].split(":")[0]), + float(i.split(";")[0].split(":")[1])): + light = item + for item in circuits: + if item.pos == (float(i.split(";")[1].split(":")[0]), + float(i.split(";")[1].split(":")[1])): + circuit = item + connect(light, circuit) + input_or_output = "Input" + diff --git a/MANIFEST~ b/MANIFEST~ new file mode 100755 index 0000000..9e5525d --- /dev/null +++ b/MANIFEST~ @@ -0,0 +1,11 @@ +GrapherActivity.py +LogicCircuits.py +saves/ +data/AND.svg +data/greenlight.svg +data/NOT.svg +data/OR.svg +data/redlight.svg +data/XOR.svg +activity/activity-grapher.svg +activity/activity.info diff --git a/activity/.logic-circuits.sugar.svg.swp b/activity/.logic-circuits.sugar.svg.swp new file mode 100755 index 0000000..dbf37ed --- /dev/null +++ b/activity/.logic-circuits.sugar.svg.swp Binary files differ diff --git a/activity/.logic-circuits.svg.swo b/activity/.logic-circuits.svg.swo new file mode 100755 index 0000000..fa518ea --- /dev/null +++ b/activity/.logic-circuits.svg.swo Binary files differ diff --git a/activity/.logic-circuits.svg.swp b/activity/.logic-circuits.svg.swp new file mode 100755 index 0000000..506b4f5 --- /dev/null +++ b/activity/.logic-circuits.svg.swp Binary files differ diff --git a/activity/activity.info b/activity/activity.info new file mode 100755 index 0000000..bc9e775 --- /dev/null +++ b/activity/activity.info @@ -0,0 +1,8 @@ +[Activity] +name = Logic-Circuits +bundle_id = org.laptop.LogicCircuitsActivity +class = LogicCircuitsActivity.LogicCircuitsActivity +icon = logic-circuits +activity_version = 1 +host_version = 1 +show_launcher = yes diff --git a/activity/activity.info~ b/activity/activity.info~ new file mode 100755 index 0000000..0933c99 --- /dev/null +++ b/activity/activity.info~ @@ -0,0 +1,8 @@ +[Activity] +name = Grapher-sugarized +bundle_id = org.laptop.GrapherActivity-sugarized +class = GrapherActivity-sugarized.GrapherActivity +icon = activity-grapher +activity_version = 1 +host_version = 1 +show_launcher = yes diff --git a/activity/logic-circuits.sugar.svg b/activity/logic-circuits.sugar.svg new file mode 100755 index 0000000..4098131 --- /dev/null +++ b/activity/logic-circuits.sugar.svg @@ -0,0 +1,9 @@ + + +]> + + + + + diff --git a/activity/logic-circuits.svg b/activity/logic-circuits.svg new file mode 100755 index 0000000..b14eac2 --- /dev/null +++ b/activity/logic-circuits.svg @@ -0,0 +1,9 @@ + + +]> + + + + + diff --git a/activity/logic-circuits.svg~ b/activity/logic-circuits.svg~ new file mode 100755 index 0000000..743e68f --- /dev/null +++ b/activity/logic-circuits.svg~ @@ -0,0 +1,9 @@ + + +]> + + + + + diff --git a/data/AND.svg b/data/AND.svg new file mode 100755 index 0000000..9e3967d --- /dev/null +++ b/data/AND.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + \ No newline at end of file diff --git a/data/NOT.svg b/data/NOT.svg new file mode 100755 index 0000000..f11beae --- /dev/null +++ b/data/NOT.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + \ No newline at end of file diff --git a/data/OR.svg b/data/OR.svg new file mode 100755 index 0000000..829310a --- /dev/null +++ b/data/OR.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + \ No newline at end of file diff --git a/data/XOR.svg b/data/XOR.svg new file mode 100755 index 0000000..b07a88b --- /dev/null +++ b/data/XOR.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data/greenlight.svg b/data/greenlight.svg new file mode 100755 index 0000000..5477eb9 --- /dev/null +++ b/data/greenlight.svg @@ -0,0 +1,47 @@ + + + + + + + + + + + + + diff --git a/data/redlight.svg b/data/redlight.svg new file mode 100755 index 0000000..af2bdd2 --- /dev/null +++ b/data/redlight.svg @@ -0,0 +1,47 @@ + + + + + + + + + + + + + diff --git a/manifest b/manifest new file mode 100755 index 0000000..9e5525d --- /dev/null +++ b/manifest @@ -0,0 +1,11 @@ +GrapherActivity.py +LogicCircuits.py +saves/ +data/AND.svg +data/greenlight.svg +data/NOT.svg +data/OR.svg +data/redlight.svg +data/XOR.svg +activity/activity-grapher.svg +activity/activity.info diff --git a/saves/save1.lc b/saves/save1.lc new file mode 100755 index 0000000..c532f28 --- /dev/null +++ b/saves/save1.lc @@ -0,0 +1,5 @@ +{372.0: 312.0, 365.0: 170.0, 366.0: 357.0, 367.0: 245.0} +{587.0: 205.0} +485.0:211.0:and,469.0:321.0:xor, +365.0:170.0;485.0:211.0,367.0:245.0;485.0:211.0,372.0:312.0;469.0:321.0,366.0:357.0;469.0:321.0, +587.0:205.0;485.0:211.0, diff --git a/saves/save2.lc b/saves/save2.lc new file mode 100755 index 0000000..c532f28 --- /dev/null +++ b/saves/save2.lc @@ -0,0 +1,5 @@ +{372.0: 312.0, 365.0: 170.0, 366.0: 357.0, 367.0: 245.0} +{587.0: 205.0} +485.0:211.0:and,469.0:321.0:xor, +365.0:170.0;485.0:211.0,367.0:245.0;485.0:211.0,372.0:312.0;469.0:321.0,366.0:357.0;469.0:321.0, +587.0:205.0;485.0:211.0, diff --git a/saves/save3.lc b/saves/save3.lc new file mode 100755 index 0000000..eec9e44 --- /dev/null +++ b/saves/save3.lc @@ -0,0 +1,5 @@ +{320.0: 144.0, 321.0: 169.0, 164.0: 488.0, 612.0: 100.0, 521.0: 475.0, 618.0: 169.0, 620.0: 211.0, 621.0: 236.0, 49.0: 72.0, 53.0: 100.0, 56.0: 150.0, 57.0: 179.0, 58.0: 239.0, 314.0: 57.0, 319.0: 82.0} +{774.0: 84.0, 198.0: 228.0, 201.0: 84.0, 778.0: 161.0, 683.0: 482.0, 467.0: 158.0, 468.0: 224.0, 214.0: 166.0, 475.0: 75.0, 298.0: 483.0} +120.0:86.0:and,139.0:165.0:xor,134.0:228.0:or,390.0:77.0:and,391.0:156.0:or,396.0:224.0:xor,707.0:226.0:xor,707.0:163.0:or,706.0:90.0:and,238.0:485.0:not,600.0:482.0:not, +49.0:72.0;120.0:86.0,53.0:100.0;120.0:86.0,56.0:150.0;139.0:165.0,57.0:179.0;139.0:165.0,58.0:217.0;134.0:228.0,58.0:239.0;134.0:228.0,314.0:57.0;390.0:77.0,319.0:82.0;390.0:77.0,320.0:144.0;391.0:156.0,321.0:169.0;391.0:156.0,321.0:211.0;396.0:224.0,319.0:236.0;396.0:224.0,620.0:211.0;707.0:226.0,621.0:236.0;707.0:226.0,621.0:145.0;707.0:163.0,618.0:169.0;707.0:163.0,618.0:77.0;706.0:90.0,612.0:100.0;706.0:90.0,164.0:488.0;238.0:485.0,521.0:475.0;600.0:482.0, +201.0:84.0;120.0:86.0,214.0:166.0;139.0:165.0,198.0:228.0;134.0:228.0,475.0:75.0;390.0:77.0,467.0:158.0;391.0:156.0,468.0:224.0;396.0:224.0,774.0:224.0;707.0:226.0,778.0:161.0;707.0:163.0,774.0:84.0;706.0:90.0,298.0:483.0;238.0:485.0,683.0:482.0;600.0:482.0, diff --git a/saves/save4.lc b/saves/save4.lc new file mode 100755 index 0000000..f144492 --- /dev/null +++ b/saves/save4.lc @@ -0,0 +1,5 @@ +{320.0: 144.0, 321.0: 237.0, 164.0: 488.0, 613.0: 137.0, 521.0: 475.0, 618.0: 169.0, 620.0: 211.0, 621.0: 236.0, 49.0: 72.0, 318.0: 211.0, 53.0: 211.0, 57.0: 178.0, 56.0: 150.0, 612.0: 100.0, 58.0: 239.0, 314.0: 57.0, 608.0: 71.0, 319.0: 82.0} +{774.0: 84.0, 198.0: 228.0, 201.0: 84.0, 778.0: 161.0, 683.0: 482.0, 782.0: 224.0, 467.0: 158.0, 468.0: 224.0, 214.0: 166.0, 475.0: 75.0, 298.0: 483.0} +120.0:86.0:and,139.0:165.0:xor,134.0:228.0:or,390.0:77.0:and,391.0:156.0:or,396.0:224.0:xor,707.0:226.0:xor,707.0:163.0:or,706.0:90.0:and,238.0:485.0:not,600.0:482.0:not, +49.0:72.0;120.0:86.0,53.0:100.0;120.0:86.0,56.0:150.0;139.0:165.0,57.0:178.0;139.0:165.0,53.0:211.0;134.0:228.0,58.0:239.0;134.0:228.0,314.0:57.0;390.0:77.0,319.0:82.0;390.0:77.0,320.0:144.0;391.0:156.0,321.0:169.0;391.0:156.0,318.0:211.0;396.0:224.0,321.0:237.0;396.0:224.0,620.0:211.0;707.0:226.0,621.0:236.0;707.0:226.0,613.0:137.0;707.0:163.0,618.0:169.0;707.0:163.0,608.0:71.0;706.0:90.0,612.0:100.0;706.0:90.0,164.0:488.0;238.0:485.0,521.0:475.0;600.0:482.0, +201.0:84.0;120.0:86.0,214.0:166.0;139.0:165.0,198.0:228.0;134.0:228.0,475.0:75.0;390.0:77.0,467.0:158.0;391.0:156.0,468.0:224.0;396.0:224.0,782.0:224.0;707.0:226.0,778.0:161.0;707.0:163.0,774.0:84.0;706.0:90.0,298.0:483.0;238.0:485.0,683.0:482.0;600.0:482.0, diff --git a/saves/save5.lc b/saves/save5.lc new file mode 100755 index 0000000..65657a4 --- /dev/null +++ b/saves/save5.lc @@ -0,0 +1,5 @@ +{320.0: 144.0, 321.0: 237.0, 164.0: 488.0, 613.0: 137.0, 521.0: 475.0, 618.0: 169.0, 620.0: 211.0, 621.0: 236.0, 49.0: 72.0, 53.0: 211.0, 612.0: 100.0, 608.0: 71.0, 56.0: 150.0, 57.0: 178.0, 58.0: 239.0, 314.0: 57.0, 318.0: 211.0, 319.0: 82.0} +{774.0: 84.0, 198.0: 228.0, 201.0: 84.0, 778.0: 161.0, 683.0: 482.0, 782.0: 224.0, 467.0: 158.0, 468.0: 224.0, 214.0: 166.0, 475.0: 75.0, 298.0: 483.0} +120.0:86.0:and,139.0:165.0:xor,134.0:228.0:or,390.0:77.0:and,391.0:156.0:or,396.0:224.0:xor,707.0:226.0:xor,707.0:163.0:or,706.0:90.0:and,238.0:485.0:not,600.0:482.0:not, +49.0:72.0;120.0:86.0,56.0:150.0;139.0:165.0,57.0:178.0;139.0:165.0,53.0:211.0;134.0:228.0,58.0:239.0;134.0:228.0,314.0:57.0;390.0:77.0,319.0:82.0;390.0:77.0,320.0:144.0;391.0:156.0,318.0:211.0;396.0:224.0,321.0:237.0;396.0:224.0,620.0:211.0;707.0:226.0,621.0:236.0;707.0:226.0,613.0:137.0;707.0:163.0,618.0:169.0;707.0:163.0,608.0:71.0;706.0:90.0,612.0:100.0;706.0:90.0,164.0:488.0;238.0:485.0,521.0:475.0;600.0:482.0, +201.0:84.0;120.0:86.0,214.0:166.0;139.0:165.0,198.0:228.0;134.0:228.0,475.0:75.0;390.0:77.0,467.0:158.0;391.0:156.0,468.0:224.0;396.0:224.0,782.0:224.0;707.0:226.0,778.0:161.0;707.0:163.0,774.0:84.0;706.0:90.0,298.0:483.0;238.0:485.0,683.0:482.0;600.0:482.0, diff --git a/saves/save6.lc b/saves/save6.lc new file mode 100755 index 0000000..f026c8d --- /dev/null +++ b/saves/save6.lc @@ -0,0 +1,5 @@ +{320.0: 144.0, 321.0: 237.0, 164.0: 488.0, 613.0: 137.0, 521.0: 475.0, 618.0: 169.0, 620.0: 211.0, 621.0: 236.0, 49.0: 97.0, 318.0: 164.0, 53.0: 211.0, 57.0: 178.0, 56.0: 150.0, 612.0: 100.0, 58.0: 239.0, 314.0: 57.0, 608.0: 71.0, 319.0: 82.0} +{774.0: 84.0, 198.0: 228.0, 201.0: 84.0, 778.0: 161.0, 683.0: 482.0, 782.0: 224.0, 467.0: 158.0, 468.0: 224.0, 214.0: 166.0, 475.0: 75.0, 298.0: 483.0} +120.0:86.0:and,139.0:165.0:xor,134.0:228.0:or,390.0:77.0:and,391.0:156.0:or,396.0:224.0:xor,707.0:226.0:xor,707.0:163.0:or,706.0:90.0:and,238.0:485.0:not,600.0:482.0:not, +49.0:72.0;120.0:86.0,49.0:97.0;120.0:86.0,56.0:150.0;139.0:165.0,57.0:178.0;139.0:165.0,53.0:211.0;134.0:228.0,58.0:239.0;134.0:228.0,314.0:57.0;390.0:77.0,319.0:82.0;390.0:77.0,320.0:144.0;391.0:156.0,318.0:164.0;391.0:156.0,318.0:211.0;396.0:224.0,321.0:237.0;396.0:224.0,620.0:211.0;707.0:226.0,621.0:236.0;707.0:226.0,613.0:137.0;707.0:163.0,618.0:169.0;707.0:163.0,608.0:71.0;706.0:90.0,612.0:100.0;706.0:90.0,164.0:488.0;238.0:485.0,521.0:475.0;600.0:482.0, +201.0:84.0;120.0:86.0,214.0:166.0;139.0:165.0,198.0:228.0;134.0:228.0,475.0:75.0;390.0:77.0,467.0:158.0;391.0:156.0,468.0:224.0;396.0:224.0,782.0:224.0;707.0:226.0,778.0:161.0;707.0:163.0,774.0:84.0;706.0:90.0,298.0:483.0;238.0:485.0,683.0:482.0;600.0:482.0, diff --git a/saves/save7.lc b/saves/save7.lc new file mode 100755 index 0000000..3561aa7 --- /dev/null +++ b/saves/save7.lc @@ -0,0 +1,5 @@ +{320.0: 144.0, 321.0: 237.0, 164.0: 488.0, 613.0: 137.0, 521.0: 475.0, 618.0: 169.0, 620.0: 211.0, 621.0: 236.0, 49.0: 97.0, 53.0: 211.0, 612.0: 100.0, 608.0: 71.0, 56.0: 150.0, 57.0: 178.0, 58.0: 239.0, 314.0: 57.0, 318.0: 164.0, 319.0: 82.0} +{774.0: 84.0, 198.0: 228.0, 201.0: 84.0, 778.0: 161.0, 683.0: 482.0, 782.0: 224.0, 467.0: 158.0, 468.0: 224.0, 214.0: 166.0, 475.0: 75.0, 298.0: 483.0} +120.0:86.0:and,139.0:165.0:xor,134.0:228.0:or,390.0:77.0:and,391.0:156.0:or,396.0:224.0:xor,707.0:226.0:xor,707.0:163.0:or,706.0:90.0:and,238.0:485.0:not,600.0:482.0:not, + + diff --git a/saves/save8.lc b/saves/save8.lc new file mode 100755 index 0000000..acbc961 --- /dev/null +++ b/saves/save8.lc @@ -0,0 +1,5 @@ +{128.0: 493.0, 261.0: 339.0, 390.0: 525.0, 7.0: 314.0, 393.0: 564.0, 11.0: 261.0, 534.0: 429.0, 535.0: 473.0, 177.0: 153.0, 183.0: 93.0, 696.0: 624.0, 710.0: 659.0, 119.0: 527.0, 722.0: 135.0, 212.0: 579.0, 726.0: 170.0, 220.0: 626.0, 734.0: 369.0, 225.0: 228.0, 370.0: 297.0, 759.0: 406.0, 255.0: 370.0} +{521.0: 277.0, 369.0: 244.0} +448.0:273.0:and,297.0:233.0:not,215.0:511.0:and,511.0:553.0:and,650.0:449.0:and,844.0:385.0:and,781.0:639.0:and,354.0:357.0:and,326.0:608.0:and,87.0:282.0:and,284.0:137.0:and,802.0:157.0:and, +369.0:244.0;448.0:273.0,370.0:297.0;448.0:273.0,225.0:228.0;297.0:233.0,128.0:493.0;215.0:511.0,119.0:527.0;215.0:511.0,390.0:525.0;511.0:553.0,393.0:564.0;511.0:553.0,534.0:429.0;650.0:449.0,535.0:473.0;650.0:449.0,734.0:369.0;844.0:385.0,759.0:406.0;844.0:385.0,696.0:624.0;781.0:639.0,710.0:659.0;781.0:639.0,261.0:339.0;354.0:357.0,255.0:370.0;354.0:357.0,212.0:579.0;326.0:608.0,220.0:626.0;326.0:608.0,11.0:261.0;87.0:282.0,7.0:314.0;87.0:282.0,183.0:93.0;284.0:137.0,177.0:153.0;284.0:137.0,722.0:135.0;802.0:157.0,726.0:170.0;802.0:157.0, +521.0:277.0;448.0:273.0,369.0:244.0;297.0:233.0, diff --git a/saves/save9.lc b/saves/save9.lc new file mode 100755 index 0000000..6e6aed5 --- /dev/null +++ b/saves/save9.lc @@ -0,0 +1,5 @@ +{128.0: 493.0, 261.0: 339.0, 390.0: 525.0, 7.0: 314.0, 393.0: 564.0, 11.0: 261.0, 534.0: 429.0, 535.0: 473.0, 177.0: 153.0, 183.0: 93.0, 696.0: 624.0, 710.0: 659.0, 119.0: 527.0, 722.0: 135.0, 212.0: 579.0, 726.0: 170.0, 220.0: 626.0, 734.0: 369.0, 225.0: 228.0, 370.0: 297.0, 759.0: 406.0, 255.0: 370.0} +{449.0: 353.0, 771.0: 444.0, 401.0: 610.0, 521.0: 277.0, 856.0: 641.0, 369.0: 244.0, 931.0: 393.0, 597.0: 554.0, 278.0: 511.0, 888.0: 151.0, 153.0: 286.0, 350.0: 144.0} +448.0:273.0:and,297.0:233.0:not,215.0:511.0:and,511.0:553.0:and,650.0:449.0:and,844.0:385.0:and,781.0:639.0:and,354.0:357.0:and,326.0:608.0:and,87.0:282.0:and,284.0:137.0:and,802.0:157.0:and, +369.0:244.0;448.0:273.0,370.0:297.0;448.0:273.0,225.0:228.0;297.0:233.0,128.0:493.0;215.0:511.0,119.0:527.0;215.0:511.0,390.0:525.0;511.0:553.0,393.0:564.0;511.0:553.0,534.0:429.0;650.0:449.0,535.0:473.0;650.0:449.0,734.0:369.0;844.0:385.0,759.0:406.0;844.0:385.0,696.0:624.0;781.0:639.0,710.0:659.0;781.0:639.0,261.0:339.0;354.0:357.0,255.0:370.0;354.0:357.0,212.0:579.0;326.0:608.0,220.0:626.0;326.0:608.0,11.0:261.0;87.0:282.0,7.0:314.0;87.0:282.0,183.0:93.0;284.0:137.0,177.0:153.0;284.0:137.0,722.0:135.0;802.0:157.0,726.0:170.0;802.0:157.0, +521.0:277.0;448.0:273.0,369.0:244.0;297.0:233.0,278.0:511.0;215.0:511.0,597.0:554.0;511.0:553.0,771.0:444.0;650.0:449.0,931.0:393.0;844.0:385.0,856.0:641.0;781.0:639.0,449.0:353.0;354.0:357.0,401.0:610.0;326.0:608.0,153.0:286.0;87.0:282.0,350.0:144.0;284.0:137.0,888.0:151.0;802.0:157.0, diff --git a/setup.py b/setup.py new file mode 100755 index 0000000..6ed89aa --- /dev/null +++ b/setup.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python +from sugar.activity import bundlebuilder +bundlebuilder.start() + -- cgit v0.9.1