Example #1
25
class GameGUI:

  def __init__(self):
    self.app = Tk()
    self.app.title('Tic Tac Toe A.I')
    self.app.resizable(width=False, height=False)
    self.board = GameAI()
    self.font = Font(family = "Arial", size = 28)
    self.buttons = {}
    for x,y in self.board.fields:
     handler = lambda x = x, y = y: self.move(x,y)
     button = Button(self.app, command = handler, font = self.font, width = 2,height = 1)
     button.grid(row = y, column = x)
     self.buttons[x,y] = button
    handler = lambda: self.reset()
    button = Button(self.app,text = 'reset',command = handler)
    button.grid(row = self.board.dim+1, column = 0, columnspan = self.board.dim,sticky="WE")
    self.quit = Button(self.app,text = 'quit', command = self.app.quit)
    self.quit.grid(row = self.board.dim+2, column = 0, columnspan = self.board.dim,sticky="WE")
    print "Dear Player, to mave a move click on any button and wait for A.I..."

  def reset(self):
    self.board = GameAI()
    self.update()

  def move(self,x,y):
    self.app.config(cursor = "watch")
    self.app.update()
    self.board = self.board.move(x,y)
    self.update()
    move = self.board.best()
    if move:
     self.board = self.board.move(*move)
     self.update()
    self.app.config(cursor = "")

  def update(self):
   for (x,y) in self.board.fields:
     text = self.board.fields[x,y]
     self.buttons[x,y]['text'] = text
     self.buttons[x,y]['disabledforeground'] = 'black'
     if text == self.board.empty:
       self.buttons[x,y]['state'] = 'normal'
     else:
       self.buttons[x,y]['state'] = 'disabled'
     winning = self.board.won()
     if winning:
      for x,y in winning:
       self.buttons[x,y]['disabledforeground'] = 'red'
      for x,y in self.buttons:
       self.buttons[x,y]['state']= 'disabled'
      for (x,y) in self.board.fields:
       self.buttons[x,y].update()

  def mainloop(self):
    self.app.mainloop()
Example #2
1
class GUI:

  def __init__(self):
    self.app = Tk()
    self.app.title('TicTacToe')
    self.app.resizable(width=False, height=False)
    self.board = Board()
    self.font = Font(family="Helvetica", size=32)
    self.buttons = {}
    for x,y in self.board.fields:
      handler = lambda x=x,y=y: self.move(x,y)
      button = Button(self.app, command=handler, font=self.font, width=2, height=1)
      button.grid(row=y, column=x)
      self.buttons[x,y] = button
    handler = lambda: self.reset()
    button = Button(self.app, text='reset', command=handler)
    button.grid(row=self.board.size+1, column=0, columnspan=self.board.size, sticky="WE")
    self.update()

  def reset(self):
    self.board = Board()
    self.update()

  def move(self,x,y):
    self.app.config(cursor="watch")
    self.app.update()
    self.board = self.board.move(x,y)
    self.update()
    move = self.board.best()
    if move:
      self.board = self.board.move(*move)
      self.update()
    self.app.config(cursor="")

  def update(self):
    for (x,y) in self.board.fields:
      text = self.board.fields[x,y]
      self.buttons[x,y]['text'] = text
      self.buttons[x,y]['disabledforeground'] = 'black'
      if text==self.board.empty:
        self.buttons[x,y]['state'] = 'normal'
      else:
        self.buttons[x,y]['state'] = 'disabled'
    winning = self.board.won()
    if winning:
      for x,y in winning:
        self.buttons[x,y]['disabledforeground'] = 'red'
      for x,y in self.buttons:
        self.buttons[x,y]['state'] = 'disabled'
    for (x,y) in self.board.fields:
      self.buttons[x,y].update()

  def mainloop(self):
    self.app.mainloop()
Example #3
1
def main():
    note_sample_window_size = 75
    training_time = 10
    number_of_keys = 4

    if len(sys.argv) > 1:
        note_sample_window_size = int(sys.argv[1])
    if len(sys.argv) > 2:
        training_time = int(sys.argv[2])
    if len(sys.argv) > 3:
        number_of_keys = int(sys.argv[3])

    # first, run the training function
    (clf, mb) = train(note_sample_window_size, train_time_sec=training_time, n_keys=number_of_keys)

    root = Tk()
    root.geometry("1000x400")
    MainWindow(root, clf, mb, note_sample_window_size)
    menubar = Menu(root)
    menubar.add_command(label="Quit", command=root.quit)
    # display the menu
    root.config(menu=menubar)
    root.mainloop()
Example #4
1
        currentMove = self.v
        self.top.destroy()

class GameButton():
    def __init__(self, i, master=None):
        self.numara = i
        self.satir = i / 3
        self.sutun = i % 3
        self.metin = StringVar()
        self.metin.set("")
        def clicked():
            player(self.numara)
        self.gorunum = Button(root, command=clicked, bg='gray', width=200, height=150, image=renksizAdam)
        self.gorunum.grid(row=self.satir, column=self.sutun)

root = Tk()
root.wait_window(WhichColor(root).top)
root.title('XOX Graphical Interface')

menubar = Menu(root)
menubar.add_command(label="NEW GAME", command=startGame)
menubar.add_command(label="POINTS", command=points)
menubar.add_command(label="EXIT", command=root.quit)

root.config(menu=menubar)
renksizAdam = ImageTk.PhotoImage(file="RenksizAdam.png")
yesilAdam = ImageTk.PhotoImage(file="YesilAdam.png")
sariAdam = ImageTk.PhotoImage(file="SariAdam.png")
startGame()
mainloop()
Example #5
0
def main():
    root = Tk()
    root.config(width=WINDOW_W, height=WINDOW_H)
    root.propagate(0)
    frame = Frame(root)
    main_menu = MainMenu(root)
    root.mainloop()
Example #6
0
def build_root():

	ui_root = Tk()

	# Build root drop-down menu and immediate child menus.
	main_menu = Menu(ui_root)
	file_submenu = Menu(main_menu, title="File")
	settings_submenu = Menu(main_menu, title="Settings")
	help_submenu = Menu(main_menu, title="Help")

	# File
	file_submenu.add_command(label="New Dataset...", command=dummy)
	file_submenu.add_command(label="Open...", command=dummy)
	file_submenu.add_command(label="Export...", command=dummy)
	file_submenu.add_separator()
	file_submenu.add_command(label="Quit", command=dummy)

	# Settings
	settings_submenu.add_command(label="PyNewhall Settings...", command=dummy)

	# Help
	help_submenu.add_command(label="About...", command=dummy)
	help_submenu.add_command(label="Documentation...", command=dummy)

	# Wrap up building main drop down menubar.
	main_menu.add_cascade(label="File", menu=file_submenu)
	main_menu.add_cascade(label="Settings", menu=settings_submenu)
	main_menu.add_cascade(label="Help", menu=help_submenu)
	ui_root.config(menu=main_menu)

	ui_root.mainloop()
Example #7
0
class GUI:
    def __init__(self):
        self.app = Tk()
        self.app.title('TicTacToe')
        self.app.resizable(width=False, height=False)
        self.board = Board()
        self.font = Font(family="Helvetica", size=32)
        self.buttons = {}
        for x, y in self.board.fields:
            handler = lambda x=x, y=y: self.move(x, y)
            button = Button(self.app,
                            command=handler,
                            font=self.font,
                            width=2,
                            height=1)
            button.grid(row=y, column=x)
            self.buttons[x, y] = button
        handler = lambda: self.reset()
        button = Button(self.app, text='reset', command=handler)
        button.grid(row=self.board.size + 1,
                    column=0,
                    columnspan=self.board.size,
                    sticky="WE")
        self.update()

    def reset(self):
        self.board = Board()
        self.update()

    def move(self, x, y):
        self.app.config(cursor="watch")
        self.app.update()
        self.board = self.board.move(x, y)
        self.update()
        move = self.board.best()
        if move:
            self.board = self.board.move(*move)
            self.update()
        self.app.config(cursor="")

    def update(self):
        for (x, y) in self.board.fields:
            text = self.board.fields[x, y]
            self.buttons[x, y]['text'] = text
            self.buttons[x, y]['disabledforeground'] = 'black'
            if text == self.board.empty:
                self.buttons[x, y]['state'] = 'normal'
            else:
                self.buttons[x, y]['state'] = 'disabled'
        winning = self.board.won()
        if winning:
            for x, y in winning:
                self.buttons[x, y]['disabledforeground'] = 'red'
            for x, y in self.buttons:
                self.buttons[x, y]['state'] = 'disabled'
        for (x, y) in self.board.fields:
            self.buttons[x, y].update()

    def mainloop(self):
        self.app.mainloop()
Example #8
0
def main():
    root = Tk()
    root.geometry("800x480")
    root.wm_title('faigh ar ais as an fharraige')
    if len(sys.argv) > 1 and sys.argv[1] == 'fs':
        root.wm_attributes('-fullscreen', True)
    faaaaf_item(root)
    root.config(cursor='none')
    root.mainloop()
    def __init__(self):
        root = Tk()
        root.title("split data")
        root.geometry("200x200")
        menu = Menu(root)
        root.config(menu=menu)
        filemenu = Menu(menu)
        menu.add_cascade(label="File", menu=filemenu)
        filemenu.add_command(label="Load data",command = self.load_data)
        self.notifcation = Label(root,text="")
        self.notifcation.grid(row=0,column=0)

        root.mainloop()
Example #10
0
class GUI:
    def __init__(self):
        self.app = Tk()
        self.app.title('War Game')
        self.app.resizable(width=False, height=False)
        self.font = Font(family="Helvetica", size=32)
        self.buttons = {}
        self.board = Board('./boards/Smolensk.txt')
        self.size = SIZE

        for y in xrange(1, self.size + 1):
            for x in xrange(1, self.size + 1):
                handler = lambda x=x, y=y: self.move(x, y)
                button = Button(self.app, command=handler, font=self.font, width=3, height=1, text=self.board.values[y, x], background='gray')
                button.grid(row=y, column=x)
                self.buttons[x, y] = button

        handler = lambda: self.auto_move()
        button = Button(self.app, text='Start AI', command=handler)
        button.grid(row=self.size + 1, column=1, columnspan=self.size, sticky="WE")

    def auto_move(self):
        while self.board.nodes_left > 0:
            if self.board.player == 1:
                cost, (y, x) = self.board.root_negalphabeta()
            else:
                cost, (y, x) = self.board.root_negalphabeta()

            print 'Player: {} Heuristic {}'.format(self.board.player, cost)
            self.move(x, y)
            print 'Score: {}'.format(self.board.score)

    def move(self, x, y):
        self.app.config(cursor="watch")
        self.app.update()
        self.board.move(x, y)
        self.update(x, y)
        self.app.config(cursor="")

    def update(self, x, y):
        self.buttons[x, y]['state'] = 'disabled'
        for y in xrange(1, self.size + 1):
            for x in xrange(1, self.size + 1):
                self.buttons[x, y]['background'] = COLORS[self.board.colors[y, x]]
                self.buttons[x, y].update()

    def mainloop(self):
        self.app.mainloop()
    def __init__(self):
        root = Tk()
        root.title("Fractal Dimension")
        root.geometry("200x200")
        menu = Menu(root)
        root.config(menu=menu)
        filemenu = Menu(menu)
        menu.add_cascade(label="File", menu=filemenu)
        filemenu.add_command(label="Load data",command = self.load_data)
        
        self.ca=[]
        max_size = 128
        while max_size>0:
            self.ca.append(CaGrid(max_size,max_size))
            max_size = max_size/2

        root.mainloop()
Example #12
0
    def __init__(self):
        root = Tk()
        root.title("Fractal Dimension")
        root.geometry("200x200")
        menu = Menu(root)
        root.config(menu=menu)
        filemenu = Menu(menu)
        menu.add_cascade(label="File", menu=filemenu)
        filemenu.add_command(label="Load data", command=self.load_data)

        self.ca = []
        max_size = 128
        while max_size > 0:
            self.ca.append(CaGrid(max_size, max_size))
            max_size = max_size / 2

        root.mainloop()
Example #13
0
    def __init__(self):
        master = Tk()
        master.style = ttk.Style()
        master.style.theme_use("default")
        master.config(bg=background_colour)
        master.resizable(
            0, 0
        )  # Disable resizing the UI to prevent having to make widget placing dynamic
        master.winfo_toplevel().title(frame_title)
        master.iconbitmap("bitcoin.ico")

        # Create pumper assistant to store data on the current BTC and alt holdings.
        self.pumper = pumper()

        self.create_title(master)
        self.create_api_info(master, previous_row=0)
        self.create_auto_sell(master, previous_row=3)
        self.create_stop_loss(master, previous_row=4)
        self.create_order_type(master, previous_row=6)
        self.create_fee_type(master, previous_row=7)
        self.create_btc_balance_picker(master, previous_row=8)
        self.create_alt_ticker(master, previous_row=10)
        self.create_pump_and_sell_buttons(master, previous_row=11)
        self.create_current_profit(master, previous_row=12)

        self.create_output_box(master, rightmost_column=1)

        # Can hardcode API key and Secret
        #self.api_key_entry.delete(0,END)
        #self.api_key_entry.insert(0,"KEY")
        #self.api_key_entry.config(state=DISABLED)
        #self.api_secret_entry.delete(0, END)
        #self.api_secret_entry.insert(0, "SECRET")
        #self.api_secret_entry.config(state=DISABLED)

        # Display the UI, this can only be called once per program.
        # Nothing in the main Python script will be run after creating the UI because of this.
        master.mainloop()
class PiPresents(object):
    def __init__(self):
        gc.set_debug(gc.DEBUG_UNCOLLECTABLE | gc.DEBUG_INSTANCES
                     | gc.DEBUG_OBJECTS | gc.DEBUG_SAVEALL)
        self.pipresents_issue = "1.3"
        self.pipresents_minorissue = '1.3.1g'
        # position and size of window without -f command line option
        self.nonfull_window_width = 0.45  # proportion of width
        self.nonfull_window_height = 0.7  # proportion of height
        self.nonfull_window_x = 0  # position of top left corner
        self.nonfull_window_y = 0  # position of top left corner
        self.pp_background = 'black'

        StopWatch.global_enable = False

        # set up the handler for SIGTERM
        signal.signal(signal.SIGTERM, self.handle_sigterm)

        # ****************************************
        # Initialisation
        # ***************************************
        # get command line options
        self.options = command_options()

        # get Pi Presents code directory
        pp_dir = sys.path[0]
        self.pp_dir = pp_dir

        if not os.path.exists(pp_dir + "/pipresents.py"):
            if self.options['manager'] is False:
                tkMessageBox.showwarning(
                    "Pi Presents",
                    "Bad Application Directory:\n{0}".format(pp_dir))
            exit(103)

        # Initialise logging and tracing
        Monitor.log_path = pp_dir
        self.mon = Monitor()
        # Init in PiPresents only
        self.mon.init()

        # uncomment to enable control of logging from within a class
        # Monitor.enable_in_code = True # enables control of log level in the code for a class  - self.mon.set_log_level()

        # make a shorter list to log/trace only some classes without using enable_in_code.
        Monitor.classes = [
            'PiPresents', 'pp_paths', 'HyperlinkShow', 'RadioButtonShow',
            'ArtLiveShow', 'ArtMediaShow', 'MediaShow', 'LiveShow', 'MenuShow',
            'PathManager', 'ControlsManager', 'ShowManager', 'PluginManager',
            'MplayerDriver', 'OMXDriver', 'UZBLDriver', 'KbdDriver',
            'GPIODriver', 'TimeOfDay', 'ScreenDriver', 'Animate', 'OSCDriver'
        ]

        # Monitor.classes=['PiPresents','ArtMediaShow','VideoPlayer','OMXDriver']

        # get global log level from command line
        Monitor.log_level = int(self.options['debug'])
        Monitor.manager = self.options['manager']
        # print self.options['manager']
        self.mon.newline(3)
        self.mon.log(
            self,
            "Pi Presents is starting, Version:" + self.pipresents_minorissue)
        # self.mon.log (self," OS and separator:" + os.name +'  ' + os.sep)
        self.mon.log(self, "sys.path[0] -  location of code: " + sys.path[0])
        if os.geteuid() != 0:
            user = os.getenv('USER')
        else:
            user = os.getenv('SUDO_USER')
        self.mon.log(self, 'User is: ' + user)
        # self.mon.log(self,"os.getenv('HOME') -  user home directory (not used): " + os.getenv('HOME')) # does not work
        # self.mon.log(self,"os.path.expanduser('~') -  user home directory: " + os.path.expanduser('~'))   # does not work

        # optional other classes used
        self.root = None
        self.ppio = None
        self.tod = None
        self.animate = None
        self.gpiodriver = None
        self.oscdriver = None
        self.osc_enabled = False
        self.gpio_enabled = False
        self.tod_enabled = False

        # get home path from -o option
        self.pp_home = pp_paths.get_home(self.options['home'])
        if self.pp_home is None:
            self.end('error', 'Failed to find pp_home')

        # get profile path from -p option
        # pp_profile is the full path to the directory that contains
        # pp_showlist.json and other files for the profile
        self.pp_profile = pp_paths.get_profile_dir(self.pp_home,
                                                   self.options['profile'])
        if self.pp_profile is None:
            self.end('error', 'Failed to find profile')

        # check profile exists
        if os.path.exists(self.pp_profile):
            self.mon.log(
                self, "Found Requested profile - pp_profile directory is: " +
                self.pp_profile)
        else:
            self.mon.err(
                self, "Failed to find requested profile: " + self.pp_profile)
            self.end('error', 'Failed to find profile')

        self.mon.start_stats(self.options['profile'])

        # check 'verify' option
        if self.options['verify'] is True:
            val = Validator()
            if val.validate_profile(None, pp_dir, self.pp_home,
                                    self.pp_profile, self.pipresents_issue,
                                    False) is False:
                self.mon.err(self, "Validation Failed")
                self.end('error', 'Validation Failed')

        # initialise and read the showlist in the profile
        self.showlist = ShowList()
        self.showlist_file = self.pp_profile + "/pp_showlist.json"
        if os.path.exists(self.showlist_file):
            self.showlist.open_json(self.showlist_file)
        else:
            self.mon.err(self, "showlist not found at " + self.showlist_file)
            self.end('error', 'showlist not found')

        # check profile and Pi Presents issues are compatible
        if float(self.showlist.sissue()) != float(self.pipresents_issue):
            self.mon.err(
                self, "Version of profile " + self.showlist.sissue() +
                " is not  same as Pi Presents, must exit")
            self.end('error', 'wrong version of profile')

        # get the 'start' show from the showlist
        index = self.showlist.index_of_show('start')
        if index >= 0:
            self.showlist.select(index)
            self.starter_show = self.showlist.selected_show()
        else:
            self.mon.err(self, "Show [start] not found in showlist")
            self.end('error', 'start show not found')

        if self.starter_show['start-show'] == '':
            self.mon.warn(self, "No Start Shows in Start Show")

# ********************
# SET UP THE GUI
# ********************
# turn off the screenblanking and saver
        if self.options['noblank'] is True:
            call(["xset", "s", "off"])
            call(["xset", "s", "-dpms"])

        self.root = Tk()

        self.title = 'Pi Presents - ' + self.pp_profile
        self.icon_text = 'Pi Presents'
        self.root.title(self.title)
        self.root.iconname(self.icon_text)
        self.root.config(bg=self.pp_background)

        self.mon.log(
            self, 'native screen dimensions are ' +
            str(self.root.winfo_screenwidth()) + ' x ' +
            str(self.root.winfo_screenheight()) + ' pixcels')
        if self.options['screensize'] == '':
            self.screen_width = self.root.winfo_screenwidth()
            self.screen_height = self.root.winfo_screenheight()
        else:
            reason, message, self.screen_width, self.screen_height = self.parse_screen(
                self.options['screensize'])
            if reason == 'error':
                self.mon.err(self, message)
                self.end('error', message)

        self.mon.log(
            self, 'commanded screen dimensions are ' + str(self.screen_width) +
            ' x ' + str(self.screen_height) + ' pixcels')

        # set window dimensions and decorations
        if self.options['fullscreen'] is False:
            self.window_width = int(self.root.winfo_screenwidth() *
                                    self.nonfull_window_width)
            self.window_height = int(self.root.winfo_screenheight() *
                                     self.nonfull_window_height)
            self.window_x = self.nonfull_window_x
            self.window_y = self.nonfull_window_y
            self.root.geometry("%dx%d%+d%+d" %
                               (self.window_width, self.window_height,
                                self.window_x, self.window_y))
        else:
            self.window_width = self.screen_width
            self.window_height = self.screen_height
            self.root.attributes('-fullscreen', True)
            os.system(
                'unclutter 1>&- 2>&- &'
            )  # Suppress 'someone created a subwindow' complaints from unclutter
            self.window_x = 0
            self.window_y = 0
            self.root.geometry("%dx%d%+d%+d" %
                               (self.window_width, self.window_height,
                                self.window_x, self.window_y))
            self.root.attributes('-zoomed', '1')

        # canvs cover the whole screen whatever the size of the window.
        self.canvas_height = self.screen_height
        self.canvas_width = self.screen_width

        # make sure focus is set.
        self.root.focus_set()

        # define response to main window closing.
        self.root.protocol("WM_DELETE_WINDOW", self.handle_user_abort)

        # setup a canvas onto which will be drawn the images or text
        self.canvas = Canvas(self.root, bg=self.pp_background)

        if self.options['fullscreen'] is True:
            self.canvas.config(height=self.canvas_height,
                               width=self.canvas_width,
                               highlightthickness=0)
        else:
            self.canvas.config(height=self.canvas_height,
                               width=self.canvas_width,
                               highlightthickness=1,
                               highlightcolor='yellow')

        self.canvas.place(x=0, y=0)
        # self.canvas.config(bg='black')
        self.canvas.focus_set()

        # ****************************************
        # INITIALISE THE INPUT DRIVERS
        # ****************************************

        # each driver takes a set of inputs, binds them to symboic names
        # and sets up a callback which returns the symbolic name when an input event occurs/

        # use keyboard driver to bind keys to symbolic names and to set up callback
        kbd = KbdDriver()
        if kbd.read(pp_dir, self.pp_home, self.pp_profile) is False:
            self.end('error', 'cannot find or error in keys.cfg')
        kbd.bind_keys(self.root, self.handle_input_event)

        self.sr = ScreenDriver()
        # read the screen click area config file
        reason, message = self.sr.read(pp_dir, self.pp_home, self.pp_profile)
        if reason == 'error':
            self.end('error', 'cannot find screen.cfg')

        # create click areas on the canvas, must be polygon as outline rectangles are not filled as far as find_closest goes
        # click areas are made on the Pi Presents canvas not the show canvases.
        reason, message = self.sr.make_click_areas(self.canvas,
                                                   self.handle_input_event)
        if reason == 'error':
            self.mon.err(self, message)
            self.end('error', message)

# ****************************************
# INITIALISE THE APPLICATION AND START
# ****************************************
        self.shutdown_required = False
        self.exitpipresents_required = False

        # kick off GPIO if enabled by command line option
        self.gpio_enabled = False
        if os.path.exists(self.pp_profile + os.sep + 'pp_io_config' + os.sep +
                          'gpio.cfg'):
            # initialise the GPIO
            self.gpiodriver = GPIODriver()
            reason, message = self.gpiodriver.init(pp_dir, self.pp_home,
                                                   self.pp_profile,
                                                   self.canvas, 50,
                                                   self.handle_input_event)
            if reason == 'error':
                self.end('error', message)
            else:
                self.gpio_enabled = True
                # and start polling gpio
                self.gpiodriver.poll()

        # kick off animation sequencer
        self.animate = Animate()
        self.animate.init(pp_dir, self.pp_home, self.pp_profile, self.canvas,
                          200, self.handle_output_event)
        self.animate.poll()

        #create a showmanager ready for time of day scheduler and osc server
        show_id = -1
        self.show_manager = ShowManager(show_id, self.showlist,
                                        self.starter_show, self.root,
                                        self.canvas, self.pp_dir,
                                        self.pp_profile, self.pp_home)
        # first time through set callback to terminate Pi Presents if all shows have ended.
        self.show_manager.init(self.canvas, self.all_shows_ended_callback,
                               self.handle_command, self.showlist)
        # Register all the shows in the showlist
        reason, message = self.show_manager.register_shows()
        if reason == 'error':
            self.mon.err(self, message)
            self.end('error', message)

        # Init OSCDriver, read config and start OSC server
        self.osc_enabled = False
        if os.path.exists(self.pp_profile + os.sep + 'pp_io_config' + os.sep +
                          'osc.cfg'):
            self.oscdriver = OSCDriver()
            reason, message = self.oscdriver.init(
                self.pp_profile, self.handle_command, self.handle_input_event,
                self.e_osc_handle_output_event)
            if reason == 'error':
                self.end('error', message)
            else:
                self.osc_enabled = True
                self.root.after(1000, self.oscdriver.start_server())

        # and run the start shows
        self.run_start_shows()

        # set up the time of day scheduler including catchup
        self.tod_enabled = False
        if os.path.exists(self.pp_profile + os.sep + 'schedule.json'):
            # kick off the time of day scheduler which may run additional shows
            self.tod = TimeOfDay()
            self.tod.init(pp_dir, self.pp_home, self.pp_profile, self.root,
                          self.handle_command)
            self.tod_enabled = True

        # then start the time of day scheduler
        if self.tod_enabled is True:
            self.tod.poll()

        # start Tkinters event loop
        self.root.mainloop()

    def parse_screen(self, size_text):
        fields = size_text.split('*')
        if len(fields) != 2:
            return 'error', 'do not understand --fullscreen comand option', 0, 0
        elif fields[0].isdigit() is False or fields[1].isdigit() is False:
            return 'error', 'dimensions are not positive integers in ---fullscreen', 0, 0
        else:
            return 'normal', '', int(fields[0]), int(fields[1])

# *********************
#  RUN START SHOWS
# ********************

    def run_start_shows(self):
        self.mon.trace(self, 'run start shows')
        # parse the start shows field and start the initial shows
        show_refs = self.starter_show['start-show'].split()
        for show_ref in show_refs:
            reason, message = self.show_manager.control_a_show(
                show_ref, 'open')
            if reason == 'error':
                self.mon.err(self, message)

# *********************
# User inputs
# ********************
# handles one command provided as a line of text

    def handle_command(self, command_text):
        self.mon.log(self, "command received: " + command_text)
        if command_text.strip() == "":
            return

        if command_text[0] == '/':
            if self.osc_enabled is True:
                self.oscdriver.send_command(command_text)
            return

        fields = command_text.split()
        show_command = fields[0]
        if len(fields) > 1:
            show_ref = fields[1]
        else:
            show_ref = ''

        if show_command in ('open', 'close'):
            if self.shutdown_required is False:
                reason, message = self.show_manager.control_a_show(
                    show_ref, show_command)
            else:
                return
        elif show_command == 'exitpipresents':
            self.exitpipresents_required = True
            if self.show_manager.all_shows_exited() is True:
                # need root.after to get out of st thread
                self.root.after(1, self.e_all_shows_ended_callback)
                return
            else:
                reason, message = self.show_manager.exit_all_shows()

        elif show_command == 'shutdownnow':
            # need root.after to get out of st thread
            self.root.after(1, self.e_shutdown_pressed)
            return
        else:
            reason = 'error'
            message = 'command not recognised: ' + show_command

        if reason == 'error':
            self.mon.err(self, message)
        return

    def e_all_shows_ended_callback(self):
        self.all_shows_ended_callback('normal', 'no shows running')

    def e_shutdown_pressed(self):
        self.shutdown_pressed('now')

    def e_osc_handle_output_event(self, line):
        #jump  out of server thread
        self.root.after(1, lambda arg=line: self.osc_handle_output_event(arg))

    def osc_handle_output_event(self, line):
        self.mon.log(self, "output event received: " + line)
        #osc sends output events as a string
        reason, message, delay, name, param_type, param_values = self.animate.parse_animate_fields(
            line)
        if reason == 'error':
            self.mon.err(self, message)
            self.end(reason, message)
        self.handle_output_event(name, param_type, param_values, 0)

    def handle_output_event(self, symbol, param_type, param_values, req_time):
        if self.gpio_enabled is True:
            reason, message = self.gpiodriver.handle_output_event(
                symbol, param_type, param_values, req_time)
            if reason == 'error':
                self.mon.err(self, message)
                self.end(reason, message)
        else:
            self.mon.warn(self, 'GPIO not enabled')

    # all input events call this callback with a symbolic name.
    # handle events that affect PP overall, otherwise pass to all active shows
    def handle_input_event(self, symbol, source):
        self.mon.log(self, "event received: " + symbol + ' from ' + source)
        if symbol == 'pp-terminate':
            self.handle_user_abort()

        elif symbol == 'pp-shutdown':
            self.shutdown_pressed('delay')

        elif symbol == 'pp-shutdownnow':
            # need root.after to grt out of st thread
            self.root.after(1, self.e_shutdown_pressed)
            return

        elif symbol == 'pp-exitpipresents':
            self.exitpipresents_required = True
            if self.show_manager.all_shows_exited() is True:
                # need root.after to grt out of st thread
                self.root.after(1, self.e_all_shows_ended_callback)
                return
            reason, message = self.show_manager.exit_all_shows()
        else:
            # events for shows affect the show and could cause it to exit.
            for show in self.show_manager.shows:
                show_obj = show[ShowManager.SHOW_OBJ]
                if show_obj is not None:
                    show_obj.handle_input_event(symbol)

    def shutdown_pressed(self, when):
        if when == 'delay':
            self.root.after(5000, self.on_shutdown_delay)
        else:
            self.shutdown_required = True
            if self.show_manager.all_shows_exited() is True:
                self.all_shows_ended_callback('normal', 'no shows running')
            else:
                # calls exit method of all shows, results in all_shows_closed_callback
                self.show_manager.exit_all_shows()

    def on_shutdown_delay(self):
        # 5 second delay is up, if shutdown button still pressed then shutdown
        if self.gpiodriver.shutdown_pressed() is True:
            self.shutdown_required = True
            if self.show_manager.all_shows_exited() is True:
                self.all_shows_ended_callback('normal', 'no shows running')
            else:
                # calls exit method of all shows, results in all_shows_closed_callback
                self.show_manager.exit_all_shows()

    def handle_sigterm(self, signum, frame):
        self.mon.log(self, 'SIGTERM received - ' + str(signum))
        self.terminate()

    def handle_user_abort(self):
        self.mon.log(self, 'User abort received')
        self.terminate()

    def terminate(self):
        self.mon.log(self, "terminate received")
        needs_termination = False
        for show in self.show_manager.shows:
            # print  show[ShowManager.SHOW_OBJ], show[ShowManager.SHOW_REF]
            if show[ShowManager.SHOW_OBJ] is not None:
                needs_termination = True
                self.mon.log(
                    self,
                    "Sent terminate to show " + show[ShowManager.SHOW_REF])
                # call shows terminate method
                # eventually the show will exit and after all shows have exited all_shows_callback will be executed.
                show[ShowManager.SHOW_OBJ].terminate()
        if needs_termination is False:
            self.end('killed', 'killed - no termination of shows required')


# ******************************
# Ending Pi Presents after all the showers and players are closed
# **************************

# callback from ShowManager when all shows have ended

    def all_shows_ended_callback(self, reason, message):
        self.canvas.config(bg=self.pp_background)
        if reason in (
                'killed', 'error'
        ) or self.shutdown_required is True or self.exitpipresents_required is True:
            self.end(reason, message)

    def end(self, reason, message):
        self.mon.log(self, "Pi Presents ending with reason: " + reason)
        if self.root is not None:
            self.root.destroy()
        self.tidy_up()
        # gc.collect()
        # print gc.garbage
        if reason == 'killed':
            self.mon.log(self, "Pi Presents Aborted, au revoir")
            # close logging files
            self.mon.finish()
            sys.exit(101)
        elif reason == 'error':
            self.mon.log(self, "Pi Presents closing because of error, sorry")
            # close logging files
            self.mon.finish()
            sys.exit(102)
        else:
            self.mon.log(self, "Pi Presents  exiting normally, bye")
            # close logging files
            self.mon.finish()
            if self.shutdown_required is True:
                # print 'SHUTDOWN'
                call(['sudo', 'shutdown', '-h', '-t 5', 'now'])
                sys.exit(100)
            else:
                sys.exit(100)

    # tidy up all the peripheral bits of Pi Presents
    def tidy_up(self):
        self.mon.log(self, "Tidying Up")
        # turn screen blanking back on
        if self.options['noblank'] is True:
            call(["xset", "s", "on"])
            call(["xset", "s", "+dpms"])

        # tidy up animation and gpio
        if self.animate is not None:
            self.animate.terminate()

        if self.gpio_enabled == True:
            self.gpiodriver.terminate()

        if self.osc_enabled is True:
            self.oscdriver.terminate()

        # tidy up time of day scheduler
        if self.tod_enabled is True:
            self.tod.terminate()
Example #15
0
class GUI:
    def __init__(self):
        self.app = Tk()
        self.app.title('Connect4')
        self.app.resizable(width=False, height=False)
        self.board = Board()
        self.buttons = {}
        self.frame = Frame(self.app, borderwidth=1, relief="raised")
        self.tiles = {}
        for x in range(self.board.width):
            handler = lambda x=x: self.move(x)
            button = Button(self.app,
                            command=handler,
                            font=Font(family="Helvetica", size=14),
                            text=x + 1)
            button.grid(row=0, column=x, sticky="WE")
            self.buttons[x] = button
        self.frame.grid(row=1, column=0, columnspan=self.board.width)
        for x, y in self.board.fields:
            tile = Canvas(self.frame,
                          width=60,
                          height=50,
                          bg="navy",
                          highlightthickness=0)
            tile.grid(row=self.board.height - 1 - y, column=x)
            self.tiles[x, y] = tile
        handler = lambda: self.reset()
        self.restart = Button(self.app, command=handler, text='reset')
        self.restart.grid(row=2,
                          column=0,
                          columnspan=self.board.width,
                          sticky="WE")
        self.update()

    def reset(self):
        self.board = Board()
        self.update()

    def move(self, x):
        self.app.config(cursor="watch")
        self.app.update()
        self.board = self.board.move(x)
        self.update()
        move = self.board.best()
        if move != None:
            self.board = self.board.move(move)
            self.update()
        self.app.config(cursor="")

    def update(self):
        for (x, y) in self.board.fields:
            text = self.board.fields[x, y]
            if (text == '.'):
                self.tiles[x, y].create_oval(10,
                                             5,
                                             50,
                                             45,
                                             fill="black",
                                             outline="blue",
                                             width=1)
            if (text == 'X'):
                self.tiles[x, y].create_oval(10,
                                             5,
                                             50,
                                             45,
                                             fill="yellow",
                                             outline="blue",
                                             width=1)
            if (text == 'O'):
                self.tiles[x, y].create_oval(10,
                                             5,
                                             50,
                                             45,
                                             fill="red",
                                             outline="blue",
                                             width=1)
        for x in range(self.board.width):
            if self.board.fields[x, self.board.height - 1] == self.board.empty:
                self.buttons[x]['state'] = 'normal'
            else:
                self.buttons[x]['state'] = 'disabled'
        winning = self.board.won()
        if winning:
            for x, y in winning:
                self.tiles[x, y].create_oval(25, 20, 35, 30, fill="black")
            for x in range(self.board.width):
                self.buttons[x]['state'] = 'disabled'

    def mainloop(self):
        self.app.mainloop()
Example #16
0
import sys
from Tkinter import Tk
from GUI import *

if __name__ == '__main__':

    root = Tk()
    #WIDTH=int(sys.argv[1])
    #HEIGHT=int(sys.argv[2])
    WIDTH = 500
    HEIGHT = 500
    root.config(height=HEIGHT, width=WIDTH)
    app = NET_GUI(root, WIDTH, HEIGHT)
    #app = GUI(root, sys.argv[1], sys.argv[2])
    app.master.title('NETWORK GRAPHICAL INTERFACE')
    app.master.after(0,
                     app.gui_loop)  #Run ~30FPS (Wich we could do 60... PCMR)
    root.mainloop()
Example #17
0
class PokerMachine():

    """Implements a video poker machine class."""

    def __init__(self):

        """Instance initialization function."""

        # Set up variables

        self.deck = pcards.Deck()
        self.cardimg = []
        self.hand = None

        self.game_start = True
        self.game_postdeal = False
        self.game_easy = True
        self.game_over = False
        self.gifdir = "./images/"

        self.pot = 100
        self.defaultbet = 5
        self.bet = 5

        self._set_up_gui()

    def button_clicked(self):

        """Event handler for button click.

        Callback method called by tk.

        """

        if self.game_over:
            self._start_new_game()
        elif not self.game_postdeal:
            self._process_bet()
        elif self.game_postdeal:
            self._evaluate_hand()

    def flip(self, event):

        """Event handler which flips a clicked card.

        Callback method called by tk.

        """

        if not self.game_postdeal:
            return

        if event.widget.flipped:
            event.widget.flipped = False
            event.widget.configure(image=event.widget.cardimage)
        else:
            event.widget.flipped = True
            event.widget.configure(image=self.backimg)

    def _start_new_game(self):

        """Returns the game an interface to its starting point."""

        for cardimg in self.cardimg:
            cardimg.configure(image=self.backimg)
            cardimg.flipped = True

        self.game_over = False
        self.game_postdeal = False
        self.pot = 100
        self.defaultbet = 5
        self.bet = 5
        self._update_pot()
        self.bet_amt_fld.configure(state=NORMAL)
        self.bet_str.set(str(self.defaultbet))
        self.button.configure(text="Deal")
        self.status_lbl.configure(text="Click 'Deal' to play.")

    def _process_bet(self):

        """Processes the player's bet and deals a new hand
        if the bet is valid.

        """

        # First check if played made a valid bet,
        # and return with no change in state (other
        # than resetting the bet field) if they did
        # not.

        b_str = self.bet_str.get()

        try:
            self.bet = int(b_str)
        except ValueError:
            self._show_bet_error("Bad bet!", "You must bet a whole number!")
            return

        if self.bet > self.pot:
            self._show_bet_error("Don't be greedy!",
                                "You don't have that much money!")
            return
        elif self.bet < 1:
            self._show_bet_error("Don't get clever!",
                                "You must bet a positive whole number!")
            return

        # We have a valid bet, so shuffle the deck
        # and get a new poker hand.

        self.deck.shuffle()
        self.hand = pcards.PokerHand(self.deck)
        self._show_cards()

        # Update game variables and GUI

        self.pot -= self.bet
        self._update_pot()

        self.button.configure(text="Exchange / skip")
        self.status_lbl.configure(text="Choose cards to exchange by " +
                                       "clicking on them.")
        self.bet_amt_fld.configure(state=DISABLED)

        self.game_postdeal = True

    def _evaluate_hand(self):

        """Evalutes a player's hand after any exchanges have
        been made and we have the final hand. Process
        winnings if we have any.

        """

        # Player has flipped their cards if we're here,
        # so figure out which ones they flipped and
        # exchange them and show the new cards.

        xchg_str = ""

        for cardimg in self.cardimg:
            if cardimg.flipped:
                xchg_str += cardimg.pos

        self.hand.exchange(xchg_str)
        self._show_cards()

        # Calculate winnings and show status

        winnings = self.hand.video_winnings(self.bet, easy=self.game_easy)
        win_str = self.hand.show_value() + ". "

        if winnings:
            self.pot += winnings
            win_str += "You won ${0:}!".format(winnings)
            self._update_pot()
        else:
            win_str += "Sorry, no win!"
            if self.pot == 0:
                win_str += " Out of money - game over!"
                self.game_over = True

        self.status_lbl.configure(text=win_str)

        # Update game variables and GUI

        if self.game_over:
            self.button.configure(text="New game")
        else:
            self.button.configure(text="Deal again")
            self.bet_amt_fld.configure(state=NORMAL)

        # Reset the bet amount field with the default bet. Check
        # here to make sure the default bet is not more money that
        # is in the pot, and limit it to that amount if it is.

        self.defaultbet = self.bet if self.bet <= self.pot else self.pot
        self.bet_str.set(str(self.defaultbet))
        self.game_postdeal = False

        # Discard and then drop the current hand

        self.hand.discard()
        self.hand = []

    def _show_bet_error(self, title, message):

        """Shows a message box and resets the bet field
        in response to an invalid bet.

        """

        tkMessageBox.showerror(title, message)
        self.bet = self.defaultbet
        self.bet_str.set(str(self.defaultbet))

    def _update_pot(self):

        """Updates the pot amount label with the current pot."""

        txt_str = "${0:}".format(self.pot)
        self.pot_amt_lbl.configure(text=txt_str)

    def _show_cards(self):

        """Shows the cards in the poker hand on the screen."""

        for cardimg, idx in zip(self.cardimg, self.hand.index_list()):
            cardfile = "{0}{1}.gif".format(self.gifdir, str(idx + 1))
            img = PhotoImage(file=cardfile)
            cardimg.configure(image=img)
            cardimg.cardimage = img
            cardimg.flipped = False

    def _set_up_gui(self):

        """Sets up the Tkinter user interface."""

        # Disable pylint warning for instance attributes defined outside
        # __init__(), since this method is called by __init__()
        #
        # pylint: disable=W0201

        self.root = Tk()
        self.root.title('Video Poker')

        # Set up menubar

        self.menubar = Menu(self.root)

        self.gamemenu = Menu(self.menubar, tearoff=0)
        self.gamemenu.add_command(label="Quit", command=sys.exit)
        self.menubar.add_cascade(label="Game", menu=self.gamemenu)

        self.helpmenu = Menu(self.menubar, tearoff=0)
        self.helpmenu.add_command(label="About", command=self.help_about)
        self.menubar.add_cascade(label="Help", menu=self.helpmenu)

        self.root.config(menu=self.menubar)

        # Set up card images

        self.backimg = PhotoImage(file="{0}b.gif".format(self.gifdir))

        for num in range(5):
            lbl = Label(self.root, image=self.backimg)
            lbl.grid(row=0, column=num, padx=10, pady=10)
            lbl.bind("<Button-1>", self.flip)
            lbl.flipped = True
            lbl.pos = str(num + 1)
            self.cardimg.append(lbl)

        # Set up labels, fields and buttons

        self.pot_lbl = Label(self.root, text="Pot:")
        self.pot_lbl.grid(row=1, column=0,
                          padx=10, pady=2, sticky=W)

        self.pot_amt_lbl = Label(self.root, text="")
        self.pot_amt_lbl.grid(row=1, column=1, columnspan=2,
                              padx=10, pady=2, sticky=W)
        self._update_pot()

        self.bet_lbl = Label(self.root, text="Bet ($):")
        self.bet_lbl.grid(row=2, column=0,
                          padx=10, pady=2, sticky=W)

        self.bet_str = StringVar()
        self.bet_str.set(str(self.defaultbet))

        self.bet_amt_fld = Entry(self.root, textvariable=self.bet_str)
        self.bet_amt_fld.grid(row=2, column=1, columnspan=2,
                              padx=10, pady=2, sticky=W)

        self.button = Button(self.root, text="Deal",
                             command=self.button_clicked)
        self.button.grid(row=1, column=3, rowspan=2, columnspan=2,
                         sticky=W + E + S + N, padx=10)

        self.status_lbl = Label(self.root, bd=1, relief=SUNKEN,
                                text="Welcome to the casino! " +
                                     "Click 'Deal' to play!")
        self.status_lbl.grid(row=3, column=0, columnspan=5,
                             padx=10, pady=10, ipadx=10, ipady=10,
                             sticky=W + E + S + N)

        # Show winnings table

        lbl = Label(self.root, text="Winnings Table", relief=RAISED)
        lbl.grid(row=4, column=1, columnspan=3,
                 pady=15, ipadx=10, ipady=10, sticky=W + E)

        # Two different tables, one for easy mode, one for normal
        # mode, so be prepared to show either one.

        wte = {2500: "Royal Flush", 250: "Straight Flush",
               100: "Four of a Kind", 50: "Full House", 20: "Flush",
               15: "Straight", 4: "Three of a Kind", 3: "Two Pair",
               2: "Jacks or Higher"}
        wtn = {800: "Royal Flush", 50: "Straight Flush", 25: "Four of a Kind",
               9: "Full House", 6: "Flush", 4: "Straight",
               3: "Three of a Kind", 2: "Two Pair", 1: "Jacks or Higher"}
        wtxt = wte if self.game_easy else wtn

        row = 5
        for key in sorted(wtxt.keys(), reverse=True):
            lbl = Label(self.root, text=wtxt[key])
            lbl.grid(row=row, column=1, columnspan=2, sticky=W)
            lbl = Label(self.root, text="{0} : 1".format(key))
            lbl.grid(row=row, column=3, sticky=E)
            row += 1

        lbl = Label(self.root, text="")
        lbl.grid(row=row, column=0, columnspan=5, pady=15)

        # pylint: enable=W0201

    def help_about(self):

        """Shows an 'about' modal dialog.

        Callback method called by tk.

        """

        about_win = Toplevel(self.root)

        # Set up dialog

        lbl = Label(about_win, text="Video Poker")
        lbl.grid(row=0, column=0, padx=10, pady=(10, 0), sticky=W + N)
        lbl = Label(about_win, text="by Paul Griffiths")
        lbl.grid(row=1, column=0, padx=10, pady=(0, 7), sticky=W + N)
        lbl = Label(about_win, text="Written in Python, with tkinter.")
        lbl.grid(row=2, column=0, padx=10, pady=7, sticky=W + N)
        lbl = Label(about_win, text="Copyright 2013 Paul Griffiths")
        lbl.grid(row=4, column=0, padx=10, pady=(7, 0), sticky=W + N)
        lbl = Label(about_win, text="Email: [email protected]")
        lbl.grid(row=5, column=0, padx=10, pady=(0, 21), sticky=W + N)
        lbl = Label(about_win, text="This program is free software: you can " +
            "redistribute it and/or modify it under the terms")
        lbl.grid(row=6, column=0, columnspan=2,
                 padx=10, pady=0, sticky=W + N)
        lbl = Label(about_win, text="of the GNU General Public License as " +
            "published by the Free Software Foundation, either")
        lbl.grid(row=7, column=0, columnspan=2,
                 padx=10, pady=(0, 0), sticky=W + N)
        lbl = Label(about_win, text="version 3 of the License, or " +
            "(at your option) any later version.")
        lbl.grid(row=8, column=0, columnspan=2,
                 padx=10, pady=(0, 21), sticky=W + N)
        lbl = Label(about_win, text="This program is distributed in " +
            "the hope that it will be useful, but WITHOUT ANY WARRANTY;")
        lbl.grid(row=9, column=0, columnspan=2,
                 padx=10, pady=0, sticky=W + N)
        lbl = Label(about_win, text="without even the implied " +
            "warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR")
        lbl.grid(row=10, column=0, columnspan=2,
                 padx=10, pady=(0, 0), sticky=W + N)
        lbl = Label(about_win, text="PURPOSE. See the " +
            "GNU General Public License for more details.")
        lbl.grid(row=11, column=0, columnspan=2,
                 padx=10, pady=(0, 21), sticky=W + N)
        lbl = Label(about_win, text="You should have received a " +
            "copy of the GNU General Public License along with this")
        lbl.grid(row=12, column=0, columnspan=2,
                 padx=10, pady=(0, 0), sticky=W + N)
        lbl = Label(about_win, text="program. If not, see " +
            "<http://www.gnu.org/licenses/>.")
        lbl.grid(row=13, column=0, columnspan=2,
                 padx=10, pady=(0, 21), sticky=W + N)
        img = PhotoImage(file="{0}27.gif".format(self.gifdir))
        lbl = Label(about_win, image=img)
        lbl.grid(row=0, column=1, rowspan=5, padx=10, pady=10, sticky=N + E)

        btn = Button(about_win, text="OK", command=about_win.quit)
        btn.grid(row=14, column=0, columnspan=2,
                 padx=0, pady=(0, 10), ipadx=30, ipady=3)

        # Show dialog

        about_win.transient(self.root)
        about_win.parent = self.root
        about_win.protocol("WM_DELETE_WINDOW", about_win.destroy)
        about_win.geometry("+{0}+{1}".format(self.root.winfo_rootx() + 50,
                                           self.root.winfo_rooty() + 50))
        about_win.title("About Video Poker")
        about_win.focus_set()
        about_win.grab_set()
        about_win.mainloop()
        about_win.destroy()
Example #18
0
class App_Runner:
    """
  App runner that uses a Board and a Palette.
  """
    def __init__(self,
                 on_init,
                 app_name,
                 dev_stage,
                 file_extension,
                 deserializers,
                 board_width,
                 board_height,
                 palette_height,
                 directed_wires,
                 label_tooltips_enabled,
                 same_label_per_connector,
                 init_file=None):
        """
    |on_init|: method called every time a new board of this app's type is
        created.
    |app_name|: name of this app.
    |dev_stage|: development stage of this app.
    |file_extension|: the file extension used for boards of this app's type.
    |deserializers|: drawabel types to open files of this app's type.
    |board_width|, |board_height|: board dimensions.
    |palette_height|: height of palette, width will be the same as board width.
    |directed_wires|: True if the board is to have directed wires, False
        otherwise.
    |label_tooltips_enabled|: if True, show wire and drawable label tooltips.
    |same_label_per_connector|: if True, all wires from a connector will have
        the same label. If False, this will only be true for wire connectors.
    |init_file|: file to open at init time.
    """
        self._on_init = on_init
        self._app_name = app_name
        self._dev_stage = dev_stage
        self._file_extension = file_extension
        self._deserializers = deserializers
        self._board_width = board_width
        self._board_height = board_height
        self._palette_height = palette_height
        self._directed_wires = directed_wires
        self._label_tooltips_enabled = label_tooltips_enabled
        self._same_label_per_connector = same_label_per_connector
        self._init_file = init_file
        self._init()
        self._setup_menu()
        self._setup_shortcuts()

    def _switch_cursor_to_draw(self, *args):
        """
    Switches board cursor state to 'draw'.
    """
        self._draw_display.highlight()
        self._drag_display.unhighlight()
        self.board.set_cursor_state('draw')

    def _switch_cursor_to_drag(self, *args):
        """
    Switches board cursor state to 'drag'.
    """
        self._draw_display.unhighlight()
        self._drag_display.highlight()
        self.board.set_cursor_state('drag')

    def _toggle_cursor(self):
        """
    Toggles board cursor state.
    """
        if self.board.get_cursor_state() == 'draw':
            self._switch_cursor_to_drag()
        else:
            self._switch_cursor_to_draw()

    def _init(self):
        """
    Creates the board and palette.
    """
        self._file_name = None
        self._root = Tk()
        self._root.resizable(0, 0)
        self._menu = Menu(self._root, tearoff=0)
        self.board = Board(
            self._root,
            self._menu,
            width=self._board_width,
            height=self._board_height,
            directed_wires=self._directed_wires,
            label_tooltips_enabled=self._label_tooltips_enabled,
            same_label_per_connector=self._same_label_per_connector,
            on_changed=self._on_changed,
            on_exit=self._request_save)
        self._init_board()
        self.palette = Palette(self._root,
                               self.board,
                               width=self._board_width,
                               height=self._palette_height)
        # buttons to change board cursor state
        self.palette.current_left_x -= PALETTE_PADDING
        self._draw_display = self.palette.add_drawable_type(
            Image_Run_Drawable,
            LEFT,
            self._switch_cursor_to_draw,
            image_file=PENCIL_IMAGE)
        self.palette.current_left_x -= PALETTE_PADDING
        self._drag_display = self.palette.add_drawable_type(
            Image_Run_Drawable,
            LEFT,
            self._switch_cursor_to_drag,
            image_file=HAND_IMAGE)
        self.palette.draw_separator()
        self._switch_cursor_to_draw()

    def _setup_menu(self):
        """
    Creates the menu.
    """
        file_menu = Menu(self._menu, tearoff=0)
        file_menu.add_command(label='New',
                              command=self._new_file,
                              accelerator='Ctrl+N')
        file_menu.add_command(label='Open',
                              command=self._open_file,
                              accelerator='Ctrl+O')
        file_menu.add_command(label='Save',
                              command=self._save_file,
                              accelerator='Ctrl+S')
        file_menu.add_command(label='Save as', command=self._save_as)
        file_menu.add_separator()
        file_menu.add_command(label='Quit',
                              command=self.board.quit,
                              accelerator='Ctrl+Q')
        self._menu.add_cascade(label='File', menu=file_menu)
        edit_menu = Menu(self._menu, tearoff=0)
        edit_menu.add_command(label='Undo',
                              command=self.board.undo,
                              accelerator='Ctrl+Z')
        edit_menu.add_command(label='Redo',
                              command=self.board.redo,
                              accelerator='Ctrl+Y')
        edit_menu.add_command(label='Delete selected',
                              command=self.board._delete_selected_items,
                              accelerator='Delete')
        edit_menu.add_command(label='Rotate selected',
                              command=self.board._rotate_selected_item,
                              accelerator='r')
        edit_menu.add_command(label='Toggle cursor',
                              command=self._toggle_cursor,
                              accelerator='D')
        self._menu.add_cascade(label='Edit', menu=edit_menu)
        self._root.config(menu=self._menu)

    def _setup_shortcuts(self):
        """
    Adds basic shortcuts.
    """
        self.board.parent.bind('<Control-n>', lambda event: self._new_file())
        self.board.parent.bind('<Control-N>', lambda event: self._new_file())
        self.board.parent.bind('<Control-o>', lambda event: self._open_file())
        self.board.parent.bind('<Control-O>', lambda event: self._open_file())
        self.board.parent.bind('<Control-q>', lambda event: self.board.quit())
        self.board.parent.bind('<Control-Q>', lambda event: self.board.quit())
        self.board.parent.bind('<Control-s>', lambda event: self._save_file())
        self.board.parent.bind('<Control-S>', lambda event: self._save_file())
        self.board.parent.bind('<Control-y>', lambda event: self.board.redo())
        self.board.parent.bind('<Control-Y>', lambda event: self.board.redo())
        self.board.parent.bind('<Control-z>', lambda event: self.board.undo())
        self.board.parent.bind('<Control-Z>', lambda event: self.board.undo())
        self.board.add_key_binding('d', self._toggle_cursor)

    def _init_board(self):
        """
    (Re)Initializes the board based on this app's specific needs, as per
        self._on_init.
    """
        self.board.clear()
        self._on_init(self.board)
        self.board.reset()

    def _on_changed(self, board_changed):
        """
    Callback for when the board is changed. Updates the title of the app window
        to indicate whether we need to save the file.
    """
        self._root.title(
            '%s (%s) %s %s' %
            (self._app_name, self._dev_stage, strip_file_name(
                self._file_name), '*' if board_changed else ''))

    def _save_as(self, file_name=None):
        """
    Saves the current state of the app with the given |file_name|.
    """
        saved_file_name = save_board(self.board, file_name, self._app_name,
                                     self._file_extension)
        if saved_file_name:
            self._file_name = saved_file_name
            self.board.set_changed(False)

    def _save_file(self):
        """
    Saves the current state of the app with its current file name (asks for a
        a file path if it currently does not have one).
    """
        self._save_as(self._file_name)

    def _request_save(self):
        """
    Requests for a file save if necessary. Returns True if there isn't anything
        to save or, in the case that there is something to save, if the user
        either decides to save the file (will be presented with a dialog to do
        so) or decides not to save the file. Returns False if the user cancels
        the request for save (i.e. does neither).
    """
        if self.board.changed():
            save = request_save_board()
            if save == 'yes':
                self._save_file()
                return True
            elif save == 'no':
                return True
            else:
                return False
        else:
            return True

    def _open_file(self, new_file_name=None):
        """
    Opens a saved file of this app's type.
    """
        if self._request_save():
            new_file_name = new_file_name or get_board_file_name(
                self._file_name, self._app_name, self._file_extension)
            if open_board_from_file(self.board, new_file_name,
                                    self._deserializers, self._file_extension):
                self._file_name = new_file_name
                self._on_changed(False)
            self.board.reset_cursor_state()

    def _new_file(self):
        """
    Opens a new file of this app's type.
    """
        if self._request_save():
            self._file_name = None
            self._init_board()

    def run(self):
        """
    Runs this app.
    """
        self.board.clear_action_history()
        self._root.title('%s (%s)' % (self._app_name, self._dev_stage))
        if self._init_file:
            self._open_file(self._init_file)
        self._root.mainloop()
Example #19
0
class ConcordanceSearchView(object):
    _BACKGROUND_COLOUR = '#FFF'  #white

    #Colour of highlighted results
    _HIGHLIGHT_WORD_COLOUR = '#F00'  #red
    _HIGHLIGHT_WORD_TAG = 'HL_WRD_TAG'

    _HIGHLIGHT_LABEL_COLOUR = '#C0C0C0'  # dark grey
    _HIGHLIGHT_LABEL_TAG = 'HL_LBL_TAG'

    #Percentage of text left of the scrollbar position
    _FRACTION_LEFT_TEXT = 0.30

    def __init__(self):
        self.model = ConcordanceSearchModel()
        self.model.add_listener(self)
        self.top = Tk()
        self._init_top(self.top)
        self._init_menubar()
        self._init_widgets(self.top)
        self._bind_event_handlers()
        self.load_corpus(self.model.DEFAULT_CORPUS)

    def _init_top(self, top):
        top.geometry('950x680+50+50')
        top.title('NLTK Concordance Search')
        top.bind('<Control-q>', self.destroy)
        top.minsize(950, 680)

    def _init_widgets(self, parent):
        self.main_frame = Frame(
            parent,
            dict(background=self._BACKGROUND_COLOUR, padx=1, pady=1, border=1))
        self._init_corpus_select(self.main_frame)
        self._init_query_box(self.main_frame)
        self._init_results_box(self.main_frame)
        self._init_paging(self.main_frame)
        self._init_status(self.main_frame)
        self.main_frame.pack(fill='both', expand=True)

    def _init_menubar(self):
        self._result_size = IntVar(self.top)
        self._cntx_bf_len = IntVar(self.top)
        self._cntx_af_len = IntVar(self.top)
        menubar = Menu(self.top)

        filemenu = Menu(menubar, tearoff=0, borderwidth=0)
        filemenu.add_command(label='Exit',
                             underline=1,
                             command=self.destroy,
                             accelerator='Ctrl-q')
        menubar.add_cascade(label='File', underline=0, menu=filemenu)

        editmenu = Menu(menubar, tearoff=0)
        rescntmenu = Menu(editmenu, tearoff=0)
        rescntmenu.add_radiobutton(label='20',
                                   variable=self._result_size,
                                   underline=0,
                                   value=20,
                                   command=self.set_result_size)
        rescntmenu.add_radiobutton(label='50',
                                   variable=self._result_size,
                                   underline=0,
                                   value=50,
                                   command=self.set_result_size)
        rescntmenu.add_radiobutton(label='100',
                                   variable=self._result_size,
                                   underline=0,
                                   value=100,
                                   command=self.set_result_size)
        rescntmenu.invoke(1)
        editmenu.add_cascade(label='Result Count',
                             underline=0,
                             menu=rescntmenu)

        cntxmenu = Menu(editmenu, tearoff=0)
        cntxbfmenu = Menu(cntxmenu, tearoff=0)
        cntxbfmenu.add_radiobutton(label='60 characters',
                                   variable=self._cntx_bf_len,
                                   underline=0,
                                   value=60,
                                   command=self.set_cntx_bf_len)
        cntxbfmenu.add_radiobutton(label='80 characters',
                                   variable=self._cntx_bf_len,
                                   underline=0,
                                   value=80,
                                   command=self.set_cntx_bf_len)
        cntxbfmenu.add_radiobutton(label='100 characters',
                                   variable=self._cntx_bf_len,
                                   underline=0,
                                   value=100,
                                   command=self.set_cntx_bf_len)
        cntxbfmenu.invoke(1)
        cntxmenu.add_cascade(label='Before', underline=0, menu=cntxbfmenu)

        cntxafmenu = Menu(cntxmenu, tearoff=0)
        cntxafmenu.add_radiobutton(label='70 characters',
                                   variable=self._cntx_af_len,
                                   underline=0,
                                   value=70,
                                   command=self.set_cntx_af_len)
        cntxafmenu.add_radiobutton(label='90 characters',
                                   variable=self._cntx_af_len,
                                   underline=0,
                                   value=90,
                                   command=self.set_cntx_af_len)
        cntxafmenu.add_radiobutton(label='110 characters',
                                   variable=self._cntx_af_len,
                                   underline=0,
                                   value=110,
                                   command=self.set_cntx_af_len)
        cntxafmenu.invoke(1)
        cntxmenu.add_cascade(label='After', underline=0, menu=cntxafmenu)

        editmenu.add_cascade(label='Context', underline=0, menu=cntxmenu)

        menubar.add_cascade(label='Edit', underline=0, menu=editmenu)

        self.top.config(menu=menubar)

    def set_result_size(self, **kwargs):
        self.model.result_count = self._result_size.get()

    def set_cntx_af_len(self, **kwargs):
        self._char_after = self._cntx_af_len.get()

    def set_cntx_bf_len(self, **kwargs):
        self._char_before = self._cntx_bf_len.get()

    def _init_corpus_select(self, parent):
        innerframe = Frame(parent, background=self._BACKGROUND_COLOUR)
        self.var = StringVar(innerframe)
        self.var.set(self.model.DEFAULT_CORPUS)
        Label(innerframe,
              justify=LEFT,
              text=' Corpus: ',
              background=self._BACKGROUND_COLOUR,
              padx=2,
              pady=1,
              border=0).pack(side='left')

        other_corpora = self.model.CORPORA.keys().remove(
            self.model.DEFAULT_CORPUS)
        om = OptionMenu(innerframe,
                        self.var,
                        self.model.DEFAULT_CORPUS,
                        command=self.corpus_selected,
                        *self.model.non_default_corpora())
        om['borderwidth'] = 0
        om['highlightthickness'] = 1
        om.pack(side='left')
        innerframe.pack(side='top', fill='x', anchor='n')

    def _init_status(self, parent):
        self.status = Label(parent,
                            justify=LEFT,
                            relief=SUNKEN,
                            background=self._BACKGROUND_COLOUR,
                            border=0,
                            padx=1,
                            pady=0)
        self.status.pack(side='top', anchor='sw')

    def _init_query_box(self, parent):
        innerframe = Frame(parent, background=self._BACKGROUND_COLOUR)
        another = Frame(innerframe, background=self._BACKGROUND_COLOUR)
        self.query_box = Entry(another, width=60)
        self.query_box.pack(side='left', fill='x', pady=25, anchor='center')
        self.search_button = Button(another,
                                    text='Search',
                                    command=self.search,
                                    borderwidth=1,
                                    highlightthickness=1)
        self.search_button.pack(side='left',
                                fill='x',
                                pady=25,
                                anchor='center')
        self.query_box.bind('<KeyPress-Return>',
                            self.search_enter_keypress_handler)
        another.pack()
        innerframe.pack(side='top', fill='x', anchor='n')

    def search_enter_keypress_handler(self, *event):
        self.search()

    def _init_results_box(self, parent):
        innerframe = Frame(parent)
        i1 = Frame(innerframe)
        i2 = Frame(innerframe)
        vscrollbar = Scrollbar(i1, borderwidth=1)
        hscrollbar = Scrollbar(i2, borderwidth=1, orient='horiz')
        self.results_box = Text(i1,
                                font=tkFont.Font(family='courier', size='16'),
                                state='disabled',
                                borderwidth=1,
                                yscrollcommand=vscrollbar.set,
                                xscrollcommand=hscrollbar.set,
                                wrap='none',
                                width='40',
                                height='20',
                                exportselection=1)
        self.results_box.pack(side='left', fill='both', expand=True)
        self.results_box.tag_config(self._HIGHLIGHT_WORD_TAG,
                                    foreground=self._HIGHLIGHT_WORD_COLOUR)
        self.results_box.tag_config(self._HIGHLIGHT_LABEL_TAG,
                                    foreground=self._HIGHLIGHT_LABEL_COLOUR)
        vscrollbar.pack(side='left', fill='y', anchor='e')
        vscrollbar.config(command=self.results_box.yview)
        hscrollbar.pack(side='left', fill='x', expand=True, anchor='w')
        hscrollbar.config(command=self.results_box.xview)
        #there is no other way of avoiding the overlap of scrollbars while using pack layout manager!!!
        Label(i2, text='   ',
              background=self._BACKGROUND_COLOUR).pack(side='left', anchor='e')
        i1.pack(side='top', fill='both', expand=True, anchor='n')
        i2.pack(side='bottom', fill='x', anchor='s')
        innerframe.pack(side='top', fill='both', expand=True)

    def _init_paging(self, parent):
        innerframe = Frame(parent, background=self._BACKGROUND_COLOUR)
        self.prev = prev = Button(innerframe,
                                  text='Previous',
                                  command=self.previous,
                                  width='10',
                                  borderwidth=1,
                                  highlightthickness=1,
                                  state='disabled')
        prev.pack(side='left', anchor='center')
        self.next = next = Button(innerframe,
                                  text='Next',
                                  command=self.next,
                                  width='10',
                                  borderwidth=1,
                                  highlightthickness=1,
                                  state='disabled')
        next.pack(side='right', anchor='center')
        innerframe.pack(side='top', fill='y')
        self.current_page = 0

    def previous(self):
        self.clear_results_box()
        self.freeze_editable()
        self.model.prev(self.current_page - 1)

    def next(self):
        self.clear_results_box()
        self.freeze_editable()
        self.model.next(self.current_page + 1)

    def about(self, *e):
        ABOUT = ("NLTK Concordance Search Demo\n")
        TITLE = 'About: NLTK Concordance Search Demo'
        try:
            from tkMessageBox import Message
            Message(message=ABOUT, title=TITLE, parent=self.main_frame).show()
        except:
            ShowText(self.top, TITLE, ABOUT)

    def _bind_event_handlers(self):
        self.top.bind(CORPUS_LOADED_EVENT, self.handle_corpus_loaded)
        self.top.bind(SEARCH_TERMINATED_EVENT, self.handle_search_terminated)
        self.top.bind(SEARCH_ERROR_EVENT, self.handle_search_error)
        self.top.bind(ERROR_LOADING_CORPUS_EVENT,
                      self.handle_error_loading_corpus)

    def handle_error_loading_corpus(self, event):
        self.status['text'] = 'Error in loading ' + self.var.get()
        self.unfreeze_editable()
        self.clear_all()
        self.freeze_editable()

    def handle_corpus_loaded(self, event):
        self.status['text'] = self.var.get() + ' is loaded'
        self.unfreeze_editable()
        self.clear_all()
        self.query_box.focus_set()

    def handle_search_terminated(self, event):
        #todo: refactor the model such that it is less state sensitive
        results = self.model.get_results()
        self.write_results(results)
        self.status['text'] = ''
        if len(results) == 0:
            self.status['text'] = 'No results found for ' + self.model.query
        else:
            self.current_page = self.model.last_requested_page
        self.unfreeze_editable()
        self.results_box.xview_moveto(self._FRACTION_LEFT_TEXT)

    def handle_search_error(self, event):
        self.status['text'] = 'Error in query ' + self.model.query
        self.unfreeze_editable()

    def corpus_selected(self, *args):
        new_selection = self.var.get()
        self.load_corpus(new_selection)

    def load_corpus(self, selection):
        if self.model.selected_corpus != selection:
            self.status['text'] = 'Loading ' + selection + '...'
            self.freeze_editable()
            self.model.load_corpus(selection)

    def search(self):
        self.current_page = 0
        self.clear_results_box()
        self.model.reset_results()
        query = self.query_box.get()
        if (len(query.strip()) == 0): return
        self.status['text'] = 'Searching for ' + query
        self.freeze_editable()
        self.model.search(
            query,
            self.current_page + 1,
        )

    def write_results(self, results):
        self.results_box['state'] = 'normal'
        row = 1
        for each in results:
            sent, pos1, pos2 = each[0].strip(), each[1], each[2]
            if len(sent) != 0:
                if (pos1 < self._char_before):
                    sent, pos1, pos2 = self.pad(sent, pos1, pos2)
                sentence = sent[pos1 - self._char_before:pos1 +
                                self._char_after]
                if not row == len(results):
                    sentence += '\n'
                self.results_box.insert(str(row) + '.0', sentence)
                word_markers, label_markers = self.words_and_labels(
                    sent, pos1, pos2)
                for marker in word_markers:
                    self.results_box.tag_add(self._HIGHLIGHT_WORD_TAG,
                                             str(row) + '.' + str(marker[0]),
                                             str(row) + '.' + str(marker[1]))
                for marker in label_markers:
                    self.results_box.tag_add(self._HIGHLIGHT_LABEL_TAG,
                                             str(row) + '.' + str(marker[0]),
                                             str(row) + '.' + str(marker[1]))
                row += 1
        self.results_box['state'] = 'disabled'

    def words_and_labels(self, sentence, pos1, pos2):
        search_exp = sentence[pos1:pos2]
        words, labels = [], []
        labeled_words = search_exp.split(' ')
        index = 0
        for each in labeled_words:
            if each == '':
                index += 1
            else:
                word, label = each.split('/')
                words.append((self._char_before + index,
                              self._char_before + index + len(word)))
                index += len(word) + 1
                labels.append((self._char_before + index,
                               self._char_before + index + len(label)))
                index += len(label)
            index += 1
        return words, labels

    def pad(self, sent, hstart, hend):
        if hstart >= self._char_before:
            return sent, hstart, hend
        d = self._char_before - hstart
        sent = ''.join([' '] * d) + sent
        return sent, hstart + d, hend + d

    def destroy(self, *e):
        if self.top is None: return
        self.top.destroy()
        self.top = None

    def clear_all(self):
        self.query_box.delete(0, END)
        self.model.reset_query()
        self.clear_results_box()

    def clear_results_box(self):
        self.results_box['state'] = 'normal'
        self.results_box.delete("1.0", END)
        self.results_box['state'] = 'disabled'

    def freeze_editable(self):
        self.query_box['state'] = 'disabled'
        self.search_button['state'] = 'disabled'
        self.prev['state'] = 'disabled'
        self.next['state'] = 'disabled'

    def unfreeze_editable(self):
        self.query_box['state'] = 'normal'
        self.search_button['state'] = 'normal'
        self.set_paging_button_states()

    def set_paging_button_states(self):
        if self.current_page == 0 or self.current_page == 1:
            self.prev['state'] = 'disabled'
        else:
            self.prev['state'] = 'normal'
        if self.model.has_more_pages(self.current_page):
            self.next['state'] = 'normal'
        else:
            self.next['state'] = 'disabled'

    def fire_event(self, event):
        #Firing an event so that rendering of widgets happen in the mainloop thread
        self.top.event_generate(event, when='tail')

    def mainloop(self, *args, **kwargs):
        if in_idle(): return
        self.top.mainloop(*args, **kwargs)
Example #20
0
class MainApp(object):
    """
    The MainApp based on TKinter

    Attributes
    ----------

    root             : Tk
                      The Tk object
    dbfdata          : dictionary
                      The current dbf data
    menubar          : Menu
                      The menu bar
    attibmenu        : Menu
                      The attribute menu
    """
    def __init__(self):
        self.root = Tk()
        self.root.geometry("300x250")
        self.root.title("Shape file Reader")
        self.createMenu()
        self.root.mainloop()

    def createMenu(self):       
        """
        Creates GUI components and register events
        """
        self.menubar = Menu(self.root)
        self.dbfdata = None
        
        filemenu = Menu(self.menubar, tearoff=0)
        filemenu.add_command(label="Open", command=self.__openShpfile)
        filemenu.add_separator()
        filemenu.add_command(label="Exit", command=self.root.quit)
        self.menubar.add_cascade(label="File", menu=filemenu)
        
        self.attibmenu = Menu(self.menubar, tearoff=0)
        self.menubar.add_cascade(label="Attibutes", menu=self.attibmenu,state='disabled')

        #Sagar Jha
        self.menubar.add_cascade(label="Simulator",command=self.__simulate) 
        #Added Simulator 
        
        self.root.config(menu=self.menubar)

    def __simulate(self):
        """
        This function will create object of SimulatorExperimence 
        """
        self.Sim = SimulatorExperimence()
        ## Test to check object type       
        ## print(type(self.Sim))
        self.Sim.doTest()
        
        
    def __openShpfile(self):
        """
        Open a shapefile and read in the contents, pop up the attribute menu 
        with the attributes of the shapefile
        """   
        print "open shape file!"
        directory="C:/Users/sjha1/Documents/GitHub/Simulator_GUI/Python-Sample/data/states/48States.shp"
        #tkFileDialog.askopenfilename(filetypes=[("SHAPE_FILE","*.shp")])
        print directory
        
        if directory == "":
            return
        
        self.shapes, self.shp_type, self.bbox = shp_reader.read_shp(directory)
        #read corresponding dbf data
        dbfFile = dbf.DbfLoader(directory[:-3] + "dbf")
        
        t = dbfFile.table2list()
        varNames = dbfFile.get_field_names()
        variables = {}
        for variable in varNames:
            variables[variable] = [record[varNames.index(variable)] for record in t]
            
        if self.dbfdata!=None:
            self.attibmenu.delete(0, len(self.dbfdata)-1)
            
        #add attributes into menu
        for key in variables.keys():
            self.__addAttribute(key)
        
        self.dbfdata = variables
        self.menubar.entryconfig(2, state=Tkconstants.NORMAL)
        self.__updateCanvas("STATE_NAME")
    
    def __addAttribute(self,attributeName):
        """
        Add an attribute to the menu
        """
        self.attibmenu.add_command(label=attributeName, command=lambda i=attributeName:self.__updateCanvas(i))
        
    def __updateCanvas(self, attributeName):
        """
        Updates the canvas and showing statistical information
        """
        print "update Canvas "+attributeName
        data_list=self.dbfdata[attributeName]
        
        print "attribute values: ", data_list
        try:
            n, min_max, mean, var, skew, kurt = stats.describe(data_list)
            print "============================"
            print "attribute statistics\n"
            print("Number of units: {0:d}".format(n))
            print("Minimum: {0:8.6f} Maximum: {1:8.6f}".format(min_max[0], min_max[1]))
            print("Mean: {0:8.6f}".format(mean))
            print("Standard deviation: {0:8.6f}".format(math.sqrt(var)))
            print("Skew : {0:8.6f}".format(skew))
            print("Kurtosis: {0:8.6f}".format(kurt))
            print "\n============================"
            
            high=max(data_list)
            low=min(data_list)
            dif=float(high-low)
            
            for i in range(len(data_list)):
                #map colors to 0-200, 0-200, 0-200 (avoid pure white for display purpose)
                index=float(data_list[i]-low)/dif*200
                index=str(hex(200-int(index)).split('x')[1])
    
                color="#"+index+index+index    
                self.shapes[i].color=color
        except:
            print "non-numeric attribute"
            
        self.canvas=MainCanvas(self.shapes,self.bbox,self.shp_type,self.root,attributeName,data_list)
Example #21
0
class Troop:
    @classmethod
    def init_troop(cls, name, nation):
        strength = random.randint(1, 3)
        health = random.randint(1, 3)
        ranged = random.choice([False, True]) #Starting troops are always melee random.choice([False, True])

        speed = random.randint(2, 4)

        discipline = random.randint(1, 2)

        rank_size = random.randint(4, 15)
        ranks = random.randint(4, 6)

        elite = random.randint(2, 6)

        if ranged:
            weapons = [random.choice(nation.basic_ranged_weapon_list), random.choice(nation.sidearm_list)]
        else:
            weapons = [random.choice(nation.basic_weapon_list), random.choice(nation.basic_weapon_list)]

        #weapons = [random.choice(nation.ranged_weapon_list), random.choice(nation.sidearm_list)]

        armor = random.choice(nation.basic_armor_list)

        mount = nation.mount_none

        if random.randint(0, 100) < elite + 5:
            mount = random.choice(nation.basic_mount_list)


        tier = 1

        # print "Unknown nation has created a new unit: " + str(name) + ", armed with: " + str(weapons[0].name) +", " + str(weapons[1].name) + ", "+str(armor.name)+", "+str(mount.name)+" elite: "+str(elite)

        return cls(name, strength, health, 0, ranged, speed, discipline, rank_size, ranks, weapons, armor, elite, tier, [], mount, troop_nation=nation)

    def __init__(self, name, strength, health, number, ranged, speed, discipline, rank_size, ranks, weapons, armor, elite, tier, upgrades, mount,
                 stats_history=None, arms_history=None, troop_nation=None):
        if arms_history is None:
            arms_history = []
        if stats_history is None:
            stats_history = []
        self.name = name
        self.strength = strength
        self.health = health
        self.number = number

        self.speed = speed

        self.originally_ranged = ranged #This one won't change when the unit swiches to melee mode.
        self.ranged = ranged

        self.discipline = discipline

        self.rank_size = rank_size
        self.ranks = ranks

        self.weapons = weapons
        self.armor = armor
        self.mount = mount

        self.upgrades = upgrades

        self.elite = elite

        self.tier = tier

        self.nation = troop_nation

        if not arms_history:
            self.arms_history = [(self.weapons, self.armor)]
        else:
            self.arms_history = arms_history

        if not stats_history:
            self.stats_history = [utility.base_soldier_stats()]
        else:
            self.stats_history = stats_history

        self.quality = 0

        if self.nation is not None:
            self.nation.troop_tree.append(self)

        self.experience = 1

    #Creates another troop to add to the troop tree
    @classmethod
    def new_troop(cls, self, nation):
        name = nation.language.make_word(nation.language.name_length, True)

        ranged = random.choice([False, True])

        strength = self.strength + random.randint(1, 10 if not ranged else 5)
        health = self.health + random.randint(1, 4 if not ranged else 2)
        discipline = self.discipline + random.randint(0, 1)

        speed = self.speed + random.randint(1, 2)

        rank_size = random.randint(3, 15)
        ranks = random.randint(3, 5)

        if ranged:
            weapons = [random.choice(nation.ranged_weapon_list), random.choice(nation.sidearm_list)]
        else:
            weapons = [random.choice(nation.weapon_list), random.choice(nation.sidearm_list)]

        armor = random.choice(nation.armor_list)

        mount = nation.mount_none

        elite = random.randint(2, 6)

        if random.randint(0, 100) < (elite * 2) + 5:
            mount = random.choice(nation.mount_list)

        # print str(nation.name) + " created a new unit: " + str(name) + ", armed with: " + str(weapons[0].name) +", " + str(weapons[1].name) + ", "+str(armor.name)+", "+str(mount.name)
        #e.append(events.EventTroopCreated('TroopCreated', {'nation_a': nation.name, 'army_a': name, 'equip_a':weapons, 'armor_a':armor}, s_parent.get_current_date()))

        return cls(name, strength, health, 0, ranged, speed, discipline, rank_size, ranks, weapons, armor, elite, self.tier + 1, [], mount, troop_nation=nation)

    def get_info(self):
        res = {}
        res['name'] = self.name
        res['strength'] = self.strength
        res['health'] = self.health
        res['number'] = self.number
        res['speed'] = self.speed
        res['ranged'] = self.ranged
        res['discipline'] = self.discipline
        res['rank_size'] = self.rank_size
        res['ranks'] = self.ranks
        res['weapons'] = map(lambda eqp: eqp.get_info(), self.weapons)
        res['armor'] = self.armor.get_info()
        res['elite'] = self.elite
        res['tier'] = self.tier
        res['mount'] = self.mount

        res['upgrades'] = []
        for upgrade in self.upgrades:
            res['upgrades'].append(upgrade.get_info())

        res['arms_history'] = []
        for weapons, armor in self.arms_history:
            res['arms_history'].append((map(lambda eqp: eqp.get_info(), weapons), armor.get_info()))

        res['stats_history'] = self.stats_history

        return res

    # TODO: Make these actually do something
    def train(self, amount):
        return 0
        #self.elite += random.randint(0, amount)
        #print self.elite

    def upgrade_gear(self):
        return 0
        # if self.quality > 6:
        #     return

        # self.quality += 1

        # #print "upgrading " + str(self.weapons[0].attack)

        # self.weapons[0].upgrade(1)
        # self.weapons[0].upgrade_skill(1)

        # #Sprint "upgrading to" + str(self.weapons[0].attack)

        # self.weapons[1].upgrade(1)
        # self.weapons[1].upgrade_skill(1)

        # self.armor.upgrade(1)
        # self.armor.upgrade_skill(1)

    def save(self, path):
        with open(path + 'army_structure.txt', 'w') as f:
            f.write(str(self.get_info()))

    def handle_battle_end(self, stats):
        self.stats_history[-1] = utility.zip_dict_with(lambda a,b: a + b, self.stats_history[-1], stats)

    def do_rearm(self, nation):
        if self.tier == 1:
            if self.ranged:
                weapons = [random.choice(nation.basic_ranged_weapon_list), random.choice(nation.sidearm_list)]
            else:
                weapons = [random.choice(nation.basic_weapon_list), random.choice(nation.basic_weapon_list)]

            armor = random.choice(nation.basic_armor_list)

            mount = nation.mount_none

            if random.randint(0, 100) < self.elite + 5:
                mount = random.choice(nation.basic_mount_list)
        else:
            if self.ranged:
                weapons = [random.choice(nation.ranged_weapon_list), random.choice(nation.sidearm_list)]
            else:
                weapons = [random.choice(nation.weapon_list), random.choice(nation.sidearm_list)]

            armor = random.choice(nation.armor_list)

            mount = nation.mount_none

            if random.randint(0, 100) < (self.elite * 2) + 5:
                mount = random.choice(nation.mount_list)

        self.weapons = weapons
        self.armor = armor
        self.mount = mount

        self.arms_history.append((self.weapons, self.armor, self.mount))
        self.stats_history.append(utility.base_soldier_stats())

        return self

    def rearm(self, name, new_weapons, new_armor, new_mount):
        if self.name == name:
            self.weapons = new_weapons
            self.armor = new_armor
            self.mount = new_mount
        else:
            for upgrade in self.upgrades:
                upgrade.rearm(name, new_weapons, new_armor, new_mount)

    def show_information_gui(self):
        self.gui_window = Tk()
        self.gui_window.title(self.name)
        self.gui_window.geometry("400x625+0+0")
        self.gui_window.config(background='white')

        self.ranged_label = gui.Label(self.gui_window, text='Is ranged: {}'.format(self.ranged))
        self.ranged_label.grid(row=0, sticky=W)

        self.mount_label = gui.Label(self.gui_window, text='Mount: {}'.format(self.mount.name))
        self.mount_label.grid(row=1, sticky=W)

        self.strength_label = gui.Label(self.gui_window, text='Strength: {}'.format(self.strength))
        self.strength_label.grid(row=2, sticky=W)

        self.health_label = gui.Label(self.gui_window, text='Health: {}'.format(self.health))
        self.health_label.grid(row=3, sticky=W)

        self.discipline_label = gui.Label(self.gui_window, text='Discipline: {}'.format(self.discipline))
        self.discipline_label.grid(row=4, sticky=W)


        self.discipline_label = gui.Label(self.gui_window, text='Cost: {}'.format(self.get_soldier_cost()))
        self.discipline_label.grid(row=5, sticky=W)

        self.arrangement = gui.Label(self.gui_window, text='Arrangement: {}x{}'.format(self.rank_size, self.ranks))
        self.arrangement.grid(row=6, sticky=W)

        self.arrangement_canvas = Canvas(self.gui_window, width = (self.rank_size + 1) * (TROOP_RADIUS + 1), height= (self.ranks + 1) * (TROOP_RADIUS + 1))
        self.arrangement_canvas.config(background='white')
        self.arrangement_canvas.grid(row=7, sticky=W)

        for x in xrange(1, self.rank_size + 1):
            for y in xrange(1, self.ranks + 1):
                base_x, base_y = x * (TROOP_RADIUS + 1), y * (TROOP_RADIUS + 1)
                self.arrangement_canvas.create_oval(base_x, base_y, base_x + TROOP_RADIUS, base_y + TROOP_RADIUS)

        self.upgrade_label = gui.Label(self.gui_window, text='Upgrades:')
        self.upgrade_label.grid(row=8, sticky=W)

        self.upgrade_buttons = []
        for (i, upgrade) in enumerate(self.upgrades):
            new_upgrade_button = gui.Button(self.gui_window, text=upgrade.name, command=upgrade.show_information_gui)
            new_upgrade_button.grid(row=9, column=i, sticky=W)

            self.upgrade_buttons.append(new_upgrade_button)

        self.history_choice = StringVar()
        self.history_choice.set(self.stringify_history(0))

        self.stats_label = gui.Label(self.gui_window, text='Stats:')
        self.stats_label.grid(row=10, column=0, sticky=W)

        self.stats_choice = OptionMenu(self.gui_window, self.history_choice, *map(self.stringify_history, range(len(self.arms_history))))
        self.stats_choice.config(background='white')
        self.stats_choice['menu'].config(background='white')
        self.stats_choice.grid(row=10, column=1, sticky=W)

        self.stats_select = gui.Button(self.gui_window, text='Select', command=self.select_history)
        self.stats_select.grid(row=10, column=2, sticky=W)

        self.stats_display = Listbox(self.gui_window)
        self.stats_display.grid(row=11, column=0, columnspan=3, sticky=W+E)

        self.select_history()

    def get_soldier_cost(self):
        amount = 0
        for weapon in self.weapons:
            amount += weapon.cost

        amount += self.armor.cost
        amount += self.mount.cost

        return amount

    def stringify_history(self, i):
        weapon_str = ', '.join(map(lambda i: i.name, self.arms_history[i][0]))
        armor_str = self.arms_history[i][1].name
        mount_str = self.mount.name
        return '{}: ({}, {}), {}'.format(i, weapon_str, armor_str, mount_str)

    def select_history(self):
        history_index = int(self.history_choice.get().split(':')[0])

        self.stats_display.delete(0, END)
        for stat in self.stats_history[history_index]:
            self.stats_display.insert(END, '{}: {}'.format(utility.displayify_text(stat), self.stats_history[history_index][stat]))

    def add_number(self, number, nation):
        self.number += number
        #e.append(events.EventArmyRaised('ArmyRaised', {'nation_a': nation.name, 'army_a': self.name, 'raised_a':number}, s_parent.get_current_date()))

        if self.number > self.elite** math.sqrt(self.tier): #If we have enough troops, we will create another, better, rank of troops
            if len(self.upgrades) < 3:
                self.upgrades.append(Troop.new_troop(self, nation))

                self.upgrades[-1].upgrades = [] #Because it wants to put itself as an upgrade, for some reason. TODO

        if self.number < 0:
            self.number = 0

        #Upgrade troops if possible.
        if self.number > (self.elite * self.tier) and len(self.upgrades) > 0:
            upgrading = random.randint(1, self.number // self.elite)
            self.number -= upgrading

            per_upgrade = upgrading // len(self.upgrades)
            for upgrade in self.upgrades:
                total_cost = nation.get_soldier_cost(upgrade)

                if nation.money > total_cost:
                    upgrade.add_number(per_upgrade, nation)
                    #print str(nation.name) + " raised an army of " + str(number) + " " + str(self.name)
                else:
                    self.number += per_upgrade #Add these people back, because they weren't actually upgraded.

        nation.update_tree(self)

        return self

    def reset(self):
        return self.zero().reset_stats()

    def reset_stats(self):
        self.stats_history = [utility.base_soldier_stats()]

        return self

    def zero(self):
        return self.copy().remove_number('', self.size())

    def add_army(self, other):
        self.add_to(other.name, other.number)

        for i in other.upgrades:
            self.add_army(i)

    def add_to(self, type, number):
        if self.name == type:
            self.number += number

            return self
        else:
            for upgrade in self.upgrades:
                if upgrade.name == type:
                    upgrade.number += number

                    return self

            for upgrade in self.upgrades:
                val = upgrade.add_to(type, number)

                if val is not None:
                    return self

            return None

    #Returns a list of the unit + it's upgrades
    def make_upgrade_list(self):
        return sorted([self] + reduce(lambda a, b: a + b, [i.make_upgrade_list() for i in self.upgrades], []), key=lambda a: a.strength * a.health)

    def copy(self):
        return Troop(self.name, self.strength, self.health, 0, self.ranged, self.speed, self.discipline, self.rank_size, self.ranks, [i.copy() for i in self.weapons], self.armor.copy(), self.elite, self.tier, map(lambda i: i.copy(), self.upgrades), self.mount, stats_history=map(dict, self.stats_history), arms_history=list(self.arms_history))

    def is_empty(self):
        return all(map(lambda i: i.is_empty(), self.upgrades)) and self.number == 0

    def trim_empty(self):
        i = 0
        while i < len(self.upgrades):
            if self.upgrades[i].is_empty():
                self.upgrades.pop(i)
            else:
                self.upgrades[i] = self.upgrades[i].trim_empty()

                i += 1

        return self

    def take_number(self, number):
        upgrade_list = self.make_upgrade_list()

        result = self.copy()

        for upgrade in upgrade_list:
            upgraded_amount = 0

            if upgrade.number > number:
                upgrade.number -= number
                upgraded_amount = number

                number = 0
            else:
                upgraded_amount = upgrade.number
                number -= upgrade.number

                upgrade.number = 0

            result.add_to(upgrade.name, upgraded_amount)

            if number == 0:
                break

        return result.trim_empty()

    def remove_number(self, type, number):
        if type == '':
            upgrade_list = self.make_upgrade_list()

            for upgrade in upgrade_list:
                if upgrade.number > number:
                    upgrade.number -= number

                    number = 0

                    return self
                else:
                    number -= upgrade.number

                    upgrade.number = 0

            return self
        else:
            if type == self.name:
                self.number -= number

                return self.number

            for i in self.upgrades:
                if i.name == type:
                    i.number -= number

                    return i.number

            #If not found in any of them, let's check all the children
            for i in self.upgrades:
                val = i.remove_number(type, number)

                if val >= 0:
                    return val

            return -1

    def size(self):
        return self.number + sum(map(lambda t: t.size(), self.upgrades))

    def merge_all(self, other):
        if self.name == other.name:
            self.number += other.number

            for index, upgrade in enumerate(other.upgrades):
                if not upgrade in self.upgrades:
                    self.upgrades.append(upgrade.copy())

                    self.upgrades[-1] = self.upgrades[-1].merge_all(upgrade)
                else:
                    self_upgrade = self.upgrades.index(upgrade)

                    self.upgrades[self_upgrade] = self.upgrades[self_upgrade].merge_all(upgrade)

            return self

    def merge_structure(self, other):
        result = self.zero()

        if result.name == other.name:
            for index, upgrade in enumerate(other.upgrades):
                if not upgrade in result.upgrades:
                    result.upgrades.append(upgrade.zero())

                    result.upgrades[-1] = result.upgrades[-1].merge_structure(upgrade)
                else:
                    self_upgrade = self.upgrades.index(upgrade)

                    result.upgrades[self_upgrade] = result.upgrades[self_upgrade].merge_structure(upgrade)

        return result

    def __eq__(self, other):
        try:
            return self.name == other.name
        except:
            return False

    def __repr__(self):
        return "{0}({1}, {2}): {3} {4}".format(self.name, self.strength, self.health, self.number, self.upgrades)
Example #22
0
class Juego:

    # Declarar el constructor de la clase Juego.
    def __init__(self):
        self.app = Tk()
        self.app.title('# Gatito #')
        self.app.resizable(width=True, height=True)
        self.tablero = Tablero()
        self.font = Font(family="Roboto", size=34)
        self.botones = {}
        # Ciclo para crear los objetos botón para posteriormente asignarlos en el Juego.
        for x, y in self.tablero.casillas:
            manejador = lambda x=x, y=y: self.movimiento(x, y)
            boton = Button(self.app,
                           command=manejador,
                           font=self.font,
                           width=2,
                           height=1)
            boton.grid(row=y, column=x)
            self.botones[x, y] = boton
        manejador = lambda: self.reiniciar()
        boton = Button(self.app, text='Reiniciar', command=manejador)
        boton.grid(row=self.tablero.size + 1,
                   column=0,
                   columnspan=self.tablero.size,
                   sticky="WE")
        self.actualizar()

    # Declarar el método Reiniciar que será asignada al botón Reiniciar en el Juego.
    def reiniciar(self):
        self.tablero = Tablero()
        self.actualizar()

    # Declarar la función movimiento que revisará los click's realizados por el usuario y los movimientos realizados por el oponente (IA).
    def movimiento(self, x, y):
        self.app.config(cursor="watch")
        self.app.update()
        self.tablero = self.tablero.movimiento(x, y)
        self.actualizar()
        movimiento = self.tablero.mejor()
        # Si se detecta un movimiento en el Juego, entonces el oponente realizara el siguiente movimiento en base al árbol creado en _minimax.
        # Después ejecutara el método actualizar y regresara el cursor al jugador para el siguiente movimiento.
        if movimiento:
            self.tablero = self.tablero.movimiento(*movimiento)
            self.actualizar()
        self.app.config(cursor="")

    # Declarar el método Actualizar que realizará
    def actualizar(self):
        #
        for (x, y) in self.tablero.casillas:
            text = self.tablero.casillas[x, y]
            self.botones[x, y]['text'] = text
            self.botones[x, y]['disabledforeground'] = 'black'
            #
            if text == self.tablero.vacio:
                self.botones[x, y]['state'] = 'normal'
            else:
                self.botones[x, y]['state'] = 'disabled'
        ganando = self.tablero.ganador()
        #
        if ganando:
            for x, y in ganando:
                self.botones[x, y]['disabledforeground'] = 'red'
            for x, y in self.botones:
                self.botones[x, y]['state'] = 'disabled'
        for (x, y) in self.tablero.casillas:
            self.botones[x, y].update()

    # Declarar el método Principal donde se inicializa el objeto app.
    def principal(self):
        self.app.mainloop()
Example #23
0
class Display:
    def __init__(self, controller):
        # initialize the GUI
        self.app = Tk()
        self.app.title('Tic Tac Toe')
        self.app.resizable(width=False, height=False)
        self.game_controller = controller   # interface to the game

        self.winner = None  # who has won the game

        # make the board
        self.buttons = [[None for i in range(SIZE)] for j in range(SIZE)]
        for x in range(SIZE):
            for y in range(SIZE):
                handler = lambda x=x, y=y: self.move(x,y)   # each button corresponds to making a move in that square
                self.buttons[x][y] = self.make_button(text='', command=handler, row=y, column=x+SIZE, width=1)
        
        # button to reset the board
        self.make_button(text='New Game', command=lambda:self.reset(), row=SIZE+1, column=SIZE)
        # button that makes the machine learn
        self.make_button(text='Learn', command=lambda:self.learn(), row=SIZE+1, column=SIZE+SIZE/2)
        # button that causes the machine to forget how to play
        self.make_button(text='Forget', command=lambda:self.forget(), row=SIZE+1, column=2*SIZE-1)

        self.update()

        # the score labels
        score = Label(self.app, text=' SCORE:', font=Font(family="Courier", weight='bold', size=32))
        score.grid(row=0, column=0, columnspan=SIZE)
        self.score = Label(self.app, text='0', font=Font(family="Courier", weight='bold', size=32))
        self.score.grid(row=1, column=1)

        # choose if you are X or O. X always goes first
        self.player_choice = StringVar()    # how to keep track of the option
        which_player = OptionMenu(self.app, self.player_choice, *(STRINGS[X], STRINGS[O])) # options are X and O
        which_player.grid(row=SIZE+2, column=SIZE+2)
        which_player.config(font=Font(family='Courier'))
        self.player_choice.set('X')
        self.player_choice.trace('w', self.choose_player)

        # choose between playing against a Perfect player or Learning player
        self.comp_type = StringVar()    # how to keep track of the option
        comp_type = OptionMenu(self.app, self.comp_type, *('Learning', 'Perfect'))
        comp_type.grid(row=SIZE+2, column=SIZE)
        comp_type.config(width=11, font=Font(family='Courier'))
        self.comp_type.set('Learning')
        self.comp_type.trace('w', self.choose_comp_type)

    def mainloop(self):
        self.app.mainloop()

    # make a new button
    def make_button(self, text, command, row, column, width=None):
        if width: button = Button(self.app, text=text, command=command, width=width, font=Font(family="Courier"))
        else: button = Button(self.app, text=text, command=command, font=Font(family="Courier"))
        button.grid(row=row, column=column, columnspan=1)
        return button

    # choose if you will be X or O player
    def choose_player(self, *args):
        if hasattr(self, 'prev_player'):    # only returns false first time
            if self.player_choice.get() != self.prev_player:    # only do something if the choice has changed
                self.prev_player = self.player_choice.get()     # get the choice

                self.game_controller.set_player(self.prev_player)   # set the player
                self.reset()    # new game. Can't switch player mid game

        else:
            self.prev_player = self.player_choice.get() # get the choice

            if self.prev_player == STRINGS[O]:  # this is the first time so only has changed if it switched to O
                self.game_controller.set_player(self.prev_player)
                self.reset()

    # choose between playing against a perfect player or learning player
    def choose_comp_type(self, *args):
        if hasattr(self, 'prev_comp_type'):     # only returns falls first time
            if self.comp_type.get() != self.prev_comp_type:     # only do something if the choice has changed
                self.prev_comp_type = self.comp_type.get()      # get the choice

                self.game_controller.set_comp_type(self.prev_comp_type)     # set the type

        else:
            self.prev_comp_type = self.comp_type.get()  # get the choice

            if self.prev_comp_type == 'Perfect':    # this is the first time so only has changed if it switched to perfect
                self.game_controller.set_comp_type(self.prev_comp_type)

    def forget(self):
        self.game_controller.forget()

    def learn(self):
        self.game_controller.learn()
     
    def reset(self):
        # clear the winner textbox if there is one
        if self.winner != None:
            self.winner.destroy()
            self.winner = None

        # reenable the board
        for x in range(SIZE):
            for y in range(SIZE):
                self.buttons[x][y]['state'] = 'normal'

        self.game_controller.reset()

        self.update()
    
    # make a move and update the display
    def move(self,x,y):
        self.game_controller.make_move(x,y)

        self.update_button(x, y)
        self.app.config(cursor="")

    # update all the buttons to reflect the game state
    def update(self):
        for x in range(SIZE):
            for y in range(SIZE):
                self.update_button(x, y)

    # update a single button
    def update_button(self, x, y):
        # convert the board position value to a string
        text = STRINGS[self.game_controller.get_position(x, y)]
        self.buttons[x][y]['text'] = text

    # game has ended. disable the board and display the results
    def game_over(self, winner):
        # disable the board
        for x in range(SIZE):
            for y in range(SIZE):
                self.buttons[x][y]['state'] = 'disabled'

        # update the score
        score = int(self.score['text'])

        # display the result of the game
        if winner == X:
            winner_str = '1'
            score += 2
        elif winner == O:
            winner_str = '2'
            score -= 2

        if winner == None:
            self.winner = Label(self.app, text="TIE", font=Font(family="Courier", weight='bold', size=32))
            score -= 1
        else:
            text = 'Player', winner_str, 'Wins!'
            self.winner = Label(self.app, text=text, font=Font(family="Courier", weight='bold', size=32))

        self.winner.grid(row=1, column=3*SIZE, columnspan=SIZE, sticky="WE")

        # display the score
        self.score['text'] = str(score)
class PiPresents(object):

    def __init__(self):
        gc.set_debug(gc.DEBUG_UNCOLLECTABLE|gc.DEBUG_INSTANCES|gc.DEBUG_OBJECTS|gc.DEBUG_SAVEALL)
        self.pipresents_issue="1.3"
        self.pipresents_minorissue = '1.3.1g'
        # position and size of window without -f command line option
        self.nonfull_window_width = 0.45 # proportion of width
        self.nonfull_window_height= 0.7 # proportion of height
        self.nonfull_window_x = 0 # position of top left corner
        self.nonfull_window_y=0   # position of top left corner
        self.pp_background='black'

        StopWatch.global_enable=False

        # set up the handler for SIGTERM
        signal.signal(signal.SIGTERM,self.handle_sigterm)
        

# ****************************************
# Initialisation
# ***************************************
        # get command line options
        self.options=command_options()

        # get Pi Presents code directory
        pp_dir=sys.path[0]
        self.pp_dir=pp_dir
        
        if not os.path.exists(pp_dir+"/pipresents.py"):
            if self.options['manager']  is False:
                tkMessageBox.showwarning("Pi Presents","Bad Application Directory:\n{0}".format(pp_dir))
            exit(103)

        
        # Initialise logging and tracing
        Monitor.log_path=pp_dir
        self.mon=Monitor()
        # Init in PiPresents only
        self.mon.init()

        # uncomment to enable control of logging from within a class
        # Monitor.enable_in_code = True # enables control of log level in the code for a class  - self.mon.set_log_level()
        
        # make a shorter list to log/trace only some classes without using enable_in_code.
        Monitor.classes  = ['PiPresents', 'pp_paths',
                            
                            'HyperlinkShow','RadioButtonShow','ArtLiveShow','ArtMediaShow','MediaShow','LiveShow','MenuShow',
                            'PathManager','ControlsManager','ShowManager','PluginManager',
                            'MplayerDriver','OMXDriver','UZBLDriver',
                            'KbdDriver','GPIODriver','TimeOfDay','ScreenDriver','Animate','OSCDriver'
                            ]

        # Monitor.classes=['PiPresents','ArtMediaShow','VideoPlayer','OMXDriver']
        
        # get global log level from command line
        Monitor.log_level = int(self.options['debug'])
        Monitor.manager = self.options['manager']
        # print self.options['manager']
        self.mon.newline(3)    
        self.mon.log (self, "Pi Presents is starting, Version:"+self.pipresents_minorissue)
        # self.mon.log (self," OS and separator:" + os.name +'  ' + os.sep)
        self.mon.log(self,"sys.path[0] -  location of code: "+sys.path[0])
        if os.geteuid() !=0:
            user=os.getenv('USER')
        else:
            user = os.getenv('SUDO_USER')
        self.mon.log(self,'User is: '+ user)
        # self.mon.log(self,"os.getenv('HOME') -  user home directory (not used): " + os.getenv('HOME')) # does not work
        # self.mon.log(self,"os.path.expanduser('~') -  user home directory: " + os.path.expanduser('~'))   # does not work

        # optional other classes used
        self.root=None
        self.ppio=None
        self.tod=None
        self.animate=None
        self.gpiodriver=None
        self.oscdriver=None
        self.osc_enabled=False
        self.gpio_enabled=False
        self.tod_enabled=False
         
        # get home path from -o option
        self.pp_home = pp_paths.get_home(self.options['home'])
        if self.pp_home is None:
            self.end('error','Failed to find pp_home')

        # get profile path from -p option
        # pp_profile is the full path to the directory that contains 
        # pp_showlist.json and other files for the profile
        self.pp_profile = pp_paths.get_profile_dir(self.pp_home, self.options['profile'])
        if self.pp_profile is None:
            self.end('error','Failed to find profile')

        # check profile exists
        if os.path.exists(self.pp_profile):
            self.mon.log(self,"Found Requested profile - pp_profile directory is: " + self.pp_profile)
        else:
            self.mon.err(self,"Failed to find requested profile: "+ self.pp_profile)
            self.end('error','Failed to find profile')

        self.mon.start_stats(self.options['profile'])
        
        # check 'verify' option
        if self.options['verify'] is True:
            val =Validator()
            if  val.validate_profile(None,pp_dir,self.pp_home,self.pp_profile,self.pipresents_issue,False) is  False:
                self.mon.err(self,"Validation Failed")
                self.end('error','Validation Failed')

        # initialise and read the showlist in the profile
        self.showlist=ShowList()
        self.showlist_file= self.pp_profile+ "/pp_showlist.json"
        if os.path.exists(self.showlist_file):
            self.showlist.open_json(self.showlist_file)
        else:
            self.mon.err(self,"showlist not found at "+self.showlist_file)
            self.end('error','showlist not found')

        # check profile and Pi Presents issues are compatible
        if float(self.showlist.sissue()) != float(self.pipresents_issue):
            self.mon.err(self,"Version of profile " + self.showlist.sissue() + " is not  same as Pi Presents, must exit")
            self.end('error','wrong version of profile')


        # get the 'start' show from the showlist
        index = self.showlist.index_of_show('start')
        if index >=0:
            self.showlist.select(index)
            self.starter_show=self.showlist.selected_show()
        else:
            self.mon.err(self,"Show [start] not found in showlist")
            self.end('error','start show not found')

        if self.starter_show['start-show']=='':
             self.mon.warn(self,"No Start Shows in Start Show")       

# ********************
# SET UP THE GUI
# ********************
        # turn off the screenblanking and saver
        if self.options['noblank'] is True:
            call(["xset","s", "off"])
            call(["xset","s", "-dpms"])

        self.root=Tk()   
       
        self.title='Pi Presents - '+ self.pp_profile
        self.icon_text= 'Pi Presents'
        self.root.title(self.title)
        self.root.iconname(self.icon_text)
        self.root.config(bg=self.pp_background)

        self.mon.log(self, 'native screen dimensions are ' + str(self.root.winfo_screenwidth()) + ' x ' + str(self.root.winfo_screenheight()) + ' pixcels')
        if self.options['screensize'] =='':        
            self.screen_width = self.root.winfo_screenwidth()
            self.screen_height = self.root.winfo_screenheight()
        else:
            reason,message,self.screen_width,self.screen_height=self.parse_screen(self.options['screensize'])
            if reason =='error':
                self.mon.err(self,message)
                self.end('error',message)

        self.mon.log(self, 'commanded screen dimensions are ' + str(self.screen_width) + ' x ' + str(self.screen_height) + ' pixcels')
       
        # set window dimensions and decorations
        if self.options['fullscreen'] is False:
            self.window_width=int(self.root.winfo_screenwidth()*self.nonfull_window_width)
            self.window_height=int(self.root.winfo_screenheight()*self.nonfull_window_height)
            self.window_x=self.nonfull_window_x
            self.window_y=self.nonfull_window_y
            self.root.geometry("%dx%d%+d%+d" % (self.window_width,self.window_height,self.window_x,self.window_y))
        else:
            self.window_width=self.screen_width
            self.window_height=self.screen_height
            self.root.attributes('-fullscreen', True)
            os.system('unclutter 1>&- 2>&- &') # Suppress 'someone created a subwindow' complaints from unclutter
            self.window_x=0
            self.window_y=0  
            self.root.geometry("%dx%d%+d%+d"  % (self.window_width,self.window_height,self.window_x,self.window_y))
            self.root.attributes('-zoomed','1')

        # canvs cover the whole screen whatever the size of the window. 
        self.canvas_height=self.screen_height
        self.canvas_width=self.screen_width
  
        # make sure focus is set.
        self.root.focus_set()

        # define response to main window closing.
        self.root.protocol ("WM_DELETE_WINDOW", self.handle_user_abort)

        # setup a canvas onto which will be drawn the images or text
        self.canvas = Canvas(self.root, bg=self.pp_background)


        if self.options['fullscreen'] is True:
            self.canvas.config(height=self.canvas_height,
                               width=self.canvas_width,
                               highlightthickness=0)
        else:
            self.canvas.config(height=self.canvas_height,
                    width=self.canvas_width,
                        highlightthickness=1,
                               highlightcolor='yellow')
            
        self.canvas.place(x=0,y=0)
        # self.canvas.config(bg='black')
        self.canvas.focus_set()


                
# ****************************************
# INITIALISE THE INPUT DRIVERS
# ****************************************

        # each driver takes a set of inputs, binds them to symboic names
        # and sets up a callback which returns the symbolic name when an input event occurs/

        # use keyboard driver to bind keys to symbolic names and to set up callback
        kbd=KbdDriver()
        if kbd.read(pp_dir,self.pp_home,self.pp_profile) is False:
            self.end('error','cannot find or error in keys.cfg')
        kbd.bind_keys(self.root,self.handle_input_event)

        self.sr=ScreenDriver()
        # read the screen click area config file
        reason,message = self.sr.read(pp_dir,self.pp_home,self.pp_profile)
        if reason == 'error':
            self.end('error','cannot find screen.cfg')


        # create click areas on the canvas, must be polygon as outline rectangles are not filled as far as find_closest goes
        # click areas are made on the Pi Presents canvas not the show canvases.
        reason,message = self.sr.make_click_areas(self.canvas,self.handle_input_event)
        if reason == 'error':
            self.mon.err(self,message)
            self.end('error',message)


# ****************************************
# INITIALISE THE APPLICATION AND START
# ****************************************
        self.shutdown_required=False
        self.exitpipresents_required=False
        
        # kick off GPIO if enabled by command line option
        self.gpio_enabled=False
        if os.path.exists(self.pp_profile + os.sep + 'pp_io_config'+os.sep+ 'gpio.cfg'):
            # initialise the GPIO
            self.gpiodriver=GPIODriver()
            reason,message=self.gpiodriver.init(pp_dir,self.pp_home,self.pp_profile,self.canvas,50,self.handle_input_event)
            if reason == 'error':
                self.end('error',message)
            else:
                self.gpio_enabled=True
                # and start polling gpio
                self.gpiodriver.poll()
            
        # kick off animation sequencer
        self.animate = Animate()
        self.animate.init(pp_dir,self.pp_home,self.pp_profile,self.canvas,200,self.handle_output_event)
        self.animate.poll()

        #create a showmanager ready for time of day scheduler and osc server
        show_id=-1
        self.show_manager=ShowManager(show_id,self.showlist,self.starter_show,self.root,self.canvas,self.pp_dir,self.pp_profile,self.pp_home)
        # first time through set callback to terminate Pi Presents if all shows have ended.
        self.show_manager.init(self.canvas,self.all_shows_ended_callback,self.handle_command,self.showlist)
        # Register all the shows in the showlist
        reason,message=self.show_manager.register_shows()
        if reason == 'error':
            self.mon.err(self,message)
            self.end('error',message)

        # Init OSCDriver, read config and start OSC server
        self.osc_enabled=False
        if os.path.exists(self.pp_profile + os.sep + 'pp_io_config'+ os.sep + 'osc.cfg'):
            self.oscdriver=OSCDriver()
            reason,message=self.oscdriver.init(self.pp_profile,self.handle_command,self.handle_input_event,self.e_osc_handle_output_event)
            if reason == 'error':
                self.end('error',message)
            else:
                self.osc_enabled=True
                self.root.after(1000,self.oscdriver.start_server())

        # and run the start shows
        self.run_start_shows()

       # set up the time of day scheduler including catchup         
        self.tod_enabled=False
        if os.path.exists(self.pp_profile + os.sep + 'schedule.json'):
            # kick off the time of day scheduler which may run additional shows
            self.tod=TimeOfDay()
            self.tod.init(pp_dir,self.pp_home,self.pp_profile,self.root,self.handle_command)
            self.tod_enabled = True


        # then start the time of day scheduler
        if self.tod_enabled is True:
            self.tod.poll()

        # start Tkinters event loop
        self.root.mainloop( )


    def parse_screen(self,size_text):
        fields=size_text.split('*')
        if len(fields)!=2:
            return 'error','do not understand --fullscreen comand option',0,0
        elif fields[0].isdigit()  is False or fields[1].isdigit()  is False:
            return 'error','dimensions are not positive integers in ---fullscreen',0,0
        else:
            return 'normal','',int(fields[0]),int(fields[1])
        

# *********************
#  RUN START SHOWS
# ********************   
    def run_start_shows(self):
        self.mon.trace(self,'run start shows')
        # parse the start shows field and start the initial shows       
        show_refs=self.starter_show['start-show'].split()
        for show_ref in show_refs:
            reason,message=self.show_manager.control_a_show(show_ref,'open')
            if reason == 'error':
                self.mon.err(self,message)
                


# *********************
# User inputs
# ********************
    # handles one command provided as a line of text
    def handle_command(self,command_text):
        self.mon.log(self,"command received: " + command_text)
        if command_text.strip()=="":
            return

        if command_text[0]=='/': 
            if self.osc_enabled is True:
                self.oscdriver.send_command(command_text)
            return
        
        fields= command_text.split()
        show_command=fields[0]
        if len(fields)>1:
            show_ref=fields[1]
        else:
            show_ref=''
            
        if show_command in ('open','close'):
            if self.shutdown_required is False:
                reason,message=self.show_manager.control_a_show(show_ref,show_command)
            else:
                return
        elif show_command == 'exitpipresents':
            self.exitpipresents_required=True
            if self.show_manager.all_shows_exited() is True:
                # need root.after to get out of st thread
                self.root.after(1,self.e_all_shows_ended_callback)
                return
            else:
                reason,message= self.show_manager.exit_all_shows()

        elif show_command == 'shutdownnow':
            # need root.after to get out of st thread
            self.root.after(1,self.e_shutdown_pressed)
            return
        else:
            reason='error'
            message = 'command not recognised: '+ show_command
            
        if reason=='error':
            self.mon.err(self,message)
        return

    def e_all_shows_ended_callback(self):
            self.all_shows_ended_callback('normal','no shows running')

    def e_shutdown_pressed(self):
            self.shutdown_pressed('now')


    def e_osc_handle_output_event(self,line):
        #jump  out of server thread
        self.root.after(1, lambda arg=line: self.osc_handle_output_event(arg))

    def  osc_handle_output_event(self,line):
        self.mon.log(self,"output event received: "+ line)
        #osc sends output events as a string
        reason,message,delay,name,param_type,param_values=self.animate.parse_animate_fields(line)
        if reason == 'error':
            self.mon.err(self,message)
            self.end(reason,message)
        self.handle_output_event(name,param_type,param_values,0)

               
    def handle_output_event(self,symbol,param_type,param_values,req_time):
        if self.gpio_enabled is True:
            reason,message=self.gpiodriver.handle_output_event(symbol,param_type,param_values,req_time)
            if reason =='error':
                self.mon.err(self,message)
                self.end(reason,message)
        else:
            self.mon.warn(self,'GPIO not enabled')


    # all input events call this callback with a symbolic name.
    # handle events that affect PP overall, otherwise pass to all active shows
    def handle_input_event(self,symbol,source):
        self.mon.log(self,"event received: "+symbol + ' from '+ source)
        if symbol == 'pp-terminate':
            self.handle_user_abort()
            
        elif symbol == 'pp-shutdown':
            self.shutdown_pressed('delay')
            
        elif symbol == 'pp-shutdownnow':
            # need root.after to grt out of st thread
            self.root.after(1,self.e_shutdown_pressed)
            return
        
        elif symbol == 'pp-exitpipresents':
            self.exitpipresents_required=True
            if self.show_manager.all_shows_exited() is True:
                # need root.after to grt out of st thread
                self.root.after(1,self.e_all_shows_ended_callback)
                return
            reason,message= self.show_manager.exit_all_shows()
        else:
            # events for shows affect the show and could cause it to exit.
            for show in self.show_manager.shows:
                show_obj=show[ShowManager.SHOW_OBJ]
                if show_obj is not None:
                    show_obj.handle_input_event(symbol)



    def shutdown_pressed(self, when):
        if when == 'delay':
            self.root.after(5000,self.on_shutdown_delay)
        else:
            self.shutdown_required=True
            if self.show_manager.all_shows_exited() is True:
               self.all_shows_ended_callback('normal','no shows running')
            else:
                # calls exit method of all shows, results in all_shows_closed_callback
                self.show_manager.exit_all_shows()           


    def on_shutdown_delay(self):
        # 5 second delay is up, if shutdown button still pressed then shutdown
        if self.gpiodriver.shutdown_pressed() is True:
            self.shutdown_required=True
            if self.show_manager.all_shows_exited() is True:
               self.all_shows_ended_callback('normal','no shows running')
            else:
                # calls exit method of all shows, results in all_shows_closed_callback
                self.show_manager.exit_all_shows()


    def handle_sigterm(self,signum,frame):
        self.mon.log(self,'SIGTERM received - '+ str(signum))
        self.terminate()


    def handle_user_abort(self):
        self.mon.log(self,'User abort received')
        self.terminate()

    def terminate(self):
        self.mon.log(self, "terminate received")
        needs_termination=False
        for show in self.show_manager.shows:
            # print  show[ShowManager.SHOW_OBJ], show[ShowManager.SHOW_REF]
            if show[ShowManager.SHOW_OBJ] is not None:
                needs_termination=True
                self.mon.log(self,"Sent terminate to show "+ show[ShowManager.SHOW_REF])
                # call shows terminate method
                # eventually the show will exit and after all shows have exited all_shows_callback will be executed.
                show[ShowManager.SHOW_OBJ].terminate()
        if needs_termination is False:
            self.end('killed','killed - no termination of shows required')


# ******************************
# Ending Pi Presents after all the showers and players are closed
# **************************

    # callback from ShowManager when all shows have ended
    def all_shows_ended_callback(self,reason,message):
        self.canvas.config(bg=self.pp_background)
        if reason in ('killed','error') or self.shutdown_required is True or self.exitpipresents_required is True:
            self.end(reason,message)

    def end(self,reason,message):
        self.mon.log(self,"Pi Presents ending with reason: " + reason)
        if self.root is not None:
            self.root.destroy()
        self.tidy_up()
        # gc.collect()
        # print gc.garbage
        if reason == 'killed':
            self.mon.log(self, "Pi Presents Aborted, au revoir")
            # close logging files 
            self.mon.finish()
            sys.exit(101)     
        elif reason == 'error':
            self.mon.log(self, "Pi Presents closing because of error, sorry")
            # close logging files 
            self.mon.finish()
            sys.exit(102)            
        else:
            self.mon.log(self,"Pi Presents  exiting normally, bye")
            # close logging files 
            self.mon.finish()
            if self.shutdown_required is True:
                # print 'SHUTDOWN'
                call(['sudo', 'shutdown', '-h', '-t 5','now'])
                sys.exit(100)
            else:
                sys.exit(100)


    
    # tidy up all the peripheral bits of Pi Presents
    def tidy_up(self):
        self.mon.log(self, "Tidying Up")
        # turn screen blanking back on
        if self.options['noblank'] is True:
            call(["xset","s", "on"])
            call(["xset","s", "+dpms"])
            
        # tidy up animation and gpio
        if self.animate is not None:
            self.animate.terminate()
            
        if self.gpio_enabled==True:
            self.gpiodriver.terminate()

        if self.osc_enabled is True:
            self.oscdriver.terminate()
            
        # tidy up time of day scheduler
        if self.tod_enabled is True:
            self.tod.terminate()
class OSCMonitor(object):
    def __init__(self):

        self.editor_issue = "1.3"

        # get command options
        self.command_options = remote_options()

        # get directory holding the code
        self.pp_dir = sys.path[0]

        if not os.path.exists(self.pp_dir + os.sep + "pipresents.py"):
            tkMessageBox.showwarning("Pi Presents",
                                     "Bad Application Directory")
            exit()

        # Initialise logging
        Monitor.log_path = self.pp_dir
        self.mon = Monitor()
        self.mon.init()

        Monitor.classes = ['OSCMonitor', 'OSCConfig', 'OSCEditor']

        Monitor.log_level = int(self.command_options['debug'])

        self.mon.log(self, "Pi Presents Monitor is starting")
        self.mon.log(self, " OS and separator " + os.name + '  ' + os.sep)
        self.mon.log(self,
                     "sys.path[0] -  location of code: code " + sys.path[0])

        self.setup_gui()

        # initialise OSC config class
        self.osc_config = OSCConfig()

        self.init()

        #and start the system
        self.root.after(1000, self.run_app)
        self.root.mainloop()

    def init(self):
        # read the options and allow their editing
        self.osc_config_file = self.pp_dir + os.sep + 'pp_config' + os.sep + 'pp_oscmonitor.cfg'
        self.read_create_osc()

    def add_status(self, text):
        self.status_display.insert(END, text + '\n')
        self.status_display.see(END)

    def run_app(self):
        self.client = None
        self.server = None
        self.st = None

        # initialise OSC variables
        self.prefix = '/pipresents'
        self.this_unit = '/' + self.osc_config.this_unit_name
        self.add_status('this unit is: ' + self.this_unit)
        self.controlled_by_unit = '/' + self.osc_config.controlled_by_name
        self.add_status('controlled by unit : ' + self.controlled_by_unit)

        #connect client for replies then start server to listen for commands
        self.client = OSC.OSCClient()
        self.add_status('connecting to controlled by unit: ' +
                        self.osc_config.controlled_by_ip + ':' +
                        self.osc_config.controlled_by_port + ' ' +
                        self.osc_config.controlled_by_name)
        self.client.connect((self.osc_config.controlled_by_ip,
                             int(self.osc_config.controlled_by_port)))
        self.add_status('listening for commands on:' +
                        self.osc_config.this_unit_ip + ':' +
                        self.osc_config.this_unit_port)
        self.init_server(self.osc_config.this_unit_ip,
                         self.osc_config.this_unit_port, self.client)
        self.add_initial_handlers()
        self.start_server()

    # ***************************************
    # OSC CLIENT TO SEND REPLIES
    # ***************************************

    def disconnect_client(self):
        if self.client != None:
            self.client.close()
        return

    # ***************************************
    # OSC SERVER TO LISTEN TO COMMANDS
    # ***************************************

    def init_server(self, ip, port_text, client):
        self.add_status('Init Server: ' + ip + ':' + port_text)
        self.server = myOSCServer((ip, int(port_text)), client)

    def start_server(self):
        self.add_status('Start Server')
        self.st = threading.Thread(target=self.server.serve_forever)
        self.st.start()

    def close_server(self):
        if self.server != None:
            self.server.close()
        self.mon.log(self, 'Waiting for Server-thread to finish')
        if self.st != None:
            self.st.join()  ##!!!
        self.mon.log(self, 'server thread closed')

    def add_initial_handlers(self):
        pass
        self.server.addMsgHandler('default', self.no_match_handler)
        self.server.addMsgHandler(
            self.prefix + self.this_unit + "/system/server-info",
            self.server_info_handler)
        self.server.addMsgHandler(
            self.prefix + self.this_unit + "/system/loopback",
            self.loopback_handler)

    def no_match_handler(self, addr, tags, stuff, source):
        text = "Message from %s" % OSC.getUrlStr(source) + '\n'
        text += "     %s" % addr + self.pretty_list(stuff)
        self.add_status(text + '\n')

    def server_info_handler(self, addr, tags, stuff, source):
        msg = OSC.OSCMessage(self.prefix + self.controlled_by_unit +
                             '/system/server-info-reply')
        msg.append('Unit: ' + self.osc_config.this_unit_name)
        self.add_status('Server Info Request from %s:' % OSC.getUrlStr(source))
        return msg

    def loopback_handler(self, addr, tags, stuff, source):
        # send a reply to the client.
        msg = OSC.OSCMessage(self.prefix + self.controlled_by_unit +
                             '/system/loopback-reply')
        self.add_status('Loopback Request from %s:' % OSC.getUrlStr(source))
        return msg

    def pretty_list(self, fields):
        text = ' '
        for field in fields:
            text += str(field) + ' '
        return text

    # ***************************************
    # INIT EXIT MISC
    # ***************************************

    def e_edit_osc(self):
        self.disconnect_client()
        self.close_server()
        self.edit_osc()
        self.init()
        self.add_status('\n\n\nRESTART')
        self.run_app()

    def app_exit(self):
        self.disconnect_client()
        self.close_server()
        if self.root is not None:
            self.root.destroy()
        self.mon.finish()
        sys.exit()

    def show_help(self):
        tkMessageBox.showinfo("Help", "Read 'manual.pdf'")

    def about(self):
        tkMessageBox.showinfo(
            "About", "Simple Remote Monitor for Pi Presents\n" +
            "Author: Ken Thompson" +
            "\nWebsite: http://pipresents.wordpress.com/")

    def setup_gui(self):
        # set up the gui

        # root is the Tkinter root widget
        self.root = Tk()
        self.root.title("Remote Monitor for Pi Presents")

        # self.root.configure(background='grey')

        self.root.resizable(False, False)

        # define response to main window closing
        self.root.protocol("WM_DELETE_WINDOW", self.app_exit)

        # bind some display fields
        self.filename = StringVar()
        self.display_show = StringVar()
        self.results = StringVar()
        self.status = StringVar()

        # define menu
        menubar = Menu(self.root)

        toolsmenu = Menu(menubar, tearoff=0, bg="grey", fg="black")
        menubar.add_cascade(label='Tools', menu=toolsmenu)

        osc_configmenu = Menu(menubar, tearoff=0, bg="grey", fg="black")
        menubar.add_cascade(label='Options', menu=osc_configmenu)
        osc_configmenu.add_command(label='Edit', command=self.e_edit_osc)

        helpmenu = Menu(menubar, tearoff=0, bg="grey", fg="black")
        menubar.add_cascade(label='Help', menu=helpmenu)
        helpmenu.add_command(label='Help', command=self.show_help)
        helpmenu.add_command(label='About', command=self.about)

        self.root.config(menu=menubar)

        # status_frame
        status_frame = Frame(self.root, padx=5, pady=5)
        status_frame.pack(side=TOP, fill=BOTH, expand=1)
        status_label = Label(status_frame, text="Status", font="arial 12 bold")
        status_label.pack(side=LEFT)
        scrollbar = Scrollbar(status_frame, orient=VERTICAL)
        self.status_display = Text(status_frame,
                                   height=10,
                                   yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.status_display.yview)
        scrollbar.pack(side=RIGHT, fill=Y)
        self.status_display.pack(side=LEFT, fill=BOTH, expand=1)


# ***************************************
#  OSC CONFIGURATION
# ***************************************

    def read_create_osc(self):
        if self.osc_config.read(self.osc_config_file) is False:
            self.osc_config.create(self.osc_config_file)
            eosc = OSCEditor(self.root, self.osc_config_file, 'slave',
                             'Create OSC Monitor Configuration')
            self.osc_config.read(self.osc_config_file)

    def edit_osc(self):
        if self.osc_config.read(self.osc_config_file) is False:
            self.osc_config.create(self.osc_config_file)
        eosc = OSCEditor(self.root, self.osc_config_file, 'slave',
                         'Edit OSC Monitor Configuration')
Example #26
0
            showinfo("search command", "No results found.")
        else:
            #showinfo("search command", "searching:%s\nDifficulty: %s\nRating: %s"%text%str(query.getDifficulty())%str(query.getRating()))
            showinfo(
                "search command",
                "searching: " + text + "\nRating: " + query.getRating() +
                "\n" + "Difficulty: " + query.getDifficulty())

    # def update_scene(root, milsec, filename):
    #     self.img = ImageTk.PhotoImage(Image.open(INSTALL_DIR + filename))
    #     #The Label widget is a standard Tkinter widget used to display a text or image on the screen.
    #     self.master.after(milsec, self.panel.config(image = self.img))
    #     self.master.update()

    root = Tk()
    root.geometry("800x600")
    root.title("Search")
    root.config(background="#bf5700")
    Search_Bar(root,
               command=command,
               placeholder="Search for professors...",
               entry_highlightthickness=0).pack(pady=6, padx=3)

    img = ImageTk.PhotoImage(
        Image.open(INSTALL_DIR + "logo.png").resize((500, 500),
                                                    Image.ANTIALIAS))
    panel = Label(root, image=img, background="#bf5700")

    panel.pack(side=TOP)
    root.mainloop()
Example #27
0
File: tic.py Project: aqiu384/cs440
class GUI:
    def __init__(self):
        self.app = Tk()
        self.app.title('War Game')
        self.app.resizable(width=False, height=False)
        self.font = Font(family="Helvetica", size=32)
        self.buttons = {}
        self.board_file = './boards/Westerplatte.txt'
        self.board = Board(self.board_file)
        self.size = SIZE

        for y in xrange(1, self.size + 1):
            for x in xrange(1, self.size + 1):
                handler = lambda x=x, y=y: self.move(x, y)
                button = Button(self.app, command=handler, font=self.font, width=3, height=1, text=self.board.values[y, x], background='gray')
                button.grid(row=y, column=x)
                self.buttons[x, y] = button

        handler = lambda: self.auto_move()
        button = Button(self.app, text='Start AI', command=handler)
        button.grid(row=self.size + 1, column=1, columnspan=self.size, sticky="WE")

    def auto_move(self):
        output_file = open('./output/alpha_mini.txt', 'a')
        expanded_list = []
        time_list = []

        while self.board.nodes_left > 0:

            start_time = clock()
            if self.board.player == 1:
                cost, (y, x), expanded = self.board.root_negalphabeta()
            else:
                cost, (y, x), expanded = self.board.root_negamax()

            elapsed_time = clock() - start_time

            print 'Player: {} Heuristic {} Expanded {} Time took {}'.format(self.board.player, cost, expanded, elapsed_time)
            self.move(x, y)
            print 'Score: {}'.format(self.board.score)
            expanded_list.append(expanded)
            time_list.append(elapsed_time)

        output_file.write(self.board_file + '\n')
        output_file.write(' '.join(str(x) for x in expanded_list) + '\n')
        output_file.write(' '.join(str(x) for x in time_list) + '\n')
        output_file.write((self.board.colors + 66).tostring() + '\n\n')

    def move(self, x, y):
        self.app.config(cursor="watch")
        self.app.update()
        self.board.move(x, y)
        self.update(x, y)
        self.app.config(cursor="")

    def update(self, x, y):
        self.buttons[x, y]['state'] = 'disabled'
        for y in xrange(1, self.size + 1):
            for x in xrange(1, self.size + 1):
                self.buttons[x, y]['background'] = COLORS[self.board.colors[y, x]]
                self.buttons[x, y].update()

    def mainloop(self):
        self.app.mainloop()
Example #28
0
class PokerMachine():

    """Implements a video poker machine class."""

    def __init__(self):

        """Instance initialization function."""

        # Set up variables

        self.deck = pcards.Deck()
        self.cardimg = []
        self.hand = None

        self.game_start = True
        self.game_postdeal = False
        self.game_easy = True
        self.game_over = False
        self.gifdir = "./images/"

        self.pot = 100
        self.defaultbet = 5
        self.bet = 5

        self._set_up_gui()

    def button_clicked(self):

        """Event handler for button click.

        Callback method called by tk.

        """

        if self.game_over:
            self._start_new_game()
        elif not self.game_postdeal:
            self._process_bet()
        elif self.game_postdeal:
            self._evaluate_hand()

    def flip(self, event):

        """Event handler which flips a clicked card.

        Callback method called by tk.

        """

        if not self.game_postdeal:
            return

        if event.widget.flipped:
            event.widget.flipped = False
            event.widget.configure(image=event.widget.cardimage)
        else:
            event.widget.flipped = True
            event.widget.configure(image=self.backimg)

    def _start_new_game(self):

        """Returns the game an interface to its starting point."""

        for cardimg in self.cardimg:
            cardimg.configure(image=self.backimg)
            cardimg.flipped = True

        self.game_over = False
        self.game_postdeal = False
        self.pot = 100
        self.defaultbet = 5
        self.bet = 5
        self._update_pot()
        self.bet_amt_fld.configure(state=NORMAL)
        self.bet_str.set(str(self.defaultbet))
        self.button.configure(text="Deal")
        self.status_lbl.configure(text="Click 'Deal' to play.")

    def _process_bet(self):

        """Processes the player's bet and deals a new hand
        if the bet is valid.

        """

        # First check if played made a valid bet,
        # and return with no change in state (other
        # than resetting the bet field) if they did
        # not.

        b_str = self.bet_str.get()

        try:
            self.bet = int(b_str)
        except ValueError:
            self._show_bet_error("Bad bet!", "You must bet a whole number!")
            return

        if self.bet > self.pot:
            self._show_bet_error("Don't be greedy!",
                                 "You don't have that much money!")
            return
        elif self.bet < 1:
            self._show_bet_error("Don't get clever!",
                                 "You must bet a positive whole number!")
            return

        # We have a valid bet, so shuffle the deck
        # and get a new poker hand.

        self.deck.shuffle()
        self.hand = pcards.PokerHand(self.deck)
        self._show_cards()

        # Update game variables and GUI

        self.pot -= self.bet
        self._update_pot()

        self.button.configure(text="Exchange / skip")
        self.status_lbl.configure(text="Choose cards to exchange by " +
                                       "clicking on them.")
        self.bet_amt_fld.configure(state=DISABLED)

        self.game_postdeal = True

    def _evaluate_hand(self):

        """Evalutes a player's hand after any exchanges have
        been made and we have the final hand. Process
        winnings if we have any.

        """

        # Player has flipped their cards if we're here,
        # so figure out which ones they flipped and
        # exchange them and show the new cards.

        xchg_str = ""

        for cardimg in self.cardimg:
            if cardimg.flipped:
                xchg_str += cardimg.pos

        self.hand.exchange(xchg_str)
        self._show_cards()

        # Calculate winnings and show status

        winnings = self.hand.video_winnings(self.bet, easy=self.game_easy)
        win_str = self.hand.show_value() + ". "

        if winnings:
            self.pot += winnings
            win_str += "You won ${0:}!".format(winnings)
            self._update_pot()
        else:
            win_str += "Sorry, no win!"
            if self.pot == 0:
                win_str += " Out of money - game over!"
                self.game_over = True

        self.status_lbl.configure(text=win_str)

        # Update game variables and GUI

        if self.game_over:
            self.button.configure(text="New game")
        else:
            self.button.configure(text="Deal again")
            self.bet_amt_fld.configure(state=NORMAL)

        # Reset the bet amount field with the default bet. Check
        # here to make sure the default bet is not more money that
        # is in the pot, and limit it to that amount if it is.

        self.defaultbet = self.bet if self.bet <= self.pot else self.pot
        self.bet_str.set(str(self.defaultbet))
        self.game_postdeal = False

        # Discard and then drop the current hand

        self.hand.discard()
        self.hand = []

    def _show_bet_error(self, title, message):

        """Shows a message box and resets the bet field
        in response to an invalid bet.

        """

        tkMessageBox.showerror(title, message)
        self.bet = self.defaultbet
        self.bet_str.set(str(self.defaultbet))

    def _update_pot(self):

        """Updates the pot amount label with the current pot."""

        txt_str = "${0:}".format(self.pot)
        self.pot_amt_lbl.configure(text=txt_str)

    def _show_cards(self):

        """Shows the cards in the poker hand on the screen."""

        for cardimg, idx in zip(self.cardimg, self.hand.index_list()):
            cardfile = "{0}{1}.gif".format(self.gifdir, str(idx + 1))
            img = PhotoImage(file=cardfile)
            cardimg.configure(image=img)
            cardimg.cardimage = img
            cardimg.flipped = False

    def _set_up_gui(self):

        """Sets up the Tkinter user interface."""

        # Disable pylint warning for instance attributes defined outside
        # __init__(), since this method is called by __init__()
        #
        # pylint: disable=W0201

        self.root = Tk()
        self.root.title('Video Poker')

        # Set up menubar

        self.menubar = Menu(self.root)

        self.gamemenu = Menu(self.menubar, tearoff=0)
        self.gamemenu.add_command(label="Quit", command=sys.exit)
        self.menubar.add_cascade(label="Game", menu=self.gamemenu)

        self.helpmenu = Menu(self.menubar, tearoff=0)
        self.helpmenu.add_command(label="About", command=self.help_about)
        self.menubar.add_cascade(label="Help", menu=self.helpmenu)

        self.root.config(menu=self.menubar)

        # Set up card images

        self.backimg = PhotoImage(file="{0}b.gif".format(self.gifdir))

        for num in range(5):
            lbl = Label(self.root, image=self.backimg)
            lbl.grid(row=0, column=num, padx=10, pady=10)
            lbl.bind("<Button-1>", self.flip)
            lbl.flipped = True
            lbl.pos = str(num + 1)
            self.cardimg.append(lbl)

        # Set up labels, fields and buttons

        self.pot_lbl = Label(self.root, text="Pot:")
        self.pot_lbl.grid(row=1, column=0,
                          padx=10, pady=2, sticky=W)

        self.pot_amt_lbl = Label(self.root, text="")
        self.pot_amt_lbl.grid(row=1, column=1, columnspan=2,
                              padx=10, pady=2, sticky=W)
        self._update_pot()

        self.bet_lbl = Label(self.root, text="Bet ($):")
        self.bet_lbl.grid(row=2, column=0,
                          padx=10, pady=2, sticky=W)

        self.bet_str = StringVar()
        self.bet_str.set(str(self.defaultbet))

        self.bet_amt_fld = Entry(self.root, textvariable=self.bet_str)
        self.bet_amt_fld.grid(row=2, column=1, columnspan=2,
                              padx=10, pady=2, sticky=W)

        self.button = Button(self.root, text="Deal",
                             command=self.button_clicked)
        self.button.grid(row=1, column=3, rowspan=2, columnspan=2,
                         sticky=W + E + S + N, padx=10)

        self.status_lbl = Label(self.root, bd=1, relief=SUNKEN,
                                text="Welcome to the casino! " +
                                     "Click 'Deal' to play!")
        self.status_lbl.grid(row=3, column=0, columnspan=5,
                             padx=10, pady=10, ipadx=10, ipady=10,
                             sticky=W + E + S + N)

        # Show winnings table

        lbl = Label(self.root, text="Winnings Table", relief=RAISED)
        lbl.grid(row=4, column=1, columnspan=3,
                 pady=15, ipadx=10, ipady=10, sticky=W + E)

        # Two different tables, one for easy mode, one for normal
        # mode, so be prepared to show either one.

        wte = {2500: "Royal Flush", 250: "Straight Flush",
               100: "Four of a Kind", 50: "Full House", 20: "Flush",
               15: "Straight", 4: "Three of a Kind", 3: "Two Pair",
               2: "Jacks or Higher"}
        wtn = {800: "Royal Flush", 50: "Straight Flush", 25: "Four of a Kind",
               9: "Full House", 6: "Flush", 4: "Straight",
               3: "Three of a Kind", 2: "Two Pair", 1: "Jacks or Higher"}
        wtxt = wte if self.game_easy else wtn

        row = 5
        for key in sorted(wtxt.keys(), reverse=True):
            lbl = Label(self.root, text=wtxt[key])
            lbl.grid(row=row, column=1, columnspan=2, sticky=W)
            lbl = Label(self.root, text="{0} : 1".format(key))
            lbl.grid(row=row, column=3, sticky=E)
            row += 1

        lbl = Label(self.root, text="")
        lbl.grid(row=row, column=0, columnspan=5, pady=15)

        # pylint: enable=W0201

    def help_about(self):

        """Shows an 'about' modal dialog.

        Callback method called by tk.

        """

        about_win = Toplevel(self.root)

        # Set up dialog

        lbl = Label(about_win, text="Video Poker")
        lbl.grid(row=0, column=0, padx=10, pady=(10, 0), sticky=W + N)
        lbl = Label(about_win, text="by Charles Raymond Smith")
        lbl.grid(row=1, column=0, padx=10, pady=(0, 7), sticky=W + N)
        lbl = Label(about_win, text="Adapted from video poker by Paul Griffiths")
        lbl.grid(row=2, column=0, padx=10, pady=(0, 7), sticky=W + N)
        lbl = Label(about_win, text="Written in Python, with tkinter.")
        lbl.grid(row=3, column=0, padx=10, pady=7, sticky=W + N)
        lbl = Label(about_win, text="Copyright 2017 Charles Raymond Smith")
        lbl.grid(row=4, column=0, padx=10, pady=(7, 0), sticky=W + N)
        lbl = Label(about_win, text="Email: [email protected]")
        lbl.grid(row=5, column=0, padx=10, pady=(0, 21), sticky=W + N)
        lbl = Label(about_win, text="This program is free software: you can " +
            "redistribute it and/or modify it under the terms")
        lbl.grid(row=6, column=0, columnspan=2,
                 padx=10, pady=0, sticky=W + N)
        lbl = Label(about_win, text="of the GNU General Public License as " +
            "published by the Free Software Foundation, either")
        lbl.grid(row=7, column=0, columnspan=2,
                 padx=10, pady=(0, 0), sticky=W + N)
        lbl = Label(about_win, text="version 3 of the License, or " +
            "(at your option) any later version.")
        lbl.grid(row=8, column=0, columnspan=2,
                 padx=10, pady=(0, 21), sticky=W + N)
        lbl = Label(about_win, text="This program is distributed in " +
            "the hope that it will be useful, but WITHOUT ANY WARRANTY;")
        lbl.grid(row=9, column=0, columnspan=2,
                 padx=10, pady=0, sticky=W + N)
        lbl = Label(about_win, text="without even the implied " +
            "warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR")
        lbl.grid(row=10, column=0, columnspan=2,
                 padx=10, pady=(0, 0), sticky=W + N)
        lbl = Label(about_win, text="PURPOSE. See the " +
            "GNU General Public License for more details.")
        lbl.grid(row=11, column=0, columnspan=2,
                 padx=10, pady=(0, 21), sticky=W + N)
        lbl = Label(about_win, text="You should have received a " +
            "copy of the GNU General Public License along with this")
        lbl.grid(row=12, column=0, columnspan=2,
                 padx=10, pady=(0, 0), sticky=W + N)
        lbl = Label(about_win, text="program. If not, see " +
            "<http://www.gnu.org/licenses/>.")
        lbl.grid(row=13, column=0, columnspan=2,
                 padx=10, pady=(0, 21), sticky=W + N)
        img = PhotoImage(file="{0}27.gif".format(self.gifdir))
        lbl = Label(about_win, image=img)
        lbl.grid(row=0, column=1, rowspan=5, padx=10, pady=10, sticky=N + E)

        btn = Button(about_win, text="OK", command=about_win.quit)
        btn.grid(row=14, column=0, columnspan=2,
                 padx=0, pady=(0, 10), ipadx=30, ipady=3)

        # Show dialog

        about_win.transient(self.root)
        about_win.parent = self.root
        about_win.protocol("WM_DELETE_WINDOW", about_win.destroy)
        about_win.geometry("+{0}+{1}".format(self.root.winfo_rootx() + 50,
                                           self.root.winfo_rooty() + 50))
        about_win.title("About Video Poker")
        about_win.focus_set()
        about_win.grab_set()
        about_win.mainloop()
        about_win.destroy()
Example #29
0
class Cell:
    def __init__(self, parent, type, x, y, height, temperature_multiplier,
                 moisture, owner):
        self.parent = parent

        self.type = type

        self.x = x
        self.y = y

        self.cell_id = self.parent.get_next_id('cell')

        self.id = -1

        self.building_capacity = 100

        self.terrain = Terrain(height, moisture)

        self.temperature_multiplier = max(0, temperature_multiplier)
        self.temperature = None

        self.buildings = building.base_buildings(None)

        self.high_temp_range = random.random() / 5
        self.low_temp_range = random.random() / 5

        self.owner = owner

        self.make_id()

        self.can_pass = not self.terrain.is_water()

    # Determines whether it is legal for a group to move onto this square
    # Kenny - detects whether or not the cell's terrain is water. If it is water unit can't move through
    def can_move(self, group):
        return self.can_pass  # For now it is always lega

    def save(self):
        self.parent.db.execute(
            'db/internal/terrain/cell_insert.sql', {
                'cell_id': self.cell_id,
                'type': self.type,
                'x': self.x,
                'y': self.y,
                'height': self.terrain.height,
                'temperature_multiplier': self.temperature_multiplier,
                'moisture': self.terrain.moisture,
                'owner': self.owner.id if self.owner is not None else -1,
                'building_capacity': self.building_capacity,
                'high_temp_range': self.high_temp_range,
                'low_temp_range': self.low_temp_range
            })

        for building in self.buildings:
            if building.number > 0:
                building.save(self.parent.db, self.cell_id)

    def get_population_capacity(self):
        return sum([
            building.get_population_capacity() for building in self.buildings
        ])

    def get_food_output(self):
        result = random.randint(BASE_CELL_MIN_FOOD_PRODUCTION,
                                BASE_CELL_FOOD_PRODUCTION)
        result *= self.food_production_multiplier()

        return result

    def building_count(self):
        return sum([building.number for building in self.buildings])

    def get_total_buiding_size(self):
        return sum([
            building.get_size() * building.number
            for building in self.buildings
        ])

    def get_available_building_capacity(self):
        multiplier = 1.0
        if self.owner is not None:
            best = self.owner.nation.tech.get_best_in_category(
                'compact_building')

            if best is not None:
                multiplier = best.multiplier

        return multiplier * self.building_capacity - self.get_total_buiding_size(
        )

    def build_buildings(self):
        improvement_chance = int((self.building_count() + 1) /
                                 (math.sqrt(self.owner.population) + 1))
        if random.randint(0, improvement_chance + 1) == 0:
            available_buildings = filter(
                lambda b: b.get_size() <= self.get_available_building_capacity(
                ), self.buildings)

            if len(available_buildings) > 0:
                build_building = utility.weighted_random_choice(
                    available_buildings,
                    weight=lambda _, b: 1.0 / b.get_cost())

                if self.owner.nation.money > build_building.get_cost():
                    self.owner.nation.money -= build_building.get_cost()
                    build_building.number += 1

    def get_resource_productions(self):
        result = {}
        for curBuilding in self.buildings:
            production = curBuilding.get_resource_productions()

            for resource in production:
                if resource in result:
                    result[resource] += production[resource]
                else:
                    result[resource] = production[resource]
        return result

    def get_tax_rate(self):
        return utility.product(
            [building.get_tax_rate() for building in self.buildings])

    def get_money_output(self):
        return sum(
            [building.get_money_output() for building in self.buildings])

    def get_elevation(self):
        return to_meters(self.terrain.height * MAX_HEIGHT)

    def get_high_temperature(self):
        return self.get_temperature(
        ) + self.get_temperature() * self.high_temp_range

    def get_low_temperature(self):
        return self.get_temperature(
        ) - self.get_temperature() * self.low_temp_range

    def get_temperature_range(self):
        return self.get_high_temperature() - self.get_low_temperature()

    def get_temperature(self):
        # The base temperature never changes, so we only need to calculate it once.
        if self.temperature is None:
            self.temperature = temperature(
                self.terrain.height * MAX_HEIGHT, self.y,
                utility.S_HEIGHT) * (1 - self.temperature_multiplier)

        return self.temperature

    # http://www.sciencedirect.com/science/article/pii/0002157177900073
    def get_dew_point(self):
        return 0.0023 * self.get_elevation() + 0.37 * self.get_temperature(
        ) + 0.53 * self.get_temperature_range() - 10.9

    def get_evaporation(self):
        amount = (self.get_temperature() + 15.0 * self.get_dew_point()) / (
            80.0 - self.get_temperature())
        amount *= random.random()

        if self.terrain.is_water():
            return amount

        if amount > self.terrain.moisture:
            amount = self.terrain.moisture
            self.terrain.moisture = 0

            return amount
        else:
            self.terrain.moisture -= amount

            return amount

    def food_production_multiplier(self):
        # Higher temperature means better production.
        multiplier = self.get_temperature(
        ) / 98.0 * self.terrain.get_food_production_multiplier()
        for neighbor in self.neighbors():
            # So does being surrounding by water
            if neighbor.terrain.is_water():
                multiplier *= neighbor.terrain.get_food_production_multiplier()

        return multiplier

    def reset_color(self):
        if self.id >= 0:
            if self.owner is not None:
                self.parent.canvas.itemconfig(self.id,
                                              fill=self.owner.nation.color)
            else:
                self.parent.canvas.itemconfig(self.id, fill=self.terrain.color)

    def make_id(self):
        start_x, start_y = self.x * utility.CELL_SIZE, self.y * utility.CELL_SIZE
        end_x, end_y = start_x + utility.CELL_SIZE, start_y + utility.CELL_SIZE
        try:
            if self.owner is not None:
                self.id = self.parent.canvas.create_rectangle(
                    start_x,
                    start_y,
                    end_x,
                    end_y,
                    width=0,
                    fill=self.owner.nation.color)
            else:
                self.id = self.parent.canvas.create_rectangle(
                    start_x,
                    start_y,
                    end_x,
                    end_y,
                    width=0,
                    fill=self.terrain.color)
        except:
            pass

    def show_information_gui(self):
        self.gui_window = Tk()
        self.gui_window.title('Cell Information: ({}, {})'.format(
            self.x, self.y))
        self.gui_window.geometry("400x300+0+0")
        self.gui_window.config(background='white')

        self.type_label = gui.Label(self.gui_window,
                                    text='Type: {}'.format(self.type))
        self.type_label.grid(row=0, sticky=W)

        self.owning_city_label = gui.Label(self.gui_window,
                                           text='Owning city: ')
        self.owning_city_label.grid(row=1, sticky=W)

        self.owning_nation_label = gui.Label(self.gui_window,
                                             text='Owning nation: ')
        self.owning_nation_label.grid(row=2, sticky=W)

        if self.owner is not None:
            self.owning_city_button = gui.Button(
                self.gui_window,
                text=self.owner.name,
                command=self.owner.show_information_gui)
            self.owning_nation_button = gui.Button(
                self.gui_window,
                text=self.owner.nation.name,
                command=self.owner.nation.show_information_gui)
        else:
            self.owning_city_button = gui.Button(self.gui_window, text='None')
            self.owning_nation_button = gui.Button(self.gui_window,
                                                   text='None')

        self.owning_city_button.grid(row=1, column=1, sticky=W)
        self.owning_nation_button.grid(row=2, column=1, sticky=W)

        self.building_capacity_label = gui.Label(
            self.gui_window,
            text='{} of {} filled.'.format(self.get_total_buiding_size(),
                                           self.building_capacity))
        self.building_capacity_label.grid(row=3)

        self.buildings_display = Listbox(self.gui_window)

        for building in self.buildings:
            self.buildings_display.insert(
                END, '{}: {}'.format(building.name, building.number))

        self.buildings_display.grid(row=4,
                                    column=0,
                                    columnspan=3,
                                    sticky=W + E)

    def update_self(self):
        if self.owner is None:
            self.parent.canvas.itemconfig(self.id, fill=self.terrain.color)
        else:
            self.parent.canvas.itemconfig(self.id,
                                          fill=self.owner.nation.color)

    def change_type(self, new_type):
        self.type = new_type

        self.update_self()

    def change_owner(self, new_owner, new_type=None):
        if self.owner is not None:  # Remove this cell from the list of owned cells
            self.owner.remove_cell(self)

        # This must be before .add_cell
        if new_type is not None:
            self.change_type(new_type)

        self.owner = new_owner

        if self.owner is not None:
            for curBuilding in self.buildings:
                curBuilding.city = new_owner
            self.owner.add_cell(self)
        else:
            self.new_type = ''  # There is no cell type for an unowned cell.
            self.buildings = building.base_buildings(None)

        self.update_self()

    def neighbors(self):
        result = []

        if self.x > 0:
            result.append(self.parent.cells[self.x - 1][self.y])
        # else:
        #     result.append(self.parent.cells[utility.S_WIDTH // utility.CELL_SIZE - 1][self.y])

        if self.y > 0:
            result.append(self.parent.cells[self.x][self.y - 1])
        # else:
        #     result.append(self.parent.cells[self.x][utility.S_HEIGHT // utility.CELL_SIZE - 1])

        if self.x < utility.S_WIDTH // utility.CELL_SIZE - 1:
            result.append(self.parent.cells[self.x + 1][self.y])
        # else:
        #     result.append(self.parent.cells[0][self.y])

        if self.y < utility.S_HEIGHT // utility.CELL_SIZE - 1:
            result.append(self.parent.cells[self.x][self.y + 1])
        # else:
        #     result.append(self.parent.cells[self.x][0])

        return result
Example #30
0
class PiPresents(object):

    def pipresents_version(self):
        vitems=self.pipresents_issue.split('.')
        if len(vitems)==2:
            # cope with 2 digit version numbers before 1.3.2
            return 1000*int(vitems[0])+100*int(vitems[1])
        else:
            return 1000*int(vitems[0])+100*int(vitems[1])+int(vitems[2])


    def __init__(self):
        gc.set_debug(gc.DEBUG_UNCOLLECTABLE|gc.DEBUG_INSTANCES|gc.DEBUG_OBJECTS|gc.DEBUG_SAVEALL)
        self.pipresents_issue="1.3.2"
        self.pipresents_minorissue = '1.3.2a'
        # position and size of window without -f command line option
        self.nonfull_window_width = 0.45 # proportion of width
        self.nonfull_window_height= 0.7 # proportion of height
        self.nonfull_window_x = 0 # position of top left corner
        self.nonfull_window_y=0   # position of top left corner


        StopWatch.global_enable=False

        # set up the handler for SIGTERM
        signal.signal(signal.SIGTERM,self.handle_sigterm)
        

# ****************************************
# Initialisation
# ***************************************
        # get command line options
        self.options=command_options()

        # get Pi Presents code directory
        pp_dir=sys.path[0]
        self.pp_dir=pp_dir
        
        if not os.path.exists(pp_dir+"/pipresents.py"):
            if self.options['manager']  is False:
                tkMessageBox.showwarning("Pi Presents","Bad Application Directory")
            exit(102)

        
        # Initialise logging and tracing
        Monitor.log_path=pp_dir
        self.mon=Monitor()
        # Init in PiPresents only
        self.mon.init()

        # uncomment to enable control of logging from within a class
        # Monitor.enable_in_code = True # enables control of log level in the code for a class  - self.mon.set_log_level()

        
        # make a shorter list to log/trace only some classes without using enable_in_code.
        Monitor.classes  = ['PiPresents',
                            
                            'HyperlinkShow','RadioButtonShow','ArtLiveShow','ArtMediaShow','MediaShow','LiveShow','MenuShow',
                            'GapShow','Show','ArtShow',
                            'AudioPlayer','BrowserPlayer','ImagePlayer','MenuPlayer','MessagePlayer','VideoPlayer','Player',
                            'MediaList','LiveList','ShowList',
                            'PathManager','ControlsManager','ShowManager','PluginManager',
                            'MplayerDriver','OMXDriver','UZBLDriver',
                            'KbdDriver','GPIODriver','TimeOfDay','ScreenDriver','Animate','OSCDriver',
                            'Network','Mailer'
                            ]
        

        # Monitor.classes=['PiPresents','MediaShow','GapShow','Show','VideoPlayer','Player','OMXDriver']
        
        # get global log level from command line
        Monitor.log_level = int(self.options['debug'])
        Monitor.manager = self.options['manager']
        # print self.options['manager']
        self.mon.newline(3)
        self.mon.sched (self, "Pi Presents is starting, Version:"+self.pipresents_minorissue + ' at '+time.strftime("%Y-%m-%d %H:%M.%S"))
        self.mon.log (self, "Pi Presents is starting, Version:"+self.pipresents_minorissue+ ' at '+time.strftime("%Y-%m-%d %H:%M.%S"))
        # self.mon.log (self," OS and separator:" + os.name +'  ' + os.sep)
        self.mon.log(self,"sys.path[0] -  location of code: "+sys.path[0])

        # log versions of Raspbian and omxplayer, and GPU Memory
        with open("/boot/issue.txt") as file:
            self.mon.log(self,'\nRaspbian: '+file.read())

        self.mon.log(self,'\n'+check_output(["omxplayer", "-v"]))
        self.mon.log(self,'\nGPU Memory: '+check_output(["vcgencmd", "get_mem", "gpu"]))
        
        if "DESKTOP_SESSION" not in os.environ:
            print 'Pi Presents must be run from the Desktop'
            self.mon.log(self,'Pi Presents must be run from the Desktop')
            self.mon.finish()
            sys.exit(102)
        else:
            self.mon.log(self,'Desktop is '+ os.environ['DESKTOP_SESSION'])
        
        # optional other classes used
        self.root=None
        self.ppio=None
        self.tod=None
        self.animate=None
        self.gpiodriver=None
        self.oscdriver=None
        self.osc_enabled=False
        self.gpio_enabled=False
        self.tod_enabled=False
        self.email_enabled=False


        if os.geteuid() == 0:
            self.mon.err(self,'Do not run Pi Presents with sudo')
            self.end('error','Do not run Pi Presents with sudo')

        
        user=os.getenv('USER')

        self.mon.log(self,'User is: '+ user)
        # self.mon.log(self,"os.getenv('HOME') -  user home directory (not used): " + os.getenv('HOME')) # does not work
        # self.mon.log(self,"os.path.expanduser('~') -  user home directory: " + os.path.expanduser('~'))   # does not work



        # check network is available
        self.network_connected=False
        self.network_details=False
        self.interface=''
        self.ip=''
        self.unit=''
        
        # sets self.network_connected and self.network_details
        self.init_network()

        
        # start the mailer and send email when PP starts
        self.email_enabled=False
        if self.network_connected is True:
            self.init_mailer()
            if self.email_enabled is True and self.mailer.email_at_start is True:
                subject= '[Pi Presents] ' + self.unit + ': PP Started on ' + time.strftime("%Y-%m-%d %H:%M")
                message = time.strftime("%Y-%m-%d %H:%M") + '\nUnit: ' + self.unit + '   Profile: '+ self.options['profile']+ '\n ' + self.interface + '\n ' + self.ip 
                self.send_email('start',subject,message) 

         
        # get profile path from -p option
        if self.options['profile'] != '':
            self.pp_profile_path="/pp_profiles/"+self.options['profile']
        else:
            self.mon.err(self,"Profile not specified in command ")
            self.end('error','Profile not specified with the commands -p option')
        
       # get directory containing pp_home from the command,
        if self.options['home']  == "":
            home = os.sep+ 'home' + os.sep + user + os.sep+"pp_home"
        else:
            home = self.options['home'] + os.sep+ "pp_home"         
        self.mon.log(self,"pp_home directory is: " + home)


        # check if pp_home exists.
        # try for 10 seconds to allow usb stick to automount
        found=False
        for i in range (1, 10):
            self.mon.log(self,"Trying pp_home at: " + home +  " (" + str(i)+')')
            if os.path.exists(home):
                found=True
                self.pp_home=home
                break
            time.sleep (1)
        if found is True:
            self.mon.log(self,"Found Requested Home Directory, using pp_home at: " + home)
        else:
            self.mon.err(self,"Failed to find pp_home directory at " + home)
            self.end('error',"Failed to find pp_home directory at " + home)


        # check profile exists
        self.pp_profile=self.pp_home+self.pp_profile_path
        if os.path.exists(self.pp_profile):
            self.mon.sched(self,"Running profile: " + self.pp_profile_path)
            self.mon.log(self,"Found Requested profile - pp_profile directory is: " + self.pp_profile)
        else:
            self.mon.err(self,"Failed to find requested profile: "+ self.pp_profile)
            self.end('error',"Failed to find requested profile: "+ self.pp_profile)

        self.mon.start_stats(self.options['profile'])
        
        if self.options['verify'] is True:
            val =Validator()
            if  val.validate_profile(None,pp_dir,self.pp_home,self.pp_profile,self.pipresents_issue,False) is  False:
                self.mon.err(self,"Validation Failed")
                self.end('error','Validation Failed')

         
        # initialise and read the showlist in the profile
        self.showlist=ShowList()
        self.showlist_file= self.pp_profile+ "/pp_showlist.json"
        if os.path.exists(self.showlist_file):
            self.showlist.open_json(self.showlist_file)
        else:
            self.mon.err(self,"showlist not found at "+self.showlist_file)
            self.end('error',"showlist not found at "+self.showlist_file)

        # check profile and Pi Presents issues are compatible
        if self.showlist.profile_version() != self.pipresents_version():
            self.mon.err(self,"Version of showlist " + self.showlist.profile_version_string + " is not  same as Pi Presents")
            self.end('error',"Version of showlist " + self.showlist.profile_version_string + " is not  same as Pi Presents")


        # get the 'start' show from the showlist
        index = self.showlist.index_of_show('start')
        if index >=0:
            self.showlist.select(index)
            self.starter_show=self.showlist.selected_show()
        else:
            self.mon.err(self,"Show [start] not found in showlist")
            self.end('error',"Show [start] not found in showlist")


# ********************
# SET UP THE GUI
# ********************
        # turn off the screenblanking and saver
        if self.options['noblank'] is True:
            call(["xset","s", "off"])
            call(["xset","s", "-dpms"])

        self.root=Tk()   
       
        self.title='Pi Presents - '+ self.pp_profile
        self.icon_text= 'Pi Presents'
        self.root.title(self.title)
        self.root.iconname(self.icon_text)
        self.root.config(bg=self.starter_show['background-colour'])

        self.mon.log(self, 'monitor screen dimensions are ' + str(self.root.winfo_screenwidth()) + ' x ' + str(self.root.winfo_screenheight()) + ' pixels')
        if self.options['screensize'] =='':        
            self.screen_width = self.root.winfo_screenwidth()
            self.screen_height = self.root.winfo_screenheight()
        else:
            reason,message,self.screen_width,self.screen_height=self.parse_screen(self.options['screensize'])
            if reason =='error':
                self.mon.err(self,message)
                self.end('error',message)

        self.mon.log(self, 'forced screen dimensions (--screensize) are ' + str(self.screen_width) + ' x ' + str(self.screen_height) + ' pixels')
       
        # set window dimensions and decorations
        if self.options['fullscreen'] is False:
            self.window_width=int(self.root.winfo_screenwidth()*self.nonfull_window_width)
            self.window_height=int(self.root.winfo_screenheight()*self.nonfull_window_height)
            self.window_x=self.nonfull_window_x
            self.window_y=self.nonfull_window_y
            self.root.geometry("%dx%d%+d%+d" % (self.window_width,self.window_height,self.window_x,self.window_y))
        else:
            self.window_width=self.screen_width
            self.window_height=self.screen_height
            self.root.attributes('-fullscreen', True)
            os.system('unclutter &')
            self.window_x=0
            self.window_y=0  
            self.root.geometry("%dx%d%+d%+d"  % (self.window_width,self.window_height,self.window_x,self.window_y))
            self.root.attributes('-zoomed','1')

        # canvas cover the whole screen whatever the size of the window. 
        self.canvas_height=self.screen_height
        self.canvas_width=self.screen_width
  
        # make sure focus is set.
        self.root.focus_set()

        # define response to main window closing.
        self.root.protocol ("WM_DELETE_WINDOW", self.handle_user_abort)

        # setup a canvas onto which will be drawn the images or text
        self.canvas = Canvas(self.root, bg=self.starter_show['background-colour'])


        if self.options['fullscreen'] is True:
            self.canvas.config(height=self.canvas_height,
                               width=self.canvas_width,
                               highlightthickness=0)
        else:
            self.canvas.config(height=self.canvas_height,
                    width=self.canvas_width,
                        highlightthickness=1,
                               highlightcolor='yellow')
            
        self.canvas.place(x=0,y=0)
        # self.canvas.config(bg='black')
        self.canvas.focus_set()


                
# ****************************************
# INITIALISE THE INPUT DRIVERS
# ****************************************

        # each driver takes a set of inputs, binds them to symboic names
        # and sets up a callback which returns the symbolic name when an input event occurs/

        # use keyboard driver to bind keys to symbolic names and to set up callback
        kbd=KbdDriver()
        if kbd.read(pp_dir,self.pp_home,self.pp_profile) is False:
            self.end('error','cannot find, or error in keys.cfg')
        kbd.bind_keys(self.root,self.handle_input_event)

        self.sr=ScreenDriver()
        # read the screen click area config file
        reason,message = self.sr.read(pp_dir,self.pp_home,self.pp_profile)
        if reason == 'error':
            self.end('error','cannot find, or error in screen.cfg')


        # create click areas on the canvas, must be polygon as outline rectangles are not filled as far as find_closest goes
        # click areas are made on the Pi Presents canvas not the show canvases.
        reason,message = self.sr.make_click_areas(self.canvas,self.handle_input_event)
        if reason == 'error':
            self.mon.err(self,message)
            self.end('error',message)


# ****************************************
# INITIALISE THE APPLICATION AND START
# ****************************************
        self.shutdown_required=False
        self.terminate_required=False
        self.exitpipresents_required=False

        # delete omxplayer dbus files
        # if os.path.exists("/tmp/omxplayerdbus.{}".format(user)):
            # os.remove("/tmp/omxplayerdbus.{}".format(user))
        # if os.path.exists("/tmp/omxplayerdbus.{}.pid".format(user)):
            # os.remove("/tmp/omxplayerdbus.{}.pid".format(user))
        
        # kick off GPIO if enabled by command line option
        self.gpio_enabled=False
        if os.path.exists(self.pp_profile + os.sep + 'pp_io_config'+os.sep+ 'gpio.cfg'):
            # initialise the GPIO
            self.gpiodriver=GPIODriver()
            reason,message=self.gpiodriver.init(pp_dir,self.pp_home,self.pp_profile,self.canvas,50,self.handle_input_event)
            if reason == 'error':
                self.end('error',message)
            else:
                self.gpio_enabled=True
                # and start polling gpio
                self.gpiodriver.poll()
            
        # kick off animation sequencer
        self.animate = Animate()
        self.animate.init(pp_dir,self.pp_home,self.pp_profile,self.canvas,200,self.handle_output_event)
        self.animate.poll()

        #create a showmanager ready for time of day scheduler and osc server
        show_id=-1
        self.show_manager=ShowManager(show_id,self.showlist,self.starter_show,self.root,self.canvas,self.pp_dir,self.pp_profile,self.pp_home)
        # first time through set callback to terminate Pi Presents if all shows have ended.
        self.show_manager.init(self.canvas,self.all_shows_ended_callback,self.handle_command,self.showlist)
        # Register all the shows in the showlist
        reason,message=self.show_manager.register_shows()
        if reason == 'error':
            self.mon.err(self,message)
            self.end('error',message)


        # Init OSCDriver, read config and start OSC server
        self.osc_enabled=False
        if self.network_connected is True:
            if os.path.exists(self.pp_profile + os.sep + 'pp_io_config'+ os.sep + 'osc.cfg'):
                self.oscdriver=OSCDriver()
                reason,message=self.oscdriver.init(self.pp_profile,self.handle_command,self.handle_input_event,self.e_osc_handle_output_event)
                if reason == 'error':
                    self.mon.err(self,message)
                    self.end('error',message)
                else:
                    self.osc_enabled=True
                    self.root.after(1000,self.oscdriver.start_server())

        
        # enable ToD scheduler if schedule exists      
        if os.path.exists(self.pp_profile + os.sep + 'schedule.json'):                
            self.tod_enabled = True
        else:
            self.tod_enabled=False

        # warn if the network not available when ToD required

        if self.tod_enabled is True and self.network_connected is False:
            self.mon.warn(self,'Network not connected  so Time of Day scheduler may be using the internal clock')

        # warn about start shows and scheduler

        if self.starter_show['start-show']=='' and self.tod_enabled is False:
            self.mon.sched(self,"No Start Shows in Start Show and no shows scheduled") 
            self.mon.warn(self,"No Start Shows in Start Show and no shows scheduled")

        if self.starter_show['start-show'] !='' and self.tod_enabled is True:
            self.mon.sched(self,"Start Shows in Start Show and shows scheduled - conflict?") 
            self.mon.warn(self,"Start Shows in Start Show and shows scheduled - conflict?")

        # run the start shows
        self.run_start_shows()           

        # kick off the time of day scheduler which may run additional shows
        if self.tod_enabled is True:
            self.tod=TimeOfDay()
            self.tod.init(pp_dir,self.pp_home,self.pp_profile,self.root,self.handle_command)
            self.tod.poll()            


        # start Tkinters event loop
        self.root.mainloop( )


    def parse_screen(self,size_text):
        fields=size_text.split('*')
        if len(fields)!=2:
            return 'error','do not understand --screensize comand option',0,0
        elif fields[0].isdigit()  is False or fields[1].isdigit()  is False:
            return 'error','dimensions are not positive integers in --screensize',0,0
        else:
            return 'normal','',int(fields[0]),int(fields[1])
        

# *********************
#  RUN START SHOWS
# ********************   
    def run_start_shows(self):
        self.mon.trace(self,'run start shows')
        # parse the start shows field and start the initial shows       
        show_refs=self.starter_show['start-show'].split()
        for show_ref in show_refs:
            reason,message=self.show_manager.control_a_show(show_ref,'open')
            if reason == 'error':
                self.mon.err(self,message)
                


# *********************
# User inputs
# ********************
    # handles one command provided as a line of text
    
    def handle_command(self,command_text,source='',show=''):
        # print 'PIPRESENTS ',command_text,source,'from',show
        self.mon.log(self,"command received: " + command_text)
        if command_text.strip()=="":
            return

        if command_text[0]=='/': 
            if self.osc_enabled is True:
                self.oscdriver.send_command(command_text)
            return
        
        fields= command_text.split()
        show_command=fields[0]
        if len(fields)>1:
            show_ref=fields[1]
        else:
            show_ref=''

        if show_command in ('open','close'):
            self.mon.sched(self, command_text + ' received from show:'+show)
            if self.shutdown_required is False and self.terminate_required is False:
                reason,message=self.show_manager.control_a_show(show_ref,show_command)
            else:
                return
        elif show_command =='monitor':
            self.handle_monitor_command(show_ref)
            return
        elif show_command == 'event':
            self.handle_input_event(show_ref,'Show Control')
            return
        elif show_command == 'exitpipresents':
            self.exitpipresents_required=True
            if self.show_manager.all_shows_exited() is True:
                # need root.after to get out of st thread
                self.root.after(1,self.e_all_shows_ended_callback)
                return
            else:
                reason,message= self.show_manager.exit_all_shows()

        elif show_command == 'shutdownnow':
            # need root.after to get out of st thread
            self.root.after(1,self.e_shutdown_pressed)
            return
        else:
            reason='error'
            message = 'command not recognised: '+ show_command
            
        if reason=='error':
            self.mon.err(self,message)
        return


    def handle_monitor_command(self,command):
        if command == 'on':
            os.system('vcgencmd display_power 1 >/dev/null')
        elif command == 'off':
            os.system('vcgencmd display_power 0 >/dev/null')           
                      
    

    def e_all_shows_ended_callback(self):
        self.all_shows_ended_callback('normal','no shows running')

    def e_shutdown_pressed(self):
        self.shutdown_pressed('now')


    def e_osc_handle_output_event(self,line):
        #jump  out of server thread
        self.root.after(1, lambda arg=line: self.osc_handle_output_event(arg))

    def  osc_handle_output_event(self,line):
        self.mon.log(self,"output event received: "+ line)
        #osc sends output events as a string
        reason,message,delay,name,param_type,param_values=self.animate.parse_animate_fields(line)
        if reason == 'error':
            self.mon.err(self,message)
            self.end(reason,message)
        self.handle_output_event(name,param_type,param_values,0)

               
    def handle_output_event(self,symbol,param_type,param_values,req_time):
        if self.gpio_enabled is True:
            reason,message=self.gpiodriver.handle_output_event(symbol,param_type,param_values,req_time)
            if reason =='error':
                self.mon.err(self,message)
                self.end(reason,message)
        else:
            self.mon.warn(self,'GPIO not enabled')


    # all input events call this callback with a symbolic name.
    # handle events that affect PP overall, otherwise pass to all active shows
    def handle_input_event(self,symbol,source):
        self.mon.log(self,"event received: "+symbol + ' from '+ source)
        if symbol == 'pp-terminate':
            self.handle_user_abort()
            
        elif symbol == 'pp-shutdown':
            self.shutdown_pressed('delay')
            
        elif symbol == 'pp-shutdownnow':
            # need root.after to grt out of st thread
            self.root.after(1,self.e_shutdown_pressed)
            return
        
        elif symbol == 'pp-exitpipresents':
            self.exitpipresents_required=True
            if self.show_manager.all_shows_exited() is True:
                # need root.after to grt out of st thread
                self.root.after(1,self.e_all_shows_ended_callback)
                return
            reason,message= self.show_manager.exit_all_shows()
        else:
            # events for shows affect the show and could cause it to exit.
            for show in self.show_manager.shows:
                show_obj=show[ShowManager.SHOW_OBJ]
                if show_obj is not None:
                    show_obj.handle_input_event(symbol)



    def shutdown_pressed(self, when):
        if when == 'delay':
            self.root.after(5000,self.on_shutdown_delay)
        else:
            self.shutdown_required=True
            if self.show_manager.all_shows_exited() is True:
               self.all_shows_ended_callback('normal','no shows running')
            else:
                # calls exit method of all shows, results in all_shows_closed_callback
                self.show_manager.exit_all_shows()           


    def on_shutdown_delay(self):
        # 5 second delay is up, if shutdown button still pressed then shutdown
        if self.gpiodriver.shutdown_pressed() is True:
            self.shutdown_required=True
            if self.show_manager.all_shows_exited() is True:
               self.all_shows_ended_callback('normal','no shows running')
            else:
                # calls exit method of all shows, results in all_shows_closed_callback
                self.show_manager.exit_all_shows()


    def handle_sigterm(self,signum,frame):
        self.mon.log(self,'SIGTERM received - '+ str(signum))
        self.terminate()


    def handle_user_abort(self):
        self.mon.log(self,'User abort received')
        self.terminate()

    def terminate(self):
        self.mon.log(self, "terminate received")
        self.terminate_required=True
        needs_termination=False
        for show in self.show_manager.shows:
            # print  show[ShowManager.SHOW_OBJ], show[ShowManager.SHOW_REF]
            if show[ShowManager.SHOW_OBJ] is not None:
                needs_termination=True
                self.mon.log(self,"Sent terminate to show "+ show[ShowManager.SHOW_REF])
                # call shows terminate method
                # eventually the show will exit and after all shows have exited all_shows_callback will be executed.
                show[ShowManager.SHOW_OBJ].terminate()
        if needs_termination is False:
            self.end('killed','killed - no termination of shows required')


# ******************************
# Ending Pi Presents after all the showers and players are closed
# **************************

    # callback from ShowManager when all shows have ended
    def all_shows_ended_callback(self,reason,message):
        self.canvas.config(bg=self.starter_show['background-colour'])
        if reason in ('killed','error') or self.shutdown_required is True or self.exitpipresents_required is True:
            self.end(reason,message)

    def end(self,reason,message):
        self.mon.log(self,"Pi Presents ending with reason: " + reason)
        if self.root is not None:
            self.root.destroy()
        self.tidy_up()
        # gc.collect()
        # print gc.garbage
        if reason == 'killed':
            if self.email_enabled is True and self.mailer.email_on_terminate is True:
                subject= '[Pi Presents] ' + self.unit + ': PP Exited with reason: Terminated'
                message = time.strftime("%Y-%m-%d %H:%M") + '\n ' + self.unit + '\n ' + self.interface + '\n ' + self.ip 
                self.send_email(reason,subject,message)
            self.mon.sched(self, "Pi Presents Terminated, au revoir\n")
            self.mon.log(self, "Pi Presents Terminated, au revoir")
                          
            # close logging files 
            self.mon.finish()
            sys.exit(101)
                          
        elif reason == 'error':
            if self.email_enabled is True and self.mailer.email_on_error is True:
                subject= '[Pi Presents] ' + self.unit + ': PP Exited with reason: Error'
                message_text = 'Error message: '+ message + '\n'+ time.strftime("%Y-%m-%d %H:%M") + '\n ' + self.unit + '\n ' + self.interface + '\n ' + self.ip 
                self.send_email(reason,subject,message_text)   
            self.mon.sched(self, "Pi Presents closing because of error, sorry\n")
            self.mon.log(self, "Pi Presents closing because of error, sorry")
                          
            # close logging files 
            self.mon.finish()
            sys.exit(102)

        else:           
            self.mon.sched(self,"Pi Presents  exiting normally, bye\n")
            self.mon.log(self,"Pi Presents  exiting normally, bye")
            
            # close logging files 
            self.mon.finish()
            if self.shutdown_required is True:
                # print 'SHUTDOWN'
                call (['sudo','shutdown','now','SHUTTING DOWN'])
            sys.exit(100)



    def init_network(self):

        timeout=int(self.options['nonetwork'])
        if timeout== 0:
            self.network_connected=False
            self.unit=''
            self.ip=''
            self.interface=''
            return
        
        self.network=Network()
        self.network_connected=False

        # try to connect to network
        self.mon.log (self, 'Waiting up to '+ str(timeout) + ' seconds for network')
        success=self.network.wait_for_network(timeout)
        if success is False:
            self.mon.warn(self,'Failed to connect to network after ' + str(timeout) + ' seconds')
            # tkMessageBox.showwarning("Pi Presents","Failed to connect to network so using fake-hwclock")
            return

        self.network_connected=True
        self.mon.sched (self, 'Time after network check is '+ time.strftime("%Y-%m-%d %H:%M.%S"))
        self.mon.log (self, 'Time after network check is '+ time.strftime("%Y-%m-%d %H:%M.%S"))

        # Get web configuration
        self.network_details=False
        network_options_file_path=self.pp_dir+os.sep+'pp_config'+os.sep+'pp_web.cfg'
        if not os.path.exists(network_options_file_path):
            self.mon.warn(self,"pp_web.cfg not found at "+network_options_file_path)
            return
        self.mon.log(self, 'Found pp_web.cfg in ' + network_options_file_path)

        self.network.read_config(network_options_file_path)
        self.unit=self.network.unit

        # get interface and IP details of preferred interface
        self.interface,self.ip = self.network.get_preferred_ip()
        if self.interface == '':
            self.network_connected=False
            return
        self.network_details=True
        self.mon.log (self, 'Network details ' + self.unit + ' ' + self.interface + ' ' +self.ip)


    def init_mailer(self):

        self.email_enabled=False
        email_file_path = self.pp_dir+os.sep+'pp_config'+os.sep+'pp_email.cfg'
        if not os.path.exists(email_file_path):
            self.mon.log(self,'pp_email.cfg not found at ' + email_file_path)
            return
        self.mon.log(self,'Found pp_email.cfg at ' + email_file_path)
        self.mailer=Mailer()
        self.mailer.read_config(email_file_path)
        # all Ok so can enable email if config file allows it.
        if self.mailer.email_allowed is True:
            self.email_enabled=True
            self.mon.log (self,'Email Enabled')



    def send_email(self,reason,subject,message):
        if self.try_connect() is False:
            return False
        else:
            success,error = self.mailer.send(subject,message)
            if success is False:
                self.mon.log(self, 'Failed to send email: ' + str(error))
                success,error=self.mailer.disconnect()
                if success is False:
                    self.mon.log(self,'Failed disconnect after send:' + str(error))
                return False
            else:
                self.mon.log(self,'Sent email for ' + reason)
                success,error=self.mailer.disconnect()
                if success is False:
                    self.mon.log(self,'Failed disconnect from email server ' + str(error))
                return True


    def try_connect(self):
        tries=1
        while True:
            success, error = self.mailer.connect()
            if success is True:
                return True
            else:
                self.mon.log(self,'Failed to connect to email SMTP server ' + str(tries) +  '\n ' +str(error))
                tries +=1
                if tries >5:
                    self.mon.log(self,'Failed to connect to email SMTP server after ' + str(tries))
                    return False

                
    
    # tidy up all the peripheral bits of Pi Presents
    def tidy_up(self):
        self.handle_monitor_command('on')
        self.mon.log(self, "Tidying Up")
        # turn screen blanking back on
        if self.options['noblank'] is True:
            call(["xset","s", "on"])
            call(["xset","s", "+dpms"])
            
        # tidy up animation and gpio
        if self.animate is not None:
            self.animate.terminate()
            
        if self.gpio_enabled==True:
            self.gpiodriver.terminate()

        if self.osc_enabled is True:
            self.oscdriver.terminate()
            
        # tidy up time of day scheduler
        if self.tod_enabled is True:
            self.tod.terminate()
Example #31
0
class PPEditor(object):

    # ***************************************
    # INIT
    # ***************************************

    def __init__(self):
    
        self.editor_issue="1.3"

        # get command options
        self.command_options=ed_options()

        # get directory holding the code
        self.pp_dir=sys.path[0]
            
        if not os.path.exists(self.pp_dir+os.sep+"pp_editor.py"):
            tkMessageBox.showwarning("Pi Presents","Bad Application Directory")
            exit()
            
          
        # Initialise logging
        Monitor.log_path=self.pp_dir
        self.mon=Monitor()
        self.mon.init()
        
        Monitor.classes  = ['PPEditor','EditItem','Validator']

        Monitor.log_level = int(self.command_options['debug'])

        self.mon.log (self, "Pi Presents Editor is starting")
        self.mon.log (self," OS and separator " + os.name +'  ' + os.sep)
        self.mon.log(self,"sys.path[0] -  location of code: code "+sys.path[0])


        # set up the gui
 
        # root is the Tkinter root widget
        self.root = Tk()
        self.root.title("Editor for Pi Presents")

        # self.root.configure(background='grey')

        self.root.resizable(False,False)

        # define response to main window closing
        self.root.protocol ("WM_DELETE_WINDOW", self.app_exit)

        # bind some display fields
        self.filename = StringVar()
        self.display_selected_track_title = StringVar()
        self.display_show = StringVar()


        # define menu
        menubar = Menu(self.root)

        profilemenu = Menu(menubar, tearoff=0, bg="grey", fg="black")
        profilemenu.add_command(label='Open', command = self.open_existing_profile)
        profilemenu.add_command(label='Validate', command = self.validate_profile)
        menubar.add_cascade(label='Profile', menu = profilemenu)

        ptypemenu = Menu(profilemenu, tearoff=0, bg="grey", fg="black")
        ptypemenu.add_command(label='Exhibit', command = self.new_exhibit_profile)
        ptypemenu.add_command(label='Media Show', command = self.new_mediashow_profile)
        ptypemenu.add_command(label='Art Media Show', command = self.new_artmediashow_profile)
        ptypemenu.add_command(label='Menu', command = self.new_menu_profile)
        ptypemenu.add_command(label='Presentation', command = self.new_presentation_profile)
        ptypemenu.add_command(label='Interactive', command = self.new_interactive_profile)
        ptypemenu.add_command(label='Live Show', command = self.new_liveshow_profile)
        ptypemenu.add_command(label='Art Live Show', command = self.new_artliveshow_profile)
        ptypemenu.add_command(label='RadioButton Show', command = self.new_radiobuttonshow_profile)
        ptypemenu.add_command(label='Hyperlink Show', command = self.new_hyperlinkshow_profile)
        ptypemenu.add_command(label='Blank', command = self.new_blank_profile)
        profilemenu.add_cascade(label='New from Template', menu = ptypemenu)
        
        showmenu = Menu(menubar, tearoff=0, bg="grey", fg="black")
        showmenu.add_command(label='Delete', command = self.remove_show)
        showmenu.add_command(label='Edit', command = self.m_edit_show)
        showmenu.add_command(label='Copy To', command = self.copy_show)
        menubar.add_cascade(label='Show', menu = showmenu)

        stypemenu = Menu(showmenu, tearoff=0, bg="grey", fg="black")
        stypemenu.add_command(label='Menu', command = self.add_menushow)
        stypemenu.add_command(label='MediaShow', command = self.add_mediashow)
        stypemenu.add_command(label='LiveShow', command = self.add_liveshow)
        stypemenu.add_command(label='HyperlinkShow', command = self.add_hyperlinkshow)
        stypemenu.add_command(label='RadioButtonShow', command = self.add_radiobuttonshow)
        stypemenu.add_command(label='ArtMediaShow', command = self.add_artmediashow)
        stypemenu.add_command(label='ArtLiveShow', command = self.add_artliveshow)
        showmenu.add_cascade(label='Add', menu = stypemenu)
        
        medialistmenu = Menu(menubar, tearoff=0, bg="grey", fg="black")
        menubar.add_cascade(label='MediaList', menu = medialistmenu)
        medialistmenu.add_command(label='Add', command = self.add_medialist)
        medialistmenu.add_command(label='Delete', command = self.remove_medialist)
        medialistmenu.add_command(label='Copy To', command = self.copy_medialist)
      
        trackmenu = Menu(menubar, tearoff=0, bg="grey", fg="black")
        trackmenu.add_command(label='Delete', command = self.remove_track)
        trackmenu.add_command(label='Edit', command = self.m_edit_track)
        trackmenu.add_command(label='Add from Dir', command = self.add_tracks_from_dir)
        trackmenu.add_command(label='Add from File', command = self.add_track_from_file)


        menubar.add_cascade(label='Track', menu = trackmenu)

        typemenu = Menu(trackmenu, tearoff=0, bg="grey", fg="black")
        typemenu.add_command(label='Video', command = self.new_video_track)
        typemenu.add_command(label='Audio', command = self.new_audio_track)
        typemenu.add_command(label='Image', command = self.new_image_track)
        typemenu.add_command(label='Web', command = self.new_web_track)
        typemenu.add_command(label='Message', command = self.new_message_track)
        typemenu.add_command(label='Show', command = self.new_show_track)
        typemenu.add_command(label='Menu Track', command = self.new_menu_track)
        trackmenu.add_cascade(label='New', menu = typemenu)

        oscmenu = Menu(menubar, tearoff=0, bg="grey", fg="black")
        menubar.add_cascade(label='OSC', menu = oscmenu)
        oscmenu.add_command(label='Create OSC configuration', command = self.create_osc)
        oscmenu.add_command(label='Edit OSC Configuration', command = self.edit_osc)
        oscmenu.add_command(label='Delete OSC Configuration', command = self.delete_osc)


        toolsmenu = Menu(menubar, tearoff=0, bg="grey", fg="black")
        menubar.add_cascade(label='Tools', menu = toolsmenu)
        toolsmenu.add_command(label='Update All', command = self.update_all)
        
        optionsmenu = Menu(menubar, tearoff=0, bg="grey", fg="black")
        menubar.add_cascade(label='Options', menu = optionsmenu)
        optionsmenu.add_command(label='Edit', command = self.edit_options)

        helpmenu = Menu(menubar, tearoff=0, bg="grey", fg="black")
        menubar.add_cascade(label='Help', menu = helpmenu)
        helpmenu.add_command(label='Help', command = self.show_help)
        helpmenu.add_command(label='About', command = self.about)
         
        self.root.config(menu=menubar)

        top_frame=Frame(self.root)
        top_frame.pack(side=TOP)
        bottom_frame=Frame(self.root)
        bottom_frame.pack(side=TOP, fill=BOTH, expand=1)        

        left_frame=Frame(bottom_frame, padx=5)
        left_frame.pack(side=LEFT)
        middle_frame=Frame(bottom_frame,padx=5)
        middle_frame.pack(side=LEFT)              
        right_frame=Frame(bottom_frame,padx=5,pady=10)
        right_frame.pack(side=LEFT)
        updown_frame=Frame(bottom_frame,padx=5)
        updown_frame.pack(side=LEFT)
        
        tracks_title_frame=Frame(right_frame)
        tracks_title_frame.pack(side=TOP)
        tracks_label = Label(tracks_title_frame, text="Tracks in Selected Medialist")
        tracks_label.pack()
        tracks_frame=Frame(right_frame)
        tracks_frame.pack(side=TOP)
        shows_title_frame=Frame(left_frame)
        shows_title_frame.pack(side=TOP)
        shows_label = Label(shows_title_frame, text="Shows")
        shows_label.pack()
        shows_frame=Frame(left_frame)
        shows_frame.pack(side=TOP)
        shows_title_frame=Frame(left_frame)
        shows_title_frame.pack(side=TOP)
        medialists_title_frame=Frame(left_frame)
        medialists_title_frame.pack(side=TOP)
        medialists_label = Label(medialists_title_frame, text="Medialists")
        medialists_label.pack()
        medialists_frame=Frame(left_frame)
        medialists_frame.pack(side=LEFT)
        
        # define buttons 

        add_button = Button(middle_frame, width = 5, height = 2, text='Edit\nShow',
                            fg='black', command = self.m_edit_show, bg="light grey")
        add_button.pack(side=RIGHT)
        
        add_button = Button(updown_frame, width = 5, height = 1, text='Add',
                            fg='black', command = self.add_track_from_file, bg="light grey")
        add_button.pack(side=TOP)
        add_button = Button(updown_frame, width = 5, height = 1, text='Edit',
                            fg='black', command = self.m_edit_track, bg="light grey")
        add_button.pack(side=TOP)
        add_button = Button(updown_frame, width = 5, height = 1, text='Up',
                            fg='black', command = self.move_track_up, bg="light grey")
        add_button.pack(side=TOP)
        add_button = Button(updown_frame, width = 5, height = 1, text='Down',
                            fg='black', command = self.move_track_down, bg="light grey")
        add_button.pack(side=TOP)


        # define display of showlist 
        scrollbar = Scrollbar(shows_frame, orient=VERTICAL)
        self.shows_display = Listbox(shows_frame, selectmode=SINGLE, height=12,
                                     width = 40, bg="white",activestyle=NONE,
                                     fg="black", yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.shows_display.yview)
        scrollbar.pack(side=RIGHT, fill=Y)
        self.shows_display.pack(side=LEFT, fill=BOTH, expand=1)
        self.shows_display.bind("<ButtonRelease-1>", self.e_select_show)

    
        # define display of medialists
        scrollbar = Scrollbar(medialists_frame, orient=VERTICAL)
        self.medialists_display = Listbox(medialists_frame, selectmode=SINGLE, height=12,
                                          width = 40, bg="white",activestyle=NONE,
                                          fg="black",yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.medialists_display.yview)
        scrollbar.pack(side=RIGHT, fill=Y)
        self.medialists_display.pack(side=LEFT,  fill=BOTH, expand=1)
        self.medialists_display.bind("<ButtonRelease-1>", self.select_medialist)


        # define display of tracks
        scrollbar = Scrollbar(tracks_frame, orient=VERTICAL)
        self.tracks_display = Listbox(tracks_frame, selectmode=SINGLE, height=25,
                                      width = 40, bg="white",activestyle=NONE,
                                      fg="black",yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.tracks_display.yview)
        scrollbar.pack(side=RIGHT, fill=Y)
        self.tracks_display.pack(side=LEFT,fill=BOTH, expand=1)
        self.tracks_display.bind("<ButtonRelease-1>", self.e_select_track)


        # initialise editor options class and OSC config class
        self.options=Options(self.pp_dir) # creates options file in code directory if necessary
        self.osc_config=OSCConfig()
        
        # initialise variables      
        self.init()
        
        # and enter Tkinter event loop
        self.root.mainloop()        


    # ***************************************
    # INIT AND EXIT
    # ***************************************
    def app_exit(self):
        self.root.destroy()
        exit()


    def init(self):
        self.options.read()
        self.pp_home_dir = self.options.pp_home_dir
        self.pp_profiles_offset = self.options.pp_profiles_offset
        self.initial_media_dir = self.options.initial_media_dir
        self.mon.log(self,"Data Home from options is "+self.pp_home_dir)
        self.mon.log(self,"Current Profiles Offset from options is "+self.pp_profiles_offset)
        self.mon.log(self,"Initial Media from options is "+self.initial_media_dir)
        self.pp_profile_dir=''
        self.osc_config_file = ''
        self.current_medialist=None
        self.current_showlist=None
        self.current_show=None
        self.shows_display.delete(0,END)
        self.medialists_display.delete(0,END)
        self.tracks_display.delete(0,END)



    # ***************************************
    # MISCELLANEOUS
    # ***************************************

    def edit_options(self):
        """edit the options then read them from file"""
        eo = OptionsDialog(self.root, self.options.options_file,'Edit Options')
        if eo.result is True: self.init()



    def show_help (self):
        tkMessageBox.showinfo("Help","Read 'manual.pdf'")
  

    def about (self):
        tkMessageBox.showinfo("About","Editor for Pi Presents Profiles\n"
                              +"For profile version: " + self.editor_issue + "\nAuthor: Ken Thompson"
                              +"\nWebsite: http://pipresents.wordpress.com/")

    def validate_profile(self):
        val =Validator()
        val.validate_profile(self.root,self.pp_dir,self.pp_home_dir,self.pp_profile_dir,self.editor_issue,True)


    # **************
    # OSC CONFIGURATION
    # **************

    def create_osc(self):
        if self.pp_profile_dir=='':
            return
        if self.osc_config.read(self.osc_config_file) is False:
            iodir=self.pp_profile_dir+os.sep+'pp_io_config'
            if not os.path.exists(iodir):
                os.makedirs(iodir)
            self.osc_config.create(self.osc_config_file)

    def edit_osc(self):
        if self.osc_config.read(self.osc_config_file) is False:
            # print 'no config file'
            return
        osc_ut=OSCUnitType(self.root,self.osc_config.this_unit_type)
        self.req_unit_type=osc_ut.result
        if self.req_unit_type != None:
            # print self.req_unit_type
            eosc = OSCEditor(self.root, self.osc_config_file,self.req_unit_type,'Edit OSC Configuration')
            
    def delete_osc(self):
        if self.osc_config.read(self.osc_config_file) is False:
            return
        os.rename(self.osc_config_file,self.osc_config_file+'.bak')
        

    
    # **************
    # PROFILES
    # **************

    def open_existing_profile(self):
        initial_dir=self.pp_home_dir+os.sep+"pp_profiles"+self.pp_profiles_offset
        if os.path.exists(initial_dir) is False:
            self.mon.err(self,"Profiles directory not found: " + initial_dir + "\n\nHint: Data Home option must end in pp_home")
            return
        dir_path=tkFileDialog.askdirectory(initialdir=initial_dir)
        # dir_path="C:\Users\Ken\pp_home\pp_profiles\\ttt"
        if len(dir_path)>0:
            self.open_profile(dir_path)
        

    def open_profile(self,dir_path):
        showlist_file = dir_path + os.sep + "pp_showlist.json"
        if os.path.exists(showlist_file) is False:
            self.mon.err(self,"Not a Profile: " + dir_path + "\n\nHint: Have you opened the profile directory?")
            return
        self.pp_profile_dir = dir_path
        self.root.title("Editor for Pi Presents - "+ self.pp_profile_dir)
        if self.open_showlist(self.pp_profile_dir) is False:
            self.init()
            return
        self.open_medialists(self.pp_profile_dir)
        self.refresh_tracks_display()
        self.osc_config_file=self.pp_profile_dir+os.sep+'pp_io_config'+os.sep+'osc.cfg'


    def new_profile(self,profile):
        d = Edit1Dialog(self.root,"New Profile","Name", "")
        if d .result  is  None:
            return
        name=str(d.result)
        if name == "":
            tkMessageBox.showwarning("New Profile","Name is blank")
            return
        to = self.pp_home_dir + os.sep + "pp_profiles"+ self.pp_profiles_offset + os.sep + name
        if os.path.exists(to) is  True:
            tkMessageBox.showwarning( "New Profile","Profile exists\n(%s)" % to )
            return
        shutil.copytree(profile, to, symlinks=False, ignore=None)
        self.open_profile(to)


        
    def new_exhibit_profile(self):
        profile = self.pp_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_exhibit_1p3'
        self.new_profile(profile)

    def new_interactive_profile(self):
        profile = self.pp_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_interactive_1p3'
        self.new_profile(profile)

    def new_menu_profile(self):
        profile = self.pp_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_menu_1p3'
        self.new_profile(profile)

    def new_presentation_profile(self):
        profile = self.pp_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_presentation_1p3'
        self.new_profile(profile)

    def new_blank_profile(self):
        profile = self.pp_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep +"ppt_blank_1p3"
        self.new_profile(profile)

    def new_mediashow_profile(self):
        profile = self.pp_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_mediashow_1p3'
        self.new_profile(profile)
        
    def new_liveshow_profile(self):
        profile = self.pp_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_liveshow_1p3'
        self.new_profile(profile)

    def new_artmediashow_profile(self):
        profile = self.pp_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_artmediashow_1p3'
        self.new_profile(profile)
        
    def new_artliveshow_profile(self):
        profile = self.pp_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_artliveshow_1p3'
        self.new_profile(profile)

    def new_radiobuttonshow_profile(self):
        profile = self.pp_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_radiobuttonshow_1p3'
        self.new_profile(profile)

    def new_hyperlinkshow_profile(self):
        profile = self.pp_dir+os.sep+'pp_resources'+os.sep+'pp_templates'+os.sep + 'ppt_hyperlinkshow_1p3'
        self.new_profile(profile)

    # ***************************************
    # Shows
    # ***************************************

    def open_showlist(self,profile_dir):
        showlist_file = profile_dir + os.sep + "pp_showlist.json"
        if os.path.exists(showlist_file) is False:
            self.mon.err(self,"showlist file not found at " + profile_dir + "\n\nHint: Have you opened the profile directory?")
            self.app_exit()
        self.current_showlist=ShowList()
        self.current_showlist.open_json(showlist_file)
        if float(self.current_showlist.sissue())<float(self.editor_issue) or  (self.command_options['forceupdate']  is  True and float(self.current_showlist.sissue()) == float(self.editor_issue)):
            self.update_profile()
            self.mon.err(self,"Version of profile has been updated to "+self.editor_issue+", please re-open")
            return False
        if float(self.current_showlist.sissue())>float(self.editor_issue):
            self.mon.err(self,"Version of profile is greater than editor, must exit")
            self.app_exit()
        self.refresh_shows_display()
        return True


    def save_showlist(self,showlist_dir):
        if self.current_showlist is not None:
            showlist_file = showlist_dir + os.sep + "pp_showlist.json"
            self.current_showlist.save_list(showlist_file)
            
    def add_mediashow(self):
        self.add_show(PPdefinitions.new_shows['mediashow'])

    def add_liveshow(self):
        self.add_show(PPdefinitions.new_shows['liveshow'])

    def add_radiobuttonshow(self):
        self.add_show(PPdefinitions.new_shows['radiobuttonshow'])

    def add_hyperlinkshow(self):
        self.add_show(PPdefinitions.new_shows['hyperlinkshow'])

    def add_artliveshow(self):
        self.add_show(PPdefinitions.new_shows['artliveshow'])

    def add_artmediashow(self):
        self.add_show(PPdefinitions.new_shows['artmediashow'])
        
    def add_menushow(self):
        self.add_show(PPdefinitions.new_shows['menu'])

    def add_start(self):  
        self.add_show(PPdefinitions.new_shows['start'])


    def add_show(self,default):
        # append it to the showlist and then add the medialist
        if self.current_showlist is not None:
            d = Edit1Dialog(self.root,"AddShow","Show Reference", "")
            if d.result  is  None:
                return
            name=str(d.result)
            if name == "":
                tkMessageBox.showwarning("Add Show","Name is blank")
                return
                                         
            if self.current_showlist.index_of_show(name) != -1:
                tkMessageBox.showwarning("Add Show","A Show with this name already exists")
                return            
            copied_show=self.current_showlist.copy(default,name)
            mediafile=self.add_medialist(name)
            if mediafile != '':
                copied_show['medialist']=mediafile
            self.current_showlist.append(copied_show)
            self.save_showlist(self.pp_profile_dir)
            self.refresh_shows_display()

            
    def remove_show(self):
        if  self.current_showlist is not None and self.current_showlist.length()>0 and self.current_showlist.show_is_selected():
            if tkMessageBox.askokcancel("Delete Show","Delete Show"):
                index= self.current_showlist.selected_show_index()
                self.current_showlist.remove(index)
                self.save_showlist(self.pp_profile_dir)
                self.refresh_shows_display()

    def show_refs(self):
        _show_refs=[]
        for index in range(self.current_showlist.length()):
            if self.current_showlist.show(index)['show-ref'] != "start":
                _show_refs.append(copy.deepcopy(self.current_showlist.show(index)['show-ref']))
        return _show_refs
 
    def refresh_shows_display(self):
        self.shows_display.delete(0,self.shows_display.size())
        for index in range(self.current_showlist.length()):
            self.shows_display.insert(END, self.current_showlist.show(index)['title']+"   ["+self.current_showlist.show(index)['show-ref']+"]")        
        if self.current_showlist.show_is_selected():
            self.shows_display.itemconfig(self.current_showlist.selected_show_index(),fg='red')            
            self.shows_display.see(self.current_showlist.selected_show_index())

            
    def e_select_show(self,event):
        if self.current_showlist is not None and self.current_showlist.length()>0:
            mouse_item_index=int(event.widget.curselection()[0])
            self.current_showlist.select(mouse_item_index)
            self.refresh_shows_display()

    def copy_show(self):
        if  self.current_showlist is not None and self.current_showlist.show_is_selected():
            self.add_show(self.current_showlist.selected_show())

        
    def m_edit_show(self):
        self.edit_show(PPdefinitions.show_types,PPdefinitions.show_field_specs)
        
     

    def edit_show(self,show_types,field_specs):
        if self.current_showlist is not None and self.current_showlist.show_is_selected():
            d=EditItem(self.root,"Edit Show",self.current_showlist.selected_show(),show_types,field_specs,self.show_refs(),
                       self.initial_media_dir,self.pp_home_dir,'show')
            if d.result  is  True:

                self.save_showlist(self.pp_profile_dir)
                self.refresh_shows_display()

 

    # ***************************************
    #   Medialists
    # ***************************************

    def open_medialists(self,profile_dir):
        self.medialists = []
        for this_file in os.listdir(profile_dir):
            if this_file.endswith(".json") and this_file not in ('pp_showlist.json','schedule.json'):
                self.medialists = self.medialists + [this_file]
        self.medialists_display.delete(0,self.medialists_display.size())
        for index in range (len(self.medialists)):
            self.medialists_display.insert(END, self.medialists[index])
        self.current_medialists_index=-1
        self.current_medialist=None


    def add_medialist(self,name=None):
        if name is None:
            d = Edit1Dialog(self.root,"Add Medialist","File", "")
            if d.result  is  None:
                return ''
            name=str(d.result)
            if name == "":
                tkMessageBox.showwarning("Add medialist","Name is blank")
                return ''
            
        if not name.endswith(".json"):
            name=name+(".json")
                
        path = self.pp_profile_dir + os.sep + name
        if os.path.exists(path) is  True:
            tkMessageBox.showwarning("Add medialist","Medialist file exists\n(%s)" % path)
            return ''
        nfile = open(path,'wb')
        nfile.write("{")
        nfile.write("\"issue\":  \""+self.editor_issue+"\",\n")
        nfile.write("\"tracks\": [")
        nfile.write("]")
        nfile.write("}")
        nfile.close()
        # append it to the list
        self.medialists.append(copy.deepcopy(name))
        # add title to medialists display
        self.medialists_display.insert(END, name)  
        # and set it as the selected medialist
        self.refresh_medialists_display()
        return name


    def copy_medialist(self,to_file=None):
        if self.current_medialist is not None:
            #from_file= self.current_medialist 
            from_file= self.medialists[self.current_medialists_index]
            if to_file is None:
                d = Edit1Dialog(self.root,"Copy Medialist","File", "")
                if d.result  is  None:
                    return ''
                to_file=str(d.result)
                if to_file == "":
                    tkMessageBox.showwarning("Copy medialist","Name is blank")
                    return ''
                
            success_file = self.copy_medialist_file(from_file,to_file)
            if success_file =='':
                return ''

            # append it to the list
            self.medialists.append(copy.deepcopy(success_file))
            # add title to medialists display
            self.medialists_display.insert(END, success_file)
            # and reset  selected medialist
            self.current_medialist=None
            self.refresh_medialists_display()
            self.refresh_tracks_display()
            return success_file
        else:
            return ''

    def copy_medialist_file(self,from_file,to_file):
        if not to_file.endswith(".json"):
            to_file+=(".json")
                
        to_path = self.pp_profile_dir + os.sep + to_file
        if os.path.exists(to_path) is  True:
            tkMessageBox.showwarning("Copy medialist","Medialist file exists\n(%s)" % to_path)
            return ''
        
        from_path= self.pp_profile_dir + os.sep + from_file
        if os.path.exists(from_path) is  False:
            tkMessageBox.showwarning("Copy medialist","Medialist file not found\n(%s)" % from_path)
            return ''

        shutil.copy(from_path,to_path)
        return to_file


    def remove_medialist(self):
        if self.current_medialist is not None:
            if tkMessageBox.askokcancel("Delete Medialist","Delete Medialist"):
                os.remove(self.pp_profile_dir+ os.sep + self.medialists[self.current_medialists_index])
                self.open_medialists(self.pp_profile_dir)
                self.refresh_medialists_display()
                self.refresh_tracks_display()


    def select_medialist(self,event):
        """
        user clicks on a medialst in a profile so try and select it.
        """
        # needs forgiving int for possible tkinter upgrade
        if len(self.medialists)>0:
            self.current_medialists_index=int(event.widget.curselection()[0])
            self.current_medialist=MediaList('ordered')
            if not self.current_medialist.open_list(self.pp_profile_dir+ os.sep + self.medialists[self.current_medialists_index],self.current_showlist.sissue()):
                self.mon.err(self,"medialist is a different version to showlist: "+ self.medialists[self.current_medialists_index])
                self.app_exit()        
            self.refresh_tracks_display()
            self.refresh_medialists_display()


    def refresh_medialists_display(self):
        self.medialists_display.delete(0,len(self.medialists))
        for index in range (len(self.medialists)):
            self.medialists_display.insert(END, self.medialists[index])
        if self.current_medialist is not None:
            self.medialists_display.itemconfig(self.current_medialists_index,fg='red')
            self.medialists_display.see(self.current_medialists_index)

    def save_medialist(self):
        basefile=self.medialists[self.current_medialists_index]
        # print type(basefile)
        # basefile=str(basefile)
        # print type(basefile)
        medialist_file = self.pp_profile_dir+ os.sep + basefile
        self.current_medialist.save_list(medialist_file)

  
          
    # ***************************************
    #   Tracks
    # ***************************************
          
    def refresh_tracks_display(self):
        self.tracks_display.delete(0,self.tracks_display.size())
        if self.current_medialist is not None:
            for index in range(self.current_medialist.length()):
                if self.current_medialist.track(index)['track-ref'] != '':
                    track_ref_string="  ["+self.current_medialist.track(index)['track-ref']+"]"
                else:
                    track_ref_string=""
                self.tracks_display.insert(END, self.current_medialist.track(index)['title']+track_ref_string)        
            if self.current_medialist.track_is_selected():
                self.tracks_display.itemconfig(self.current_medialist.selected_track_index(),fg='red')            
                self.tracks_display.see(self.current_medialist.selected_track_index())
            
    def e_select_track(self,event):
        if self.current_medialist is not None and self.current_medialist.length()>0:
            mouse_item_index=int(event.widget.curselection()[0])
            self.current_medialist.select(mouse_item_index)
            self.refresh_tracks_display()

    def m_edit_track(self):
        self.edit_track(PPdefinitions.track_types,PPdefinitions.track_field_specs)

    def edit_track(self,track_types,field_specs):      
        if self.current_medialist is not None and self.current_medialist.track_is_selected():
            d=EditItem(self.root,"Edit Track",self.current_medialist.selected_track(),track_types,field_specs,
                       self.show_refs(),self.initial_media_dir,self.pp_home_dir,'track')
            if d.result  is  True:
                self.save_medialist()
            self.refresh_tracks_display()

    def move_track_up(self):
        if self.current_medialist is not None and self.current_medialist.track_is_selected():
            self.current_medialist.move_up()
            self.refresh_tracks_display()
            self.save_medialist()

    def move_track_down(self):
        if self.current_medialist is not None and self.current_medialist.track_is_selected():
            self.current_medialist.move_down()
            self.refresh_tracks_display()
            self.save_medialist()
        
    def new_track(self,fields,values):
        if self.current_medialist is not None:
            # print '\nfields ', fields
            # print '\nvalues ', values
            new_track=copy.deepcopy(fields)
            # print ',\new track ',new_track
            self.current_medialist.append(new_track)
            # print '\nbefore values ',self.current_medialist.print_list()
            if values is not None:
                self.current_medialist.update(self.current_medialist.length()-1,values)
            self.current_medialist.select(self.current_medialist.length()-1)
            self.refresh_tracks_display()
            self.save_medialist()

    def new_message_track(self):
        self.new_track(PPdefinitions.new_tracks['message'],None)
            
    def new_video_track(self):
        self.new_track(PPdefinitions.new_tracks['video'],None)
  
    def new_audio_track(self):
        self.new_track(PPdefinitions.new_tracks['audio'],None)

    def new_web_track(self):
        self.new_track(PPdefinitions.new_tracks['web'],None)
        
    def new_image_track(self):
        self.new_track(PPdefinitions.new_tracks['image'],None)

    def new_show_track(self):
        self.new_track(PPdefinitions.new_tracks['show'],None)

    def new_menu_track(self):
        self.new_track(PPdefinitions.new_tracks['menu'],None)
 
    def remove_track(self):
        if  self.current_medialist is not None and self.current_medialist.length()>0 and self.current_medialist.track_is_selected():
            if tkMessageBox.askokcancel("Delete Track","Delete Track"):
                index= self.current_medialist.selected_track_index()
                self.current_medialist.remove(index)
                self.save_medialist()
                self.refresh_tracks_display()
                
    def add_track_from_file(self):
        if self.current_medialist is None: return
        # print "initial directory ", self.options.initial_media_dir
        files_path=tkFileDialog.askopenfilename(initialdir=self.options.initial_media_dir, multiple=True)
        # fix for tkinter bug
        files_path =  self.root.tk.splitlist(files_path)
        for file_path in files_path:
            file_path=os.path.normpath(file_path)
            # print "file path ", file_path
            self.add_track(file_path)
        self.save_medialist()

    def add_tracks_from_dir(self):
        if self.current_medialist is None: return
        image_specs =[PPdefinitions.IMAGE_FILES,PPdefinitions.VIDEO_FILES,PPdefinitions.AUDIO_FILES,
                      PPdefinitions.WEB_FILES,('All files', '*')]
        # last one is ignored in finding files in directory, for dialog box only
        directory=tkFileDialog.askdirectory(initialdir=self.options.initial_media_dir)
        # deal with tuple returned on Cancel
        if len(directory) == 0: return
        # make list of exts we recognise
        exts = []
        for image_spec in image_specs[:-1]:
            image_list=image_spec[1:]
            for ext in image_list:
                exts.append(copy.deepcopy(ext))
        for this_file in os.listdir(directory):
            (root_file,ext_file)= os.path.splitext(this_file)
            if ext_file.lower() in exts:
                file_path=directory+os.sep+this_file
                # print "file path before ", file_path
                file_path=os.path.normpath(file_path)
                # print "file path after ", file_path
                self.add_track(file_path)
        self.save_medialist()


    def add_track(self,afile):
        relpath = os.path.relpath(afile,self.pp_home_dir)
        # print "relative path ",relpath
        common = os.path.commonprefix([afile,self.pp_home_dir])
        # print "common ",common
        if common.endswith("pp_home")  is  False:
            location = afile
        else:
            location = "+" + os.sep + relpath
            location = string.replace(location,'\\','/')
            # print "location ",location
        (root,title)=os.path.split(afile)
        (root,ext)= os.path.splitext(afile)
        if ext.lower() in PPdefinitions.IMAGE_FILES:
            self.new_track(PPdefinitions.new_tracks['image'],{'title':title,'track-ref':'','location':location})
        elif ext.lower() in PPdefinitions.VIDEO_FILES:
            self.new_track(PPdefinitions.new_tracks['video'],{'title':title,'track-ref':'','location':location})
        elif ext.lower() in PPdefinitions.AUDIO_FILES:
            self.new_track(PPdefinitions.new_tracks['audio'],{'title':title,'track-ref':'','location':location})
        elif ext.lower() in PPdefinitions.WEB_FILES:
            self.new_track(PPdefinitions.new_tracks['web'],{'title':title,'track-ref':'','location':location})
        else:
            self.mon.err(self,afile + " - cannot determine track type, use menu track>new")



    # *********************************************
    # UPDATE PROFILE
    # **********************************************

    def update_all(self):
        self.init()
        for profile_file in os.listdir(self.pp_home_dir+os.sep+'pp_profiles'+self.pp_profiles_offset):
            # self.mon.log (self,"Updating "+profile_file)
            self.pp_profile_dir = self.pp_home_dir+os.sep+'pp_profiles'+self.pp_profiles_offset + os.sep + profile_file
            if not os.path.exists(self.pp_profile_dir+os.sep+"pp_showlist.json"):
                tkMessageBox.showwarning("Pi Presents","Not a profile, skipping "+self.pp_profile_dir)
            else:
                self.current_showlist=ShowList()
                self.current_showlist.open_json(self.pp_profile_dir+os.sep+"pp_showlist.json")
                self.mon.log (self,"Version of profile "+ profile_file + ' is ' + self.current_showlist.sissue())
                if float(self.current_showlist.sissue())<float(self.editor_issue):
                    self.mon.log(self,"Version of profile "+profile_file+ "  is being updated to "+self.editor_issue)
                    self.update_profile()
                elif (self.command_options['forceupdate']  is  True and float(self.current_showlist.sissue()) == float(self.editor_issue)):
                    self.mon.log(self, "Forced updating of " + profile_file + ' to '+self.editor_issue)
                    self.update_profile()
                elif float(self.current_showlist.sissue())>float(self.editor_issue):
                    tkMessageBox.showwarning("Pi Presents", "Version of profile " +profile_file+ " is greater than editor, skipping")
                else:
                    self.mon.log(self," Skipping Profile " + profile_file + " It is already up to date ")
        self.init()
        tkMessageBox.showwarning("Pi Presents","All profiles updated")
            
    def update_profile(self):

        self.update_medialists()   # medialists and their tracks
        self.update_shows()         #shows in showlist, also creates menu tracks for 1.2>1.3
        

    def update_shows(self):
        # open showlist into a list of dictionaries
        self.mon.log (self,"Updating show ")
        ifile  = open(self.pp_profile_dir + os.sep + "pp_showlist.json", 'rb')
        shows = json.load(ifile)['shows']
        ifile.close()

        # special 1.2>1.3 create menu medialists with menu track from show
        #go through shows - if type = menu and version is greater copy its medialist to a new medialist with  name = <show-ref>-menu1p3.json
        for show in shows:
            #create a new medialist medialist != show-ref as menus can't now share medialists
            if show['type']=='menu' and float(self.current_showlist.sissue())<float(self.editor_issue):
                to_file=show['show-ref']+'-menu1p3.json'
                from_file = show['medialist']
                if to_file != from_file:
                    self.copy_medialist_file(from_file,to_file)
                else:
                    self.mon.warn(self, 'medialist file' + to_file + ' already exists, must exit with incomplete update')
                    return False

                #update the reference to the medialist
                show['medialist']=to_file
                
                #delete show fields so they are recreated with new default content
                del show['controls']
                
                # open the  medialist and add the menu track then populate some of its fields from the show
                ifile  = open(self.pp_profile_dir + os.sep + to_file, 'rb')
                tracks = json.load(ifile)['tracks']
                ifile.close()
                
                new_track=copy.deepcopy(PPdefinitions.new_tracks['menu'])
                tracks.append(copy.deepcopy(new_track))

                # copy menu parameters from menu show to menu track and init values of some              
                self.transfer_show_params(show,tracks,'menu-track',("entry-colour","entry-font", "entry-select-colour", 
                                                                    "hint-colour", "hint-font", "hint-text", "hint-x","hint-y",
                                                                    "menu-bullet", "menu-columns", "menu-direction", "menu-guidelines",
                                                                    "menu-horizontal-padding", "menu-horizontal-separation", "menu-icon-height", "menu-icon-mode",
                                                                    "menu-icon-width", "menu-rows", "menu-strip", "menu-strip-padding",  "menu-text-height", "menu-text-mode", "menu-text-width",
                                                                     "menu-vertical-padding", "menu-vertical-separation",
                                                                    "menu-window"))
                                          
                # and save the medialist
                dic={'issue':self.editor_issue,'tracks':tracks}
                ofile  = open(self.pp_profile_dir + os.sep + to_file, "wb")
                json.dump(dic,ofile,sort_keys=True,indent=1)
                # end for show in shows

        #update the fields in  all shows
        replacement_shows=self.update_shows_in_showlist(shows)
        dic={'issue':self.editor_issue,'shows':replacement_shows}
        ofile  = open(self.pp_profile_dir + os.sep + "pp_showlist.json", "wb")
        json.dump(dic,ofile,sort_keys=True,indent=1)
        return True


    def transfer_show_params(self,show,tracks,track_ref,fields):
        # find the menu track in medialist
        for index,track in enumerate(tracks):
            if track['track-ref']== 'menu-track':
                break
            
        #update some fields with new default content
        tracks[index]['links']=PPdefinitions.new_tracks['menu']['links']

        #transfer values from show to track
        for field in fields:
            tracks[index][field]=show[field]
            # print show[field], tracks[index][field]
            pass
            
        
                                          

    def update_medialists(self):
         # UPDATE MEDIALISTS AND THEIR TRACKS
        for this_file in os.listdir(self.pp_profile_dir):
            if this_file.endswith(".json") and this_file not in  ('pp_showlist.json','schedule.json'):
                self.mon.log (self,"Updating medialist " + this_file)
                # open a medialist and update its tracks
                ifile  = open(self.pp_profile_dir + os.sep + this_file, 'rb')
                tracks = json.load(ifile)['tracks']
                ifile.close()
                replacement_tracks=self.update_tracks(tracks)
                dic={'issue':self.editor_issue,'tracks':replacement_tracks}
                ofile  = open(self.pp_profile_dir + os.sep + this_file, "wb")
                json.dump(dic,ofile,sort_keys=True,indent=1)       



    def update_tracks(self,old_tracks):
        # get correct spec from type of field
        replacement_tracks=[]
        for old_track in old_tracks:
            # print '\nold track ',old_track
            track_type=old_track['type']
            #update if new tracks has the track type otherwise skip
            if track_type in PPdefinitions.new_tracks:
                spec_fields=PPdefinitions.new_tracks[track_type]
                left_overs=dict()
                # go through track and delete fields not in spec
                for key in old_track.keys():
                    if key in spec_fields:
                        left_overs[key]=old_track[key]
                # print '\n leftovers',left_overs
                replacement_track=copy.deepcopy(PPdefinitions.new_tracks[track_type])
                # print '\n before update', replacement_track
                replacement_track.update(left_overs)
                # print '\nafter update',replacement_track
                replacement_tracks.append(copy.deepcopy(replacement_track))
        return replacement_tracks


    def update_shows_in_showlist(self,old_shows):
        # get correct spec from type of field
        replacement_shows=[]
        for old_show in old_shows:
            show_type=old_show['type']
            ## menu to menushow
            spec_fields=PPdefinitions.new_shows[show_type]
            left_overs=dict()
            # go through track and delete fields not in spec
            for key in old_show.keys():
                if key in spec_fields:
                    left_overs[key]=old_show[key]
            # print '\n leftovers',left_overs
            replacement_show=copy.deepcopy(PPdefinitions.new_shows[show_type])
            replacement_show.update(left_overs)
            replacement_shows.append(copy.deepcopy(replacement_show))
        return replacement_shows                
noveltyButton = Button(framenovelty, text = "Use Novelty", command = novelty_func)
noveltyButton.grid(row=4, column = 0)

evolveButton = Button(frame, text = "Evolve population", command = evolve_pop)
evolveButton.grid(row = 5, column = 0)

menu = Menu(root)
filemenu = Menu(menu)
menu.add_cascade(label="File", menu = filemenu)
filemenu.add_command(label = "Export Song", command = export)

viewmenu = Menu(menu)
menu.add_cascade(label = "View", menu = viewmenu)
viewmenu.add_command(label = "Print all", command = print_all)

root.config(menu = menu)

yscroll = Scrollbar(framelistbox, relief = 'raised')
yscroll.grid(row=0, column=1)


listbox = Listbox(framelistbox, yscrollcommand = yscroll.set, width = 40, height = 8)
for song in song_list:
  listbox.insert(END, "Song: %d.%d" %(GEN_NUM, song.song_id) + "    Fitness:" + str( song.fitness) + "    Novelty:" + str(song.novelty_score))

listbox.grid(row = 0, column = 0)
yscroll.config(command = listbox.yview)
listbox.bind('<<ListboxSelect>>', song_clicked)

fitnesslabel = Label(frame, text = "Fitness Functions")
fitnesslabel.grid(row = 0, column = 0)
Example #33
0
from Tkinter import Tk
import sys

print(sys.executable)
print(sys.version)


def doNothing():
    print("ok ok I won't...")


root = Tk()

menu = Menu(root)
root.config(menu=menu)

subMenu = Menu(menu)
menu.add_cascade(label="file", menu=subMenu)
subMenu.add_command(label="Now Project...", command=doNothing)
subMenu.add_command(label="Now...", command=doNothing)
subMenu.add_seperator()
subMenu.add_command(label="Exit", command=doNothing)

editMenu = Menu(menu)
menu.add_cascade(label="Edit", menu=subMenu)
editMenu.add_command(label="Redo", command=doNothing)
root.mainloop()
Example #34
0
class TkApplicationWindow(AbstractApplicationWindow):
    def __init__(self, app):
        self.root = Tk()
        self.root.title("Llia")
        self.root.config(background=factory.bg())
        super(TkApplicationWindow, self).__init__(app, self.root)
        self.root.withdraw()
        if app.config["enable-splash"]:
            splash = TkSplashWindow(self.root, app)
        self.root.deiconify()
        self.root.protocol("WM_DELETE_WINDOW", self.exit_app)
        self.llia_graph = None
        self._main = layout.BorderFrame(self.root)
        self._main.config(background=factory.bg())
        self._main.pack(anchor="nw", expand=True, fill=BOTH)
        self._init_status_panel()
        self._init_menu()
        self._init_center_frame(self._main.center)
        self.root.minsize(width=665, height=375)
        self.group_windows = []
        self.add_synth_group()

    # def _init_status_panel(self):
    #     south = self._main.south
    #     south.configure(padx=4, pady=4)
    #     self._lab_status = factory.label(south, "", modal=False)
    #     b_panic = factory.panic_button(south)
    #     ttip = "Clear status line"
    #     b_clear_status = factory.clear_button(south,command=self.clear_status,ttip=ttip)
    #     b_panic.grid(row=0, column=0, sticky="w")
    #     b_clear_status.grid(row=0, column=1, sticky="w")
    #     self._lab_status.grid(row=0,column=2, sticky="w", padx=8)
    #     south.config(background=factory.bg())

    def _init_status_panel(self):
        south = self._main.south
        south.configure(padx=4, pady=4)
        self._lab_status = factory.label(south, "", modal=False)
        b_panic = factory.panic_button(south)
        b_down = factory.button(south, "-")
        b_up = factory.button(south, "+")
        b_panic.grid(row=0, column=0)
        # b_down.grid(row=0,column=1)
        # b_up.grid(row=0,column=2)
        self._lab_status.grid(row=0, column=3, sticky='w')
        south.config(background=factory.bg())
        b_down.configure(command=lambda: self.root.lower())
        b_up.configure(command=lambda: self.root.lift())
        # b_clear_status = factory.clear_button(south,command=self.clear_status,ttip=ttip)
        # b_panic.grid(row=0, column=0, sticky="w")
        # b_clear_status.grid(row=0, column=1, sticky="w")
        # self._lab_status.grid(row=0,column=2, sticky="w", padx=8)
        # south.config(background=factory.bg())

    def _tab_change_callback(self, event):
        self.llia_graph.sync()

    def _init_center_frame(self, master):
        nb = ttk.Notebook(master)
        nb.pack(expand=True, fill="both")
        frame_synths = layout.FlowGrid(nb, 6)
        frame_efx = layout.FlowGrid(nb, 6)
        frame_controllers = layout.FlowGrid(nb, 6)
        self.llia_graph = LliaGraph(nb, self.app)
        nb.add(frame_synths, text="Synths")
        nb.add(frame_efx, text="Effects")
        nb.add(frame_controllers, text="Controllers")
        nb.add(self.llia_graph, text="Graph")
        nb.bind("<Button-1>", self._tab_change_callback)

        def display_info_callback(event):
            sp = event.widget.synth_spec
            msg = "%s:    %s" % (sp["format"], sp["description"])
            self.status(msg)

        def clear_info_callback(*_):
            self.status("")

        for st in con.SYNTH_TYPES:
            sp = specs[st]
            ttp = "Add %s Synthesizer (%s)" % (st, sp["description"])
            b = factory.logo_button(frame_synths, st, ttip=ttp)
            b.synth_spec = sp
            b.bind("<Button-1>", self._show_add_synth_dialog)
            b.bind("<Enter>", display_info_callback)
            b.bind("<Leave>", clear_info_callback)
            frame_synths.add(b)
        for st in con.EFFECT_TYPES:
            sp = specs[st]
            ttp = "Add %s Effect (%s)" % (st, sp["description"])
            b = factory.logo_button(frame_efx, st, ttip=ttp)
            b.synth_spec = sp
            b.bind("<Button-1>", self._show_add_efx_dialog)
            b.bind("<Enter>", display_info_callback)
            b.bind("<Leave>", clear_info_callback)
            frame_efx.add(b)
        for st in con.CONTROLLER_SYNTH_TYPES:
            sp = specs[st]
            ttp = "Add %s Effect (%s)" % (st, sp["description"])
            b = factory.logo_button(frame_controllers, st, ttip=ttp)
            b.synth_spec = sp
            b.bind("<Button-1>", self._show_add_controller_dialog)
            b.bind("<Enter>", display_info_callback)
            b.bind("<Leave>", clear_info_callback)
            frame_controllers.add(b)

    @staticmethod
    def menu(master):
        m = Menu(master, tearoff=0)
        m.config(background=factory.bg(), foreground=factory.fg())
        return m

    def _init_menu(self):
        main_menu = self.menu(self.root)
        self.root.config(menu=main_menu)
        file_menu = self.menu(main_menu)
        osc_menu = self.menu(main_menu)
        midi_menu = self.menu(main_menu)
        bus_menu = self.menu(main_menu)
        #buffer_menu = self.menu(main_menu)
        tune_menu = self.menu(main_menu)
        help_menu = self.menu(main_menu)
        main_menu.add_cascade(label="File", menu=file_menu)
        main_menu.add_cascade(label="OSC", menu=osc_menu)
        main_menu.add_cascade(label="MIDI", menu=midi_menu)
        main_menu.add_cascade(label="Buses", menu=bus_menu)
        #main_menu.add_cascade(label="Buffers", menu=buffer_menu)
        main_menu.add_cascade(label="Tune", menu=tune_menu)
        main_menu.add_cascade(label="Help", menu=help_menu)
        self._init_file_menu(file_menu)
        self._init_osc_menu(osc_menu)
        self._init_midi_menu(midi_menu)
        self._init_bus_menu(bus_menu)
        #self._init_buffer_menu(buffer_menu)
        self._init_tune_menu(tune_menu)
        self._init_help_menu(help_menu)

    def _init_file_menu(self, fmenu):
        fmenu.add_command(label="Lliascript", command=self.show_history_editor)
        fmenu.add_separator()
        fmenu.add_command(label="New Synth Group",
                          command=self._add_synth_group)
        fmenu.add_separator()
        fmenu.add_command(label="Quit", command=self.exit_app)

    def _init_osc_menu(self, iomenu):
        iomenu.add_command(label="Ping", command=self.ping_global)
        iomenu.add_command(label="Dump", command=self.app.proxy.dump)
        iomenu.add_command(label="Toggle OSC Trace",
                           command=self.toggle_osc_trace)

    def _init_midi_menu(self, mmenu):
        map_menu = self.menu(mmenu)
        mmenu.add_command(label="Channel Names",
                          command=self.show_channel_name_dialog)
        mmenu.add_command(label="Controller Names",
                          command=self.show_controller_name_dialog)
        mmenu.add_cascade(label="MIDI Maps", menu=map_menu)
        mmenu.add_command(label="Toggle MIDI Input Trace",
                          command=self.toggle_midi_input_trace)
        mmenu.add_command(label="Toggle MIDI Output Trace",
                          command=self.toggle_midi_output_trace)
        mmenu.add_command(label="Toggle Program Pretty Printer",
                          command=self.toggle_program_pretty_printer)

    def _init_bus_menu(self, bmenu):
        bmenu.add_command(label="Audio", command=self.show_audiobus_dialog)
        bmenu.add_command(label="Control", command=self.show_controlbus_dialog)

    # def _init_buffer_menu(self, bmenu):
    #     bmenu.add_command(label="View Buffers", command=self.show_bufferlist_dialog)

    def _init_tune_menu(self, tmenu):
        tmenu.add_command(label="FIX ME: Nothing to see here")

    def _init_help_menu(self, hmenu):
        pass

    def exit_gui(self):
        try:
            self.root.destroy()
        except:
            pass

    def exit_app(self):
        # ISSUE: Check config and ask user confirmation before existing
        self.app.exit_()

    def as_widget(self):
        return self.root

    def status(self, msg):
        self._lab_status.config(text=str(msg))

    def warning(self, msg):
        msg = "WARNING: %s" % msg
        self._lab_status.config(text=msg)

    def clear_status(self):
        self.status("")

    def start_gui_loop(self):
        self.root.mainloop()

    def show_about_dialog(self):
        from llia.gui.tk.tk_about_dialog import TkAboutDialog
        dialog = TkAboutDialog(self.root, self.app)
        self.root.wait_window(dialog)

    def display_help(self, topic=None):
        pass

    def show_history_editor(self):
        from llia.gui.tk.tk_history import TkHistoryEditor
        dialog = TkHistoryEditor(self.root, self.app)
        self.root.wait_window(dialog)

    def ping_global(self):
        try:
            rs = self.app.proxy.ping()
            if rs:
                self.status("Ping OK")
            else:
                self.warning("Ping Error")
        except LliaPingError as err:
            self.warning(err.message)

    def toggle_osc_trace(self):
        LliaProxy.trace = not LliaProxy.trace
        if LliaProxy.trace:
            self.status("OSC transmission trace enabled")
        else:
            self.status("OSC transmission trace disabled")

    def show_channel_name_dialog(self):
        from llia.gui.tk.tk_channel_name_editor import TkChannelNameEditor
        dialog = TkChannelNameEditor(self.root, self.app)
        self.root.wait_window(dialog)

    def show_controller_name_dialog(self):
        from llia.gui.tk.tk_controller_name_editor import TkControllerNameEditor
        dialog = TkControllerNameEditor(self.root, self.app)
        self.root.wait_window(dialog)

    def toggle_midi_input_trace(self):
        flag = not self.app.midi_in_trace
        self.app.midi_in_trace = flag
        self.app.midi_receiver.enable_trace(flag)
        if flag:
            self.status("MIDI input trace enabled")
        else:
            self.status("MIDI output trace disabled")

    def toggle_midi_output_trace(self):
        self.status("MIDI output not available")  # FIX ME

    def toggle_program_pretty_printer(self):
        self.app.pp_enabled = not self.app.pp_enabled
        if self.app.pp_enabled:
            self.status("Pretty printer enabled")
        else:
            self.status("Pretty printer disabled")

    def show_audiobus_dialog(self):
        from llia.gui.tk.tk_audiobus_editor import TkAudiobusEditor
        dialog = TkAudiobusEditor(self.root, self.app)
        self.root.wait_window(dialog)

    def show_controlbus_dialog(self):
        from llia.gui.tk.tk_controlbus_editor import TkControlbusEditor
        dialog = TkControlbusEditor(self.root, self.app)
        self.root.wait_window(dialog)

    # def show_bufferlist_dialog(self):
    #     from llia.gui.tk.tk_buffer_info import TkBufferListDialog
    #     dialog = TkBufferListDialog(self.root, self.app)
    #     self.root.wait_window(dialog)

    def _show_add_synth_dialog(self, event):
        w = event.widget
        st = w.config()["text"][-1]
        dialog = TkAddSynthDialog(self.root, self.app, st, False)
        self.root.wait_window(dialog)

    def _show_add_efx_dialog(self, event):
        w = event.widget
        st = w.config()["text"][-1]
        dialog = TkAddSynthDialog(self.root,
                                  self.app,
                                  st,
                                  is_efx=True,
                                  is_controller=False)
        self.root.wait_window(dialog)

    def _show_add_controller_dialog(self, event):
        w = event.widget
        st = w.config()["text"][-1]
        dialog = TkAddSynthDialog(self.root,
                                  self.app,
                                  st,
                                  is_efx=False,
                                  is_controller=True)
        self.root.wait_window(dialog)

    def _add_synth_group(self):
        sh = self.app.ls_parser.synthhelper
        sh.new_group()

    def add_synth_group(self, name=None):
        gw = GroupWindow(self.app, self.root, name)
        gw.transient(self.root)
        self.group_windows.append(gw)
        self.status("Added new Synth Group Window")
        return gw

    def display_synth_editor(self, sid):
        try:
            swin = self[sid]
            grpid = swin.group_index
            grp = self.group_windows[grpid]
            #grp.deiconify()
            grp.show_synth_editor(sid)
        except (KeyError, IndexError):
            msg = "Can not find editor for %s" % sid
            self.warning(msg)
                              height=canvas_height)
        self.canvas.itemconfigure("inner_frame",
                                  width=window_width,
                                  height=window_height)


if __name__ == '__main__':
    try:
        from Tkinter import Tk, Label
    except ImportError:
        from tkinter import Tk, Label

    root = Tk()

    root.title('TEST1')
    root.config(width=600, height=300)

    scrolling_area = Scrolling_Area(root)
    scrolling_area.config(width=100, height=60)
    scrolling_area.place(x=20, y=40)
    # scrolling_area.canvas.config(scrollregion=(0, 0, 8*20, 20*20))
    # scrolling_area.pack(expand=1, fill=BOTH)

    pixel = tk.PhotoImage(master=root, name='test_photo', width=1, height=1)

    colors = ['#00FF00', '#FF0000']
    for i in range(0, 20):
        rowFrame = Frame(scrolling_area.innerframe)
        rowFrame.pack()
        # rowFrame.config(width=20*20, height=20)
        # rowFrame.place(x=0, y=i*20)
Example #36
0
class PraiseTexGUI(object):
    """Graphical interface for selecting songs and compiling them"""
    def __init__(self, songdir="songs"):
        # data
        self.songs = []
        self.praisetex = PraiseTex(songdir)
        self.root = Tk()
        
        button_width = 6
        button_padx = "2m"
        button_pady = "1m"
        frame_padx = "3m"
        frame_pady = "2m"
        label_padx = "3m"
        label_pady = "2m"
        listbox_width = 30
        listbox_height = 20
        frame_title_font = ("TkDefaultFont", 14)
        text_font = ("TkDefaultFont", 12)
        menu_font = ("TkDefaultFont", 12)
        button_font = ("TkDefaultFont", 12)

        # window properties
        self.root.title("praisetex")
        self.root.option_add("*Font", ("TkDefaultFont", 12))

        # menu
        menubar = Menu(self.root)
        menubar.tk.call('tk', 'scaling', 2.5)
        filemenu = Menu(menubar, tearoff=0)
        filemenu.add_command(label="Open Directory", command=self.openDirectory)
        filemenu.add_command(label="Exit", command=self.root.quit)
        menubar.add_cascade(label="File", menu=filemenu)
        self.root.config(menu=menubar)

        # left section
        self.availableSongsTitle = Label(self.root, 
                                         text="Available Songs",
                                         font=frame_title_font,
                                         padx=label_padx, 
                                         pady=label_pady)
        self.availableSongsTitle.grid(row=0, column=0)
        self.availableSongsFrame = Frame(self.root)
        self.availableSongsFrame.grid(row=1, column=0,
                                      padx=frame_padx, pady=frame_pady)
        self.availableSongsScroll = Scrollbar(self.availableSongsFrame, 
                                              orient=VERTICAL)
        self.availableSongs = Listbox(self.availableSongsFrame, 
                                      width=listbox_width, 
                                      height=listbox_height, 
                                      selectmode=EXTENDED, 
                                      yscrollcommand=self.availableSongsScroll.set,
                                      exportselection=0)
        self.availableSongsScroll.config(command=self.availableSongs.yview)
        self.availableSongsScroll.pack(side=RIGHT, fill=Y)
        self.availableSongs.pack()

        self.button = Button(self.root, 
                             text="Refresh",  
                             command=self.refreshSongList)
        self.button.grid(row=2, column=0)

        
        # middle section
        self.addRemoveButtonFrame = Frame(self.root)
        self.addRemoveButtonFrame.grid(row=1, column=1)
        self.addSongButton = Button(self.addRemoveButtonFrame,
                                    text="Add", 
                                    command=self.addSong)
        self.addSongButton.pack(side=TOP, padx=button_padx, pady=button_pady)
        self.removeSongButton = Button(self.addRemoveButtonFrame, 
                                       text="Remove", 
                                       command=self.removeSong)
        self.removeSongButton.pack(side=BOTTOM)

        # right section
        self.songsToCompileTitle = Label(self.root, text="Songs to Compile", 
                                         font=frame_title_font,
                                         padx=label_padx, pady=label_pady)
        self.songsToCompileTitle.grid(row=0, column=2)
        self.songsToCompileFrame = Frame(self.root)
        self.songsToCompileFrame.grid(row=1, column=2, 
                                      padx=frame_padx, pady=frame_pady)
        self.songsToCompileScroll = Scrollbar(self.songsToCompileFrame,
                                              orient=VERTICAL)
        self.songsToCompile = Listbox(self.songsToCompileFrame, 
                                      width=listbox_width, 
                                      height=listbox_height, 
                                      selectmode=EXTENDED,
                                      yscrollcommand=self.songsToCompileScroll.set,
                                      exportselection=0,
                                      font=text_font)
        self.songsToCompileScroll.config(command=self.songsToCompile.yview)
        self.songsToCompileScroll.pack(side=RIGHT, fill=Y)
        self.songsToCompile.pack()

        self.compileButtonFrame = Frame(self.root)
        self.compileButtonFrame.grid(row=2, column=2)
        self.chordsButton = Button(self.compileButtonFrame, 
                                   text="Chords", 
                                   command=self.compileChords)
        self.chordsButton.pack(side=LEFT, padx=button_padx, pady=button_pady)
        self.slidesButton = Button(self.compileButtonFrame, 
                                   text="Slides", 
                                   command=self.compileSlides)
        self.slidesButton.pack(side=RIGHT, padx=button_padx, pady=button_pady)

        # status bar
        self.status = Label(self.root, text="Ready", padx="1m")
        self.status.grid(row=3, column=0, columnspan=3, sticky=W)

        self.refreshSongList()

    def run(self):
        """Start event loop of GUI"""
        self.root.mainloop()

    def refreshSongList(self):
        """Sync up the filenames in songlist with files in directory"""
        # clear song list
        self.availableSongs.delete(0, END)

        # add song files
        self.songs = self.praisetex.refreshSongList()
        for song in self.songs:
            self.availableSongs.insert(END, song)
        self.updateStatus("{0} songs found in directory {1}".format(len(self.songs), self.praisetex.getSongDirectory()))

    def openDirectory(self):
        """Selects directory for songs"""
        dirname = filedialog.askdirectory(parent=self.root, initialdir=self.praisetex.getSongDirectory(), title='Please select a directory')
        if len(dirname) > 0:
            self.praisetex.setSongDirectory(dirname)
            self.updateStatus("Song directory set to {0}".format(dirname))

    def addSong(self):
        """Add song to compile list"""
        selectedSongs = self.availableSongs.curselection()

        # get index of where to insert selected songs
        insertIndex = self.songsToCompile.curselection()
        if len(insertIndex) > 0:
            insertIndex = int(insertIndex[0]) # convert to integer
        else:
            insertIndex = -1 # song should be appended


        if len(selectedSongs) == 0: # do nothing
            pass
            
        elif len(selectedSongs) == 1: # insert the one song
            song = selectedSongs[0]
            songtitle = self.availableSongs.get(song)
            if insertIndex == -1:
                end = len(self.praisetex.compile)
                self.praisetex.addSong(end, songtitle)
                self.songsToCompile.insert(END, songtitle)
            else:
                self.praisetex.addSong(insertIndex+1, songtitle)
                self.songsToCompile.insert(insertIndex+1, songtitle)
            
        else: # more than one song  
            songList = [self.availableSongs.get(song) for song in selectedSongs]
            if insertIndex != -1:
                songList.reverse()
                for songtitle in songList:
                    self.praisetex.addSong(insertIndex+1, songtitle)
                    self.songsToCompile.insert(insertIndex+1, songtitle)
            else: # add songs to the end
                for songtitle in songList:
                    end = len(self.praisetex.compile)
                    self.praisetex.addSong(end, songtitle)
                    self.songsToCompile.insert(END, songtitle)
       
        self.updateStatus("{0} songs added".format(len(selectedSongs)))


    def removeSong(self):
        """Remove song from compile list"""
        songindexes = list(self.songsToCompile.curselection())
        songindexes.reverse()
        for index in songindexes:
            self.praisetex.removeSong(index)
            self.songsToCompile.delete(index)
            
        self.updateStatus("{0} songs removed".format(len(songindexes)))

    def compileChords(self):
        """Compile a chord sheet from selected songs"""
        self.updateStatus("Compiling Songs")
        error = self.praisetex.compileChords()
        if error:
            self.updateStatus("pdflatex has failed")
        else:
            self.updateStatus("Compiled chords.pdf")

    def compileSlides(self):
        """Compile slides from selected songs"""
        self.updateStatus("Compiling Songs")
        error = self.praisetex.compileSlides()
        if error:
            self.updateStatus("pdflatex has failed")
        else:
            self.updateStatus("Compiled slides.pdf")

    def updateStatus(self, message):
        """Update the status bar"""
        self.status.config(text=message)
Example #37
0
def _help():
    win = Toplevel(root)
    lab = Label(win, text="Вам необходимо ввести колличество каналов в пакетах Социальный, Базовый и Полный.\nПосле этого открыть EXCEL файл с нужным сервичным планом и нажать на кнопку Преобразовать.\nРезультат будет преобразован в формат txt\nи появится на экране. Файл txt будет автоматически сохранен.")
    lab.pack()

def _about():
    win = Toplevel(root)
    lab = Label(win, text="Эта программа преобразовывает xls файл \n в txt формат специальной разметкой.")
    lab.pack()


root = Tk()

root.title('IPTV playlist creator')
m = Menu(root)
root.config(menu=m)
fm = Menu(m)
m.add_cascade(label="File", menu=fm)
fm.add_command(label="Open", command = _open)
fm.add_command(label="Save", command = _save)
fm.add_command(label="Exit", command = _close)

hm = Menu(m)
m.add_cascade(label="Help", menu=hm)
hm.add_command(label="Help", command = _help)
hm.add_command(label="About", command = _about)

fra1 = Frame(root, width=500, height=30, bd = 5)
fra2 = Frame(root, width=500, height=100, bd = 5)
fra3 = Frame(root, width=500, height=500, bd = 5)
 
Example #38
0
class ClusterFK:
    """
    The Tkinter UI, responsible for drawing the board and accepting user input.
    """
    def __init__(self, rounds, filename, trail):
        self.root = Tk()

        self.menubar = Menu(self.root)
        self.filemenu = Menu(self.menubar, tearoff=0)
        self.filemenu.add_command(label="Save Trail", command=self.saveTrail)
        self.filemenu.add_command(label="Load Trail", command=self.loadTrail)
        self.filemenu.add_command(label="Export to Tex",
                                  command=self.exportToLatex)
        self.filemenu.add_command(label="Quit", command=self.root.quit)
        self.menubar.add_cascade(label="File", menu=self.filemenu)

        self.root.config(menu=self.menubar)
        self.trailUI = None
        if filename.endswith(".cfk"):
            self._loadTrailFromFile(open(filename, "rb"))
        elif filename.endswith(".trail"):
            self._initTrailUI(trail(rounds, filename=filename))
        elif filename.endswith(".json"):
            self._loadTrailFromJson(open(filename, "rb"))
        else:
            print "File extensions not supported. Use .trail, .cfk or .json"
            raise IOError()
        # self.mantis.printTrail()
        self.root.geometry("{:d}x{:d}".format(1920, 1080))
        self.root.mainloop()

    def _initTrailUI(self, trail):

        if self.trailUI is not None:
            self.trailUI.cleanup()
        self.trail = trail
        #self.trail.propagate()
        self.trailUI = TrailUI(self.root, self.trail)
        self.trailUI.redraw_all()
        self.trailUI.redrawColorList()

    def saveTrail(self):
        f = tkFileDialog.asksaveasfile(mode="w", defaultextension=".json")
        if f is None:  # asksaveasfile return `None` if dialog closed with "cancel".
            return
        # pickle.dump(self.trail, f)
        json_trail = self.trail.toJSON()
        validate(json_trail, Utils.json_schema)
        json.dump(json_trail, f, sort_keys=True, indent=2)
        f.close()

    def _loadTrailFromJson(self, f):
        if f is None:
            return

        # load JSON data as string, not unicode string
        imported_trail = _byteify(json.load(f, object_hook=_byteify),
                                  ignore_dicts=True)
        validate(imported_trail, Utils.json_schema)
        f.close()

        trail = CIPHER_TRAILS[imported_trail["cipher"]](
            imported_trail["rounds"], jsontrail=imported_trail)
        self._initTrailUI(trail)

    def _loadTrailFromFile(self, f):
        # for old exports
        if f is None:
            return
        trail = pickle.load(f)
        self._initTrailUI(trail)
        f.close()

    def loadTrail(self):
        f = tkFileDialog.askopenfile(mode="r", defaultextension=".json")
        if f is None:
            return

        if f.name.endswith(".cfk"):
            self._loadTrailFromFile(f)
        elif f.name.endswith(".json"):
            self._loadTrailFromJson(f)
        else:
            print "File extensions not supported. Use .trail, .cfk or .json"
            raise IOError()

    def exportToLatex(self):
        f = tkFileDialog.asksaveasfile(mode="w", defaultextension=".tex")
        if f is None:
            return

        self.trail.exportToLatex(f)
        f.close()
Example #39
0
class App_Runner:
  """
  App runner that uses a Board and a Palette.
  """
  def __init__(self, on_init, app_name, dev_stage, file_extension,
      deserializers, board_width, board_height, palette_height,
      directed_wires, label_tooltips_enabled, same_label_per_connector,
      init_file=None):
    """
    |on_init|: method called every time a new board of this app's type is
        created.
    |app_name|: name of this app.
    |dev_stage|: development stage of this app.
    |file_extension|: the file extension used for boards of this app's type.
    |deserializers|: drawabel types to open files of this app's type.
    |board_width|, |board_height|: board dimensions.
    |palette_height|: height of palette, width will be the same as board width.
    |directed_wires|: True if the board is to have directed wires, False
        otherwise.
    |label_tooltips_enabled|: if True, show wire and drawable label tooltips.
    |same_label_per_connector|: if True, all wires from a connector will have
        the same label. If False, this will only be true for wire connectors.
    |init_file|: file to open at init time.
    """
    self._on_init = on_init
    self._app_name = app_name
    self._dev_stage = dev_stage
    self._file_extension = file_extension
    self._deserializers = deserializers
    self._board_width = board_width
    self._board_height = board_height
    self._palette_height = palette_height
    self._directed_wires = directed_wires
    self._label_tooltips_enabled = label_tooltips_enabled
    self._same_label_per_connector = same_label_per_connector
    self._init_file = init_file
    self._init()
    self._setup_menu()
    self._setup_shortcuts()
  def _switch_cursor_to_draw(self, *args):
    """
    Switches board cursor state to 'draw'.
    """
    self._draw_display.highlight()
    self._drag_display.unhighlight()
    self.board.set_cursor_state('draw')
  def _switch_cursor_to_drag(self, *args):
    """
    Switches board cursor state to 'drag'.
    """
    self._draw_display.unhighlight()
    self._drag_display.highlight()
    self.board.set_cursor_state('drag')
  def _toggle_cursor(self):
    """
    Toggles board cursor state.
    """
    if self.board.get_cursor_state() == 'draw':
      self._switch_cursor_to_drag()
    else:
      self._switch_cursor_to_draw()
  def _init(self):
    """
    Creates the board and palette.
    """
    self._file_name = None
    self._root = Tk()
    self._root.resizable(0, 0)
    self._menu = Menu(self._root, tearoff=0)
    self.board = Board(self._root, self._menu, width=self._board_width,
        height=self._board_height, directed_wires=self._directed_wires,
        label_tooltips_enabled=self._label_tooltips_enabled,
        same_label_per_connector=self._same_label_per_connector,
        on_changed=self._on_changed, on_exit=self._request_save)
    self._init_board()
    self.palette = Palette(self._root, self.board, width=self._board_width,
        height=self._palette_height)
    # buttons to change board cursor state
    self.palette.current_left_x -= PALETTE_PADDING
    self._draw_display = self.palette.add_drawable_type(Image_Run_Drawable,
        LEFT, self._switch_cursor_to_draw, image_file=PENCIL_IMAGE)
    self.palette.current_left_x -= PALETTE_PADDING
    self._drag_display = self.palette.add_drawable_type(Image_Run_Drawable,
        LEFT, self._switch_cursor_to_drag, image_file=HAND_IMAGE)
    self.palette.draw_separator()
    self._switch_cursor_to_draw()
  def _setup_menu(self):
    """
    Creates the menu.
    """
    file_menu = Menu(self._menu, tearoff=0)
    file_menu.add_command(label='New', command=self._new_file,
        accelerator='Ctrl+N')
    file_menu.add_command(label='Open', command=self._open_file,
        accelerator='Ctrl+O')
    file_menu.add_command(label='Save', command=self._save_file,
        accelerator='Ctrl+S')
    file_menu.add_command(label='Save as', command=self._save_as)
    file_menu.add_separator()
    file_menu.add_command(label='Quit', command=self.board.quit,
        accelerator='Ctrl+Q')
    self._menu.add_cascade(label='File', menu=file_menu)
    edit_menu = Menu(self._menu, tearoff=0)
    edit_menu.add_command(label='Undo', command=self.board.undo,
        accelerator='Ctrl+Z')
    edit_menu.add_command(label='Redo', command=self.board.redo,
        accelerator='Ctrl+Y')
    edit_menu.add_command(label='Delete selected',
        command=self.board._delete_selected_items, accelerator='Delete')
    edit_menu.add_command(label='Rotate selected',
        command=self.board._rotate_selected_item, accelerator='r')
    edit_menu.add_command(label='Toggle cursor', command=self._toggle_cursor,
        accelerator='D')
    self._menu.add_cascade(label='Edit', menu=edit_menu)
    self._root.config(menu=self._menu)
  def _setup_shortcuts(self):
    """
    Adds basic shortcuts.
    """
    self.board.parent.bind('<Control-n>', lambda event: self._new_file())
    self.board.parent.bind('<Control-N>', lambda event: self._new_file())
    self.board.parent.bind('<Control-o>', lambda event: self._open_file())
    self.board.parent.bind('<Control-O>', lambda event: self._open_file())
    self.board.parent.bind('<Control-q>', lambda event: self.board.quit())
    self.board.parent.bind('<Control-Q>', lambda event: self.board.quit())
    self.board.parent.bind('<Control-s>', lambda event: self._save_file())
    self.board.parent.bind('<Control-S>', lambda event: self._save_file())
    self.board.parent.bind('<Control-y>', lambda event: self.board.redo())
    self.board.parent.bind('<Control-Y>', lambda event: self.board.redo())
    self.board.parent.bind('<Control-z>', lambda event: self.board.undo())
    self.board.parent.bind('<Control-Z>', lambda event: self.board.undo())
    self.board.add_key_binding('d', self._toggle_cursor)
  def _init_board(self):
    """
    (Re)Initializes the board based on this app's specific needs, as per
        self._on_init.
    """
    self.board.clear()
    self._on_init(self.board)
    self.board.reset()
  def _on_changed(self, board_changed):
    """
    Callback for when the board is changed. Updates the title of the app window
        to indicate whether we need to save the file.
    """
    self._root.title('%s (%s) %s %s' % (self._app_name, self._dev_stage,
        strip_file_name(self._file_name), '*' if board_changed else ''))
  def _save_as(self, file_name=None):
    """
    Saves the current state of the app with the given |file_name|.
    """
    saved_file_name = save_board(self.board, file_name, self._app_name,
        self._file_extension)
    if saved_file_name:
      self._file_name = saved_file_name
      self.board.set_changed(False)
  def _save_file(self):
    """
    Saves the current state of the app with its current file name (asks for a
        a file path if it currently does not have one).
    """
    self._save_as(self._file_name)
  def _request_save(self):
    """
    Requests for a file save if necessary. Returns True if there isn't anything
        to save or, in the case that there is something to save, if the user
        either decides to save the file (will be presented with a dialog to do
        so) or decides not to save the file. Returns False if the user cancels
        the request for save (i.e. does neither).
    """
    if self.board.changed():
      save = request_save_board()
      if save == 'yes':
        self._save_file()
        return True
      elif save == 'no':
        return True
      else:
        return False
    else:
      return True
  def _open_file(self, new_file_name=None):
    """
    Opens a saved file of this app's type.
    """
    if self._request_save():
      new_file_name = new_file_name or get_board_file_name(self._file_name,
          self._app_name, self._file_extension)
      if open_board_from_file(self.board, new_file_name, self._deserializers,
          self._file_extension):
        self._file_name = new_file_name
        self._on_changed(False)
      self.board.reset_cursor_state()
  def _new_file(self):
    """
    Opens a new file of this app's type.
    """
    if self._request_save():
      self._file_name = None
      self._init_board()
  def run(self):
    """
    Runs this app.
    """
    self.board.clear_action_history()
    self._root.title('%s (%s)' % (self._app_name, self._dev_stage))
    if self._init_file:
      self._open_file(self._init_file)
    self._root.mainloop()
def Main1():
    global reproducir
    reproducir=0
    # Creacion de la ventana

    ventana = Tk()
    ventana.title("Proyecto Final")
    ventana.config(bg = "black")

    d = BooleanVar(ventana)
    e = BooleanVar(ventana)
    e.set(False)
    f = BooleanVar(ventana)
    f.set(False)

    CHUNK = 1024
    FORMAT = pyaudio.paInt16
    CHANNELS = 1
    RATE = 44100

    audio1 = Grabador1(CHUNK, FORMAT, CHANNELS, RATE)
    audio2 = Grabador2(CHUNK, FORMAT, CHANNELS, RATE)
    audio3 = Grabador3(CHUNK, FORMAT, CHANNELS, RATE)
    audio4 = Grabador4(CHUNK, FORMAT, CHANNELS, RATE)

    global Array1,Array2,Array3,Array4
    global Rec1,Rec2,Rec3,Rec4
    global ArrayFinal1,ArrayFinal2,ArrayFinal3,ArrayFinal4
    global ArrayComprimido1, ArrayComprimido2, ArrayComprimido3, ArrayComprimido4
    global FinalArray1,FinalArray2,FinalArray3,FinalArray4
    global MezclaFinalFinal,MezclaMixFinal
    global FinalArrayAux1,FinalArrayAux2,FinalArrayAux3,FinalArrayAux4
    global MezclaAUXFINAL, MezclaMixAux

    # Arreglos globales
    Array1 = []
    Array2 = []
    Array3 = []
    Array4 = []

    #Los de la grabacion
    Rec1 = []
    Rec2 = []
    Rec3 = []
    Rec4 = []

    #Arreglos comprimidos del Audio
    ArrayComprimido1= []
    ArrayComprimido2= []
    ArrayComprimido3= []
    ArrayComprimido4= []


     # Arreglos finales antes del fader
    ArrayFinal1 = []
    ArrayFinal2 = []
    ArrayFinal3 = []
    ArrayFinal4 = []

    # Arreglos finales antes del fader

    FinalArray1= []
    FinalArray2= []
    FinalArray3= []
    FinalArray4= []


    MezclaFinalFinal= []
    MezclaMixFinal = []

    #Arreglos de envio de AUX
    FinalArrayAux1 = []
    FinalArrayAux2 = []
    FinalArrayAux3 = []
    FinalArrayAux4 = []
    MezclaAUXFINAL = []
    MezclaMixAux = []


    audiocom1=BooleanVar(ventana)
    audiocom1.set(False)


    # Uso de frames para organizar la ventana.

    frame1 = Frame(ventana,bg = "black")
    frame1.pack(side=TOP)
    frame2 = Frame(ventana,bg = "black")
    frame2.pack(side=LEFT)
    frame3 = Frame(ventana,bg = "black")
    frame3.pack(side=LEFT)
    frame4 = Frame(ventana,bg = "black")
    frame4.pack(side=LEFT)
    frame5 = Frame(ventana,bg = "black")
    frame5.pack(side=LEFT)
    frame6 = Frame(ventana,bg = "black")
    frame6.pack(side=LEFT)
    frame7 = Frame(ventana,bg = "black")
    frame7.pack(side=LEFT)

    #PARTE FUNCIONES DE GRABACION POR CANAL !!!--------------------------------------------------------------------------

#Chanel 1 -----------------------------------------------------------

    def Grabar1():
        d.set(True)
        audio1.inicio()
        mensaje1.pack(side=TOP)
        while d.get():
                audio1.grabacion()
                ventana.update()
                if d.get() is False:
                    break
    def Stop1():
        d.set(False)
        e.set(True)
        mensaje1.pack_forget()
        Nombre ='AudioUno'
        global Array1, Rec1
        Rec1 = audio1.parar()
        audio1.creaAudio(Nombre)
        RecordButton1.configure(state='disabled')
        StopButton1.configure(state='disabled')
        file = wave.open(Nombre+'.wav','rb')
        tamano = int(file.getnframes())
        for i in range (0,tamano):
            dato=file.readframes(1)
            packed_value = struct.unpack('<h', dato)
            Array1.append(packed_value)

#Chanel 2 -----------------------------------------------------------
    def Grabar2():
        d.set(True)
        audio2.inicio()
        mensaje1.pack(side=TOP)
        while d.get():
                audio2.grabacion()
                ventana.update()
                if d.get() is False:
                    break
    def Stop2():
        d.set(False)
        e.set(True)
        mensaje1.pack_forget()
        Nombre ='AudioDos'
        global Array2, Rec2
        Rec2 = audio2.parar()
        audio2.creaAudio(Nombre)
        RecordButton2.configure(state='disabled')
        StopButton2.configure(state='disabled')
        file = wave.open(Nombre+'.wav','rb')
        tamano = int(file.getnframes())
        for i in range (0,tamano):
            dato=file.readframes(1)
            packed_value = struct.unpack('<h', dato)
            Array2.append(packed_value)
#Chanel 3------------------------------------------------------------
    def Grabar3():
        d.set(True)
        audio3.inicio()
        mensaje1.pack(side=TOP)
        while d.get():
                audio3.grabacion()
                ventana.update()
                if d.get() is False:
                    break
    def Stop3():
        d.set(False)
        e.set(True)
        mensaje1.pack_forget()
        Nombre ='AudioTres'
        global Array3, Rec3
        Rec3 = audio3.parar()
        audio3.creaAudio(Nombre)
        RecordButton3.configure(state='disabled')
        StopButton3.configure(state='disabled')
        file = wave.open(Nombre+'.wav','rb')
        tamano = int(file.getnframes())
        for i in range (0,tamano):
            dato=file.readframes(1)
            packed_value = struct.unpack('<h', dato)
            Array3.append(packed_value)

# Chanel 4---------------------------------------------
    def Grabar4():
        d.set(True)
        audio4.inicio()
        mensaje1.pack(side=TOP)
        while d.get():
                audio4.grabacion()
                ventana.update()
                if d.get() is False:
                    break
    def Stop4():
        d.set(False)
        e.set(True)
        mensaje1.pack_forget()
        Nombre ='AudioCuatro'
        global Array4, Rec4
        Rec4 = audio4.parar()
        audio4.creaAudio(Nombre)
        RecordButton4.configure(state='disabled')
        StopButton4.configure(state='disabled')
        file = wave.open(Nombre+'.wav','rb')
        tamano = int(file.getnframes())
        for i in range (0,tamano):
            dato=file.readframes(1)
            packed_value = struct.unpack('<h', dato)
            Array4.append(packed_value)

# PARTE FUNCION DE COMPRESORES ------------------------------------------------------------------------------------------------------------------------

    def Equal1():
        if Eq1.get()==1:

            EQ1()
    def Equal2():
        if Eq2.get()==1:
            EQ2()
    def Equal3():
        if Eq3.get()==1:
            EQ3()
    def Equal4():
        if Eq4.get()==1:
            EQ4()


# PARTE REPRODUCIR


    def Compresor1():

        compresor=Tk()

        compresor.title("Compresor 1 ")
        compresor.config(bg = "black")

        # Uso de frames para organizar la ventana.
        frame1 = Frame(compresor,bg = "black")
        frame1.pack(side=TOP)

        global Array1, ArrayComprimido1

        def compresoraudio1():

            NivelThresh=Threshold.get()
            Thresh1 = (10**float(NivelThresh/20))*((2**16)/2.0)
            Attack1=float(Attack.get()/1000.0)
            CuadrosAttack=int(Attack1*44100)
            ratio=Ratio.get()
            Knee=float((ratio-1)/CuadrosAttack)

            ArregloAttack=[]

            for j in range(1, CuadrosAttack):
                Dato1=1+float(Knee*j)
                ArregloAttack.append(Dato1)


            for i in range(0, len(Array1)):

                if Array1[i][0]>Thresh1:
                    if i<CuadrosAttack:
                        c=Array1[i][0]-Thresh1
                        k=float(c/ArregloAttack[i])
                        Amp=k+Thresh1
                    if i >CuadrosAttack:
                        c=Array1[i][0]-Thresh1
                        k=float(c/ratio)
                        Amp=k+Thresh1
                if Array1[i][0]<(Thresh1*(-1)):
                    if i<CuadrosAttack:
                        c=Array1[i][0]-Thresh1
                        k=float(c/ArregloAttack[i])
                        Amp=k+Thresh1
                    if i >CuadrosAttack:
                        c=Array1[i][0]-Thresh1
                        k=float(c/ratio)
                        Amp=k+Thresh1
                else:
                    Amp=Array1[i][0]

                ArrayComprimido1.append(Amp)

        Label1= Label(frame1, padx=15, pady=1, text="Compresor 1",fg = "white",bg = "black")
        Label1.pack(side=TOP)

        espacio2= Label(frame1, padx=15, pady=1, text=" ",fg = "white",bg = "black")
        espacio2.pack(side=TOP)

        #threshold
        Label2= Label(frame1, padx=15, pady=1, text="Threshold",fg = "white",bg = "black")
        Label2.pack(side=TOP)
        Threshold= Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=-60,to=0,bg = "yellow", fg="black")
        Threshold.pack(side=TOP)

        #ratio
        Label3= Label(frame1, padx=15, pady=1, text="Ratio",fg = "white",bg = "black")
        Label3.pack(side=TOP)
        Ratio=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=9,to=0,bg = "blue", fg="white")
        Ratio.pack(side=TOP)

        #attack
        Label4= Label(frame1, padx=15, pady=1, text="Attack",fg = "white",bg = "black")
        Label4.pack(side=TOP)
        Attack=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=50,to=500,bg = "red", fg="white")
        Attack.pack(side=TOP)

        #realease
        Label5= Label(frame1, padx=15, pady=1, text="Release",fg = "white",bg = "black")
        Label5.pack(side=TOP)
        Release=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=4000,to=5,fg = "white",bg = "black")
        Release.pack(side=TOP)

        #gain
        Label6= Label(frame1, padx=15, pady=1, text="Gain",fg = "white",bg = "black")
        Label6.pack(side=TOP)
        Gain=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=40,to=0,bg = "white", fg="black")
        Gain.pack(side=TOP)

        espacio1= Label(frame1, padx=15, pady=1, text=" ",fg = "white",bg = "black")
        espacio1.pack(side=TOP)

        # Comprimir
        ComprimirButton1 = Button(frame1, padx=30, pady=2, text="Comprimir",bg = "red",fg="white",command= compresoraudio1)
        ComprimirButton1.pack(side=TOP)

        compresor.mainloop()
    def Compresor2():

        compresor=Tk()

        compresor.title("Compresor 2 ")
        compresor.config(bg = "black")

        # Uso de frames para organizar la ventana.
        frame1 = Frame(compresor,bg = "black")
        frame1.pack(side=TOP)

        global Array2, ArrayComprimido2

        def compresoraudio2():

            NivelThresh=Threshold.get()
            Thresh1 = (10**float(NivelThresh/20))*((2**16)/2.0)
            Attack1=float(Attack.get()/1000.0)
            CuadrosAttack=int(Attack1*44100)
            ratio=Ratio.get()
            Knee=float((ratio-1)/CuadrosAttack)

            ArregloAttack=[]

            for j in range(1, CuadrosAttack):
                Dato1=1+float(Knee*j)
                ArregloAttack.append(Dato1)


            for i in range(0, len(Array2)):

                if Array2[i][0]>Thresh1:
                    if i<CuadrosAttack:
                        c=Array2[i][0]-Thresh1
                        k=float(c/ArregloAttack[i])
                        Amp=k+Thresh1
                    if i >CuadrosAttack:
                        c=Array2[i][0]-Thresh1
                        k=float(c/ratio)
                        Amp=k+Thresh1
                if Array2[i][0]<(Thresh1*(-1)):
                    if i<CuadrosAttack:
                        c=Array2[i][0]-Thresh1
                        k=float(c/ArregloAttack[i])
                        Amp=k+Thresh1
                    if i >CuadrosAttack:
                        c=Array2[i][0]-Thresh1
                        k=float(c/ratio)
                        Amp=k+Thresh1
                else:
                    Amp=Array2[i][0]

                ArrayComprimido2.append(Amp)

        Label1= Label(frame1, padx=15, pady=1, text="Compresor 2",fg = "white",bg = "black")
        Label1.pack(side=TOP)

        espacio2= Label(frame1, padx=15, pady=1, text=" ",fg = "white",bg = "black")
        espacio2.pack(side=TOP)

        #threshold
        Label2= Label(frame1, padx=15, pady=1, text="Threshold",fg = "white",bg = "black")
        Label2.pack(side=TOP)
        Threshold= Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=-60,to=0,bg = "yellow", fg="black")
        Threshold.pack(side=TOP)

        #ratio
        Label3= Label(frame1, padx=15, pady=1, text="Ratio",fg = "white",bg = "black")
        Label3.pack(side=TOP)
        Ratio=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=9,to=0,bg = "blue", fg="white")
        Ratio.pack(side=TOP)

        #attack
        Label4= Label(frame1, padx=15, pady=1, text="Attack",fg = "white",bg = "black")
        Label4.pack(side=TOP)
        Attack=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=50,to=500,bg = "red", fg="white")
        Attack.pack(side=TOP)

        #realease
        Label5= Label(frame1, padx=15, pady=1, text="Release",fg = "white",bg = "black")
        Label5.pack(side=TOP)
        Release=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=4000,to=5,fg = "white",bg = "black")
        Release.pack(side=TOP)

        #gain
        Label6= Label(frame1, padx=15, pady=1, text="Gain",fg = "white",bg = "black")
        Label6.pack(side=TOP)
        Gain=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=40,to=0,bg = "white", fg="black")
        Gain.pack(side=TOP)

        espacio1= Label(frame1, padx=15, pady=1, text=" ",fg = "white",bg = "black")
        espacio1.pack(side=TOP)

        # Comprimir
        ComprimirButton1 = Button(frame1, padx=30, pady=2, text="Comprimir",bg = "red",fg="white",command= compresoraudio2)
        ComprimirButton1.pack(side=TOP)

        compresor.mainloop()
    def Compresor3():

        compresor=Tk()

        compresor.title("Compresor 3 ")
        compresor.config(bg = "black")

        # Uso de frames para organizar la ventana.
        frame1 = Frame(compresor,bg = "black")
        frame1.pack(side=TOP)

        global Array3, ArrayComprimido3

        def compresoraudio3():

            NivelThresh=Threshold.get()
            Thresh1 = (10**float(NivelThresh/20))*((2**16)/2.0)
            Attack1=float(Attack.get()/1000.0)
            CuadrosAttack=int(Attack1*44100)
            ratio=Ratio.get()
            Knee=float((ratio-1)/CuadrosAttack)

            ArregloAttack=[]

            for j in range(1, CuadrosAttack):
                Dato1=1+float(Knee*j)
                ArregloAttack.append(Dato1)


            for i in range(0, len(Array3)):

                if Array3[i][0]>Thresh1:
                    if i<CuadrosAttack:
                        c=Array3[i][0]-Thresh1
                        k=float(c/ArregloAttack[i])
                        Amp=k+Thresh1
                    if i >CuadrosAttack:
                        c=Array3[i][0]-Thresh1
                        k=float(c/ratio)
                        Amp=k+Thresh1
                if Array3[i][0]<(Thresh1*(-1)):
                    if i<CuadrosAttack:
                        c=Array3[i][0]-Thresh1
                        k=float(c/ArregloAttack[i])
                        Amp=k+Thresh1
                    if i >CuadrosAttack:
                        c=Array3[i][0]-Thresh1
                        k=float(c/ratio)
                        Amp=k+Thresh1
                else:
                    Amp=Array3[i][0]

                ArrayComprimido3.append(Amp)

        Label1= Label(frame1, padx=15, pady=1, text="Compresor 3",fg = "white",bg = "black")
        Label1.pack(side=TOP)

        espacio2= Label(frame1, padx=15, pady=1, text=" ",fg = "white",bg = "black")
        espacio2.pack(side=TOP)

        #threshold
        Label2= Label(frame1, padx=15, pady=1, text="Threshold",fg = "white",bg = "black")
        Label2.pack(side=TOP)
        Threshold= Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=-60,to=0,bg = "yellow", fg="black")
        Threshold.pack(side=TOP)

        #ratio
        Label3= Label(frame1, padx=15, pady=1, text="Ratio",fg = "white",bg = "black")
        Label3.pack(side=TOP)
        Ratio=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=9,to=0,bg = "blue", fg="white")
        Ratio.pack(side=TOP)

        #attack
        Label4= Label(frame1, padx=15, pady=1, text="Attack",fg = "white",bg = "black")
        Label4.pack(side=TOP)
        Attack=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=50,to=500,bg = "red", fg="white")
        Attack.pack(side=TOP)

        #realease
        Label5= Label(frame1, padx=15, pady=1, text="Release",fg = "white",bg = "black")
        Label5.pack(side=TOP)
        Release=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=4000,to=5,fg = "white",bg = "black")
        Release.pack(side=TOP)

        #gain
        Label6= Label(frame1, padx=15, pady=1, text="Gain",fg = "white",bg = "black")
        Label6.pack(side=TOP)
        Gain=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=40,to=0,bg = "white", fg="black")
        Gain.pack(side=TOP)

        espacio1= Label(frame1, padx=15, pady=1, text=" ",fg = "white",bg = "black")
        espacio1.pack(side=TOP)

        # Comprimir
        ComprimirButton1 = Button(frame1, padx=30, pady=2, text="Comprimir",bg = "red",fg="white",command= compresoraudio3)
        ComprimirButton1.pack(side=TOP)

        compresor.mainloop()
    def Compresor4():

        compresor=Tk()

        compresor.title("Compresor 4 ")
        compresor.config(bg = "black")

        # Uso de frames para organizar la ventana.
        frame1 = Frame(compresor,bg = "black")
        frame1.pack(side=TOP)

        global Array4, ArrayComprimido4

        def compresoraudio4():

            NivelThresh=Threshold.get()
            Thresh1 = (10**float(NivelThresh/20))*((2**16)/2.0)
            Attack1=float(Attack.get()/1000.0)
            CuadrosAttack=int(Attack1*44100)
            ratio=Ratio.get()
            Knee=float((ratio-1)/CuadrosAttack)

            ArregloAttack=[]

            for j in range(1, CuadrosAttack):
                Dato1=1+float(Knee*j)
                ArregloAttack.append(Dato1)


            for i in range(0, len(Array4)):

                if Array4[i][0]>Thresh1:
                    if i<CuadrosAttack:
                        c=Array4[i][0]-Thresh1
                        k=float(c/ArregloAttack[i])
                        Amp=k+Thresh1
                    if i >CuadrosAttack:
                        c=Array4[i][0]-Thresh1
                        k=float(c/ratio)
                        Amp=k+Thresh1
                if Array4[i][0]<(Thresh1*(-1)):
                    if i<CuadrosAttack:
                        c=Array4[i][0]-Thresh1
                        k=float(c/ArregloAttack[i])
                        Amp=k+Thresh1
                    if i >CuadrosAttack:
                        c=Array4[i][0]-Thresh1
                        k=float(c/ratio)
                        Amp=k+Thresh1
                else:
                    Amp=Array4[i][0]

                ArrayComprimido4.append(Amp)

        Label1= Label(frame1, padx=15, pady=1, text="Compresor 1",fg = "white",bg = "black")
        Label1.pack(side=TOP)

        espacio2= Label(frame1, padx=15, pady=1, text=" ",fg = "white",bg = "black")
        espacio2.pack(side=TOP)

        #threshold
        Label2= Label(frame1, padx=15, pady=1, text="Threshold",fg = "white",bg = "black")
        Label2.pack(side=TOP)
        Threshold= Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=-60,to=0,bg = "yellow", fg="black")
        Threshold.pack(side=TOP)

        #ratio
        Label3= Label(frame1, padx=15, pady=1, text="Ratio",fg = "white",bg = "black")
        Label3.pack(side=TOP)
        Ratio=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=9,to=0,bg = "blue", fg="white")
        Ratio.pack(side=TOP)

        #attack
        Label4= Label(frame1, padx=15, pady=1, text="Attack",fg = "white",bg = "black")
        Label4.pack(side=TOP)
        Attack=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=50,to=500,bg = "red", fg="white")
        Attack.pack(side=TOP)

        #realease
        Label5= Label(frame1, padx=15, pady=1, text="Release",fg = "white",bg = "black")
        Label5.pack(side=TOP)
        Release=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=4000,to=5,fg = "white",bg = "black")
        Release.pack(side=TOP)

        #gain
        Label6= Label(frame1, padx=15, pady=1, text="Gain",fg = "white",bg = "black")
        Label6.pack(side=TOP)
        Gain=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=40,to=0,bg = "white", fg="black")
        Gain.pack(side=TOP)

        espacio1= Label(frame1, padx=15, pady=1, text=" ",fg = "white",bg = "black")
        espacio1.pack(side=TOP)

        # Comprimir
        ComprimirButton1 = Button(frame1, padx=30, pady=2, text="Comprimir",bg = "red",fg="white",command= compresoraudio4)
        ComprimirButton1.pack(side=TOP)

        compresor.mainloop()

    def PLAY():

        global Array1,Array2,Array3,Array4
        global Rec1,Rec2,Rec3,Rec4
        global ArrayFinal1,ArrayFinal2,ArrayFinal3,ArrayFinal4
        global ArrayComprimido1, ArrayComprimido2, ArrayComprimido3, ArrayComprimido4
        global FinalArray1,FinalArray2,FinalArray3,FinalArray4
        global MezclaFinalFinal,MezclaMixFinal

        ArrayFinal1 = np.asarray(Array1)
        ArrayFinal2 = np.asarray(Array2)
        ArrayFinal3 = np.asarray(Array3)
        ArrayFinal4 = np.asarray(Array4)

        ArregloCom1=np.asanyarray(ArrayComprimido1)
        ArregloCom2=np.asanyarray(ArrayComprimido2)
        ArregloCom3=np.asanyarray(ArrayComprimido3)
        ArregloCom4=np.asanyarray(ArrayComprimido4)

        #COMPRESOR 1
        if Compre1.get()==0:
            FinalArray1= NivelModificado1(ArrayFinal1,Nivel.get())
            if mute1.get()==1:#MUTE ON
                FinalArray1= (FinalArray1*0)
            if mute1.get()==0:#MUTE OFF
                FinalArray1= (FinalArray1*1)

        if Compre1.get()==1:
            FinalArray1=NivelModificado1(ArregloCom1,Nivel.get())
            if mute1.get()==1:#MUTE ON
                FinalArray1= (FinalArray1*0)
            if mute1.get()==0:#MUTE OFF
                FinalArray1= (FinalArray1*1)

        #COMPRESOR 2
        if Compre2.get()==0:
            FinalArray2= NivelModificado2(ArrayFinal2,Nivel2.get())
            if mute2.get()==1:#MUTE ON
                FinalArray2= (FinalArray2*0)
            if mute2.get()==0:#MUTE OFF
                FinalArray2= (FinalArray2*1)

        if Compre2.get()==1:
            FinalArray2=NivelModificado2(ArregloCom2,Nivel2.get())
            if mute2.get()==1:#MUTE ON
                FinalArray2= (FinalArray2*0)
            if mute2.get()==0:#MUTE OFF
                FinalArray2= (FinalArray2*1)

        #COMPRESOR 3
        if Compre3.get()==0:
            FinalArray3= NivelModificado3(ArrayFinal3,Nivel3.get())
            if mute3.get()==1:#MUTE ON
                FinalArray3= (FinalArray3*0)
            if mute3.get()==0:#MUTE OFF
                FinalArray3= (FinalArray3*1)

        if Compre3.get()==1:
            FinalArray3=NivelModificado3(ArregloCom3,Nivel3.get())
            if mute3.get()==1:#MUTE ON
                FinalArray3= (FinalArray2*0)
            if mute3.get()==0:#MUTE OFF
                FinalArray3= (FinalArray2*1)

        #COMPRESOR 4
        if Compre4.get()==0:
            FinalArray4= NivelModificado4(ArrayFinal4,Nivel4.get())
            if mute4.get()==1:#MUTE ON
                FinalArray4= (FinalArray4*0)
            if mute4.get()==0:#MUTE OFF
                FinalArray4= (FinalArray4*1)

        if Compre4.get()==1:
            FinalArray4=NivelModificado4(ArregloCom4,Nivel4.get())
            if mute4.get()==1:#MUTE ON
                FinalArray4= (FinalArray4*0)
            if mute4.get()==0:#MUTE OFF
                FinalArray4= (FinalArray4*1)

        # MEZCLA !!

        MezclaFinalFinal= [w+x+y+z for w,x,y,z in izip_longest(FinalArray1,FinalArray2,FinalArray3,FinalArray4,fillvalue=0)]
        MixFinalFinal= np.asarray(MezclaFinalFinal)
        NivelFaderMix= Nivel6.get()
        MezclaMixFinal= NivelModificadoMix(MixFinalFinal,NivelFaderMix)

        #REPRODUCCION EN TIEMPO REAL

        PlayRealTime=[]

        p=pyaudio.PyAudio()
        stream=p.open(format=2,channels=1,rate=44100,output=True)

        for k in range(0, len(MezclaMixFinal)):
            packed_value = struct.pack('<h', MezclaMixFinal[k])
            PlayRealTime.append(packed_value)



        value_str=''.join(PlayRealTime)
        stream.write(value_str)
        stream.close()

    def Aux():
        #ENVIO DE AUXILIAR

        global FinalArrayAux1,FinalArrayAux2,FinalArrayAux3,FinalArrayAux4
        global MezclaAUXFINAL, MezclaMixAux

        FinalArrayAux1= NivelModificado1(ArrayFinal4,ReverbNivel1.get())
        FinalArrayAux2= NivelModificado1(ArrayFinal4,ReverbNivel2.get())
        FinalArrayAux3= NivelModificado1(ArrayFinal4,ReverbNivel3.get())
        FinalArrayAux4= NivelModificado1(ArrayFinal4,ReverbNivel4.get())



        MezclaAUXFINAL= [w+x+y+z for w,x,y,z in izip_longest(FinalArrayAux1,FinalArrayAux2,FinalArrayAux3,FinalArrayAux4,fillvalue=0)]
        MixFinalFinalAux= np.asarray(MezclaAUXFINAL)
        NivelFaderAUX= Nivel5.get()
        MezclaMixAux= NivelModificadoMix(MixFinalFinalAux,NivelFaderAUX)

    def ExportarMix():

        global MezclaMixFinal

        doc=file(44100,16,'MEZCLA')
        doc.archive(MezclaMixFinal)

        mensaje2.pack(side=TOP)
        ReproButton1.pack(side=TOP)

    def Reproducir1():
        nombre = 'MEZCLA'
        reproduce(nombre)

    def RealPlay1():

        pygame.mixer.init(44100,-16,2,4096)
        Grabacion1 = pygame.mixer.Sound('AudioUno')
        Grabacion2 = pygame.mixer.Sound('AudioDos')
        Grabacion3 = pygame.mixer.Sound('AudioTres')
        Grabacion4 = pygame.mixer.Sound('AudioCuatro')

        RealTimePLay1(Grabacion1,Grabacion2,Grabacion3,Grabacion4,Nivel.get(),Nivel2.get(),Nivel3.get(),Nivel4.get(),Nivel6.get(),mute1.get(),mute2.get(),mute3.get(),mute4.get())

# Label para la interfraz grafica - definicion de los botones----------------------------------------------------------------------------------------

    Label1= Label(frame1, padx=15, pady=1, text="Luis Sandoval, Andres Palacio, Libardo Montealegre",fg = "white",bg = "black")
    Label1.pack(side=TOP)

    mensaje1 = Label(frame1, fg='red', padx=15, pady=10, text='Grabando...',bg = "black" )

    #CHANEL 1--------------------------------------------------------------------------------------------------------------

    mute1=IntVar()
    Eq1 = IntVar()
    Compre1 = IntVar()

    Label2= Label(frame2, padx=15, pady=1, text=" Canal 1",fg = "red",bg = "black")
    Label2.pack(side=TOP)

    RecordButton1 = Button(frame2, padx=30, pady=2, text="Record 1",bg = "red",fg="white", command= Grabar1 )
    RecordButton1.pack(side=TOP)

    StopButton1 = Button(frame2, padx=30, pady=2, text=" Stop ",bg = "red",fg="white", command= Stop1)
    StopButton1.pack(side=TOP)

    LabelPro1= Label(frame2, padx=15, pady=1, text="Procesos",fg = "red",bg = "black")
    LabelPro1.pack(side=TOP)

    EQButton1 =  Checkbutton(frame2, padx=30,variable= Eq1,onvalue=1,offvalue=0, pady=2, text="EQ1",bg = "red",fg="black", command= Equal1)
    EQButton1.pack(side=TOP)

    ACompresorButton1= Button(frame2, padx=30, pady=2, text="Compresor",bg = "red",fg="black",command=Compresor1)
    ACompresorButton1.pack(side=TOP)

    CompresorButton1= Checkbutton(frame2, padx=30,variable= Compre1,onvalue=1,offvalue=0, pady=2, text="ON / OFF",bg = "black",fg="red")
    CompresorButton1.pack(side=TOP)

    LabelReverb1= Label(frame2, padx=15, pady=1, text="Reverb",fg = "red",bg = "black")
    LabelReverb1.pack(side=TOP)

    ReverbNivel1 = Scale(frame2, from_= -20.0, to=0.0, orient= HORIZONTAL, resolution=0.1,bg = "red", fg="white")
    ReverbNivel1.pack(side=TOP)

    MuteButton1 = Checkbutton(frame2, padx=30,variable= mute1,onvalue=1,offvalue=0, pady=2, text="MUTE",bg = "red",fg="black")
    MuteButton1.pack(side=TOP)

    Nivel = Scale(frame2, from_= -20.0, to=0.0,length = 200, orient= VERTICAL, resolution=0.1,bg = "red", fg="white")
    Nivel.pack(side=TOP, padx=1, pady=1)

    #CHANEL 2------------------------------------------------------------------------------------------------

    mute2 = IntVar()
    Eq2 = IntVar()
    Compre2 = IntVar()

    Label3= Label(frame3, padx=15, pady=1, text=" Canal 2",fg = "blue",bg = "black")
    Label3.pack(side=TOP)

    RecordButton2 = Button(frame3, padx=30, pady=2, text="Record 2",bg = "blue",fg="white",command= Grabar2 )
    RecordButton2.pack(side=TOP)

    StopButton2 = Button(frame3, padx=30, pady=2, text=" Stop ",bg = "blue",fg="white",command= Stop2 )
    StopButton2.pack(side=TOP)

    LabelPro2= Label(frame3, padx=15, pady=1, text="Procesos",fg = "blue",bg = "black")
    LabelPro2.pack(side=TOP)

    EQButton2 =  Checkbutton(frame3, padx=30,variable= Eq2,onvalue=1,offvalue=0, pady=2, text="EQ2",bg = "blue",fg="black",command= Equal2)
    EQButton2.pack(side=TOP)

    ACompresorButton2= Button(frame3, padx=30, pady=2, text="Compresor",bg = "blue",fg="black",command=Compresor2)
    ACompresorButton2.pack(side=TOP)

    CompresorButton2= Checkbutton(frame3, padx=30,variable= Compre2,onvalue=1,offvalue=0, pady=2, text="ON / OFF",bg = "black",fg="blue")
    CompresorButton2.pack(side=TOP)

    LabelReverb2= Label(frame3, padx=15, pady=1, text="Reverb",fg = "blue",bg = "black")
    LabelReverb2.pack(side=TOP)

    ReverbNivel2 = Scale(frame3, from_= -20.0, to=0.0, orient= HORIZONTAL, resolution=0.1,bg = "blue", fg="white")
    ReverbNivel2.pack(side=TOP)

    MuteButton2 = Checkbutton(frame3, padx=30,variable= mute2,onvalue=1,offvalue=0, pady=2, text="MUTE",bg = "blue",fg="black")
    MuteButton2.pack(side=TOP)

    Nivel2 = Scale(frame3, from_= -20.0, to=0.0,length = 200, orient= VERTICAL, resolution=0.1,bg = "blue", fg="white")
    Nivel2.pack(side=TOP, padx=1, pady=1)

    #CHANEL 3-----------------------------------------------------------------------------
    mute3 = IntVar()
    Eq3 = IntVar()
    Compre3 = IntVar()

    Label4= Label(frame4, padx=15, pady=1, text=" Canal 3",fg = "green",bg = "black")
    Label4.pack(side=TOP)

    RecordButton3 = Button(frame4, padx=30, pady=2, text="Record 3",bg = "green",fg="white",command= Grabar3)
    RecordButton3.pack(side=TOP)

    StopButton3 = Button(frame4, padx=30, pady=2, text=" Stop ",bg = "green",fg="white",command= Stop3)
    StopButton3.pack(side=TOP)

    LabelPro3= Label(frame4, padx=15, pady=1, text="Procesos",fg = "green",bg = "black")
    LabelPro3.pack(side=TOP)

    EQButton3 =  Checkbutton(frame4, padx=30,variable= Eq3,onvalue=1,offvalue=0, pady=2, text="EQ3",bg = "green",fg="black",command= Equal3)
    EQButton3.pack(side=TOP)

    ACompresorButton3= Button(frame4, padx=30, pady=2, text="Compresor",bg = "green",fg="black",command=Compresor3)
    ACompresorButton3.pack(side=TOP)

    CompresorButton3 = Checkbutton(frame4, padx=30,variable= Compre3,onvalue=1,offvalue=0, pady=2, text="ON / OFF",bg = "black",fg="green")
    CompresorButton3.pack(side=TOP)

    LabelReverb3= Label(frame4, padx=15, pady=1, text="Reverb",fg = "green",bg = "black")
    LabelReverb3.pack(side=TOP)

    ReverbNivel3 = Scale(frame4, from_= -20.0, to=0.0, orient= HORIZONTAL, resolution=0.1,bg = "green", fg="white")
    ReverbNivel3.pack(side=TOP)

    MuteButton3 = Checkbutton(frame4, padx=30,variable= mute3,onvalue=1,offvalue=0, pady=2, text="MUTE",bg = "green",fg="black")
    MuteButton3.pack(side=TOP)

    Nivel3 = Scale(frame4, from_= -20.0, to=0.0,length = 200, orient= VERTICAL, resolution=0.1,bg = "green", fg="white")
    Nivel3.pack(side=TOP, padx=1, pady=1)

    #CHANEL 4-------------------------------------------------------------------------------------------

    mute4 = IntVar()
    Eq4 = IntVar()
    Compre4 = IntVar()


    Label5= Label(frame5, padx=15, pady=1, text=" Canal 4",fg = "purple",bg = "black")
    Label5.pack(side=TOP)

    RecordButton4 = Button(frame5, padx=30, pady=2, text="Record 4",bg = "purple",fg="white", command= Grabar4)
    RecordButton4.pack(side=TOP)

    StopButton4 = Button(frame5, padx=30, pady=2, text=" Stop ",bg = "purple",fg="white", command= Stop4)
    StopButton4.pack(side=TOP)

    LabelPro4= Label(frame5, padx=15, pady=1, text="Procesos",fg = "purple",bg = "black")
    LabelPro4.pack(side=TOP)

    EQButton4 =  Checkbutton(frame5, padx=30,variable= Eq4,onvalue=1,offvalue=0, pady=2, text="EQ4",bg = "purple",fg="black",command= Equal4)
    EQButton4.pack(side=TOP)

    ACompresorButton4= Button(frame5, padx=30, pady=2, text="Compresor",bg = "purple",fg="black",command=Compresor4)
    ACompresorButton4.pack(side=TOP)

    CompresorButton4 = Checkbutton(frame5, padx=30,variable= Compre4,onvalue=1,offvalue=0, pady=2, text="ON / OFF ",bg = "black",fg="purple")
    CompresorButton4.pack(side=TOP)

    LabelReverb4= Label(frame5, padx=15, pady=1, text="Reverb",fg = "purple",bg = "black")
    LabelReverb4.pack(side=TOP)

    ReverbNivel4 = Scale(frame5, from_= -20.0, to=0.0, orient= HORIZONTAL, resolution=0.1,bg = "purple", fg="white")
    ReverbNivel4.pack(side=TOP)

    MuteButton4 = Checkbutton(frame5, padx=30,variable= mute4,onvalue=1,offvalue=0, pady=2, text="MUTE",bg = "purple",fg="black")
    MuteButton4.pack(side=TOP)

    Nivel4 = Scale(frame5, from_= -20.0, to=0.0,length = 200, orient= VERTICAL, resolution=0.1,bg = "purple", fg="white")
    Nivel4.pack(side=TOP, padx=1, pady=1)

    # AUXILIAR------------------------------------------------------------------------------------------

    Label6= Label(frame6, padx=15, pady=1, text=" Auxiliar Reverb",fg = "orange",bg = "black")
    Label6.pack(side=TOP)

    Nivel5 = Scale(frame6, from_= -20.0, to=0.0,length = 200, orient= VERTICAL, resolution=0.1,bg = "orange", fg="white")
    Nivel5.pack(side=TOP, padx=1, pady=1)

    AUXButton = Button(frame6, padx=10, pady=2, text="AUX MIX",bg = "orange",fg="black",command= Aux)
    AUXButton.pack(side=TOP)

    # MAIN MIX ------------------------------------------------------------------------------------------

    Label7= Label(frame7, padx=15, pady=1, text=" Main MIX",fg = "turquoise",bg = "black")
    Label7.pack(side=TOP)

    Nivel6 = Scale(frame7, from_= -20.0, to=0.0,length = 200, orient= VERTICAL, resolution=0.1,bg = "turquoise", fg="black")
    Nivel6.pack(side=TOP, padx=1, pady=1)

    PlayButton = Button(frame7, padx=30, pady=2, text="PLAY",bg = "turquoise",fg="black",command= PLAY)
    PlayButton.pack(side=TOP)

    StopButton = Button(frame7, padx=30, pady=2, text="STOP",bg = "turquoise",fg="black")
    StopButton.pack(side=TOP)

    ExportButton = Button(frame7, padx=30, pady=2, text="Exportar",bg = "turquoise",fg="black",command= ExportarMix)
    ExportButton.pack(side=TOP)

    mensaje2 = Label(frame7, fg='green', padx=15, pady=10, text='Archivo Exportado',bg = "black")

    ReproButton1 = Button(frame7, padx=30, pady=2, text="Reproducir Archivo Exportado",command=Reproducir1 ,bg = "turquoise",fg="black")

    ventana.mainloop()
Example #41
0
    else:
        try:
            unicode_text = f.decode('utf-8')
        except UnicodeDecodeError:
            print('unicode error, trying different encoding')
        else:
            abs_path = os.path.join(os.path.dirname(__file__), 'output_from_utf8_to_cp1251.txt')
            text_in_1251 = unicode_text.encode('cp1251')
            f = open(abs_path, 'w')
            f.write(text_in_1251)


root = Tk()
root.title('UTF-8 Converter')
root.geometry('250x250+500+300')
root.config(background="#FFFFFF")

button = Tkinter.Button(root, text="Check encoding", width=25, bg="#FFFFFF", command=open_file)
button.pack(fill=X, padx=10, pady=20)

res = Label(root, bg="#FFFFFF")
res.pack()

button1 = Tkinter.Button(root, text="Convert from windows-1251 to utf-8", width=25, bg="#FFFFFF",
                         command=convert_from_windows_1251)
button1.pack(fill=X, padx=10, pady=15)

button1 = Tkinter.Button(root, text="Convert from utf-8 to windows-1251", width=25, bg="#FFFFFF",
                         command=convert_from_utf8_to_windows_1251)
button1.pack(fill=X, padx=10, pady=15)
    def Compresor4():

        compresor=Tk()

        compresor.title("Compresor 4 ")
        compresor.config(bg = "black")

        # Uso de frames para organizar la ventana.
        frame1 = Frame(compresor,bg = "black")
        frame1.pack(side=TOP)

        global Array4, ArrayComprimido4

        def compresoraudio4():

            NivelThresh=Threshold.get()
            Thresh1 = (10**float(NivelThresh/20))*((2**16)/2.0)
            Attack1=float(Attack.get()/1000.0)
            CuadrosAttack=int(Attack1*44100)
            ratio=Ratio.get()
            Knee=float((ratio-1)/CuadrosAttack)

            ArregloAttack=[]

            for j in range(1, CuadrosAttack):
                Dato1=1+float(Knee*j)
                ArregloAttack.append(Dato1)


            for i in range(0, len(Array4)):

                if Array4[i][0]>Thresh1:
                    if i<CuadrosAttack:
                        c=Array4[i][0]-Thresh1
                        k=float(c/ArregloAttack[i])
                        Amp=k+Thresh1
                    if i >CuadrosAttack:
                        c=Array4[i][0]-Thresh1
                        k=float(c/ratio)
                        Amp=k+Thresh1
                if Array4[i][0]<(Thresh1*(-1)):
                    if i<CuadrosAttack:
                        c=Array4[i][0]-Thresh1
                        k=float(c/ArregloAttack[i])
                        Amp=k+Thresh1
                    if i >CuadrosAttack:
                        c=Array4[i][0]-Thresh1
                        k=float(c/ratio)
                        Amp=k+Thresh1
                else:
                    Amp=Array4[i][0]

                ArrayComprimido4.append(Amp)

        Label1= Label(frame1, padx=15, pady=1, text="Compresor 1",fg = "white",bg = "black")
        Label1.pack(side=TOP)

        espacio2= Label(frame1, padx=15, pady=1, text=" ",fg = "white",bg = "black")
        espacio2.pack(side=TOP)

        #threshold
        Label2= Label(frame1, padx=15, pady=1, text="Threshold",fg = "white",bg = "black")
        Label2.pack(side=TOP)
        Threshold= Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=-60,to=0,bg = "yellow", fg="black")
        Threshold.pack(side=TOP)

        #ratio
        Label3= Label(frame1, padx=15, pady=1, text="Ratio",fg = "white",bg = "black")
        Label3.pack(side=TOP)
        Ratio=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=9,to=0,bg = "blue", fg="white")
        Ratio.pack(side=TOP)

        #attack
        Label4= Label(frame1, padx=15, pady=1, text="Attack",fg = "white",bg = "black")
        Label4.pack(side=TOP)
        Attack=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=50,to=500,bg = "red", fg="white")
        Attack.pack(side=TOP)

        #realease
        Label5= Label(frame1, padx=15, pady=1, text="Release",fg = "white",bg = "black")
        Label5.pack(side=TOP)
        Release=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=4000,to=5,fg = "white",bg = "black")
        Release.pack(side=TOP)

        #gain
        Label6= Label(frame1, padx=15, pady=1, text="Gain",fg = "white",bg = "black")
        Label6.pack(side=TOP)
        Gain=Scale(frame1, orient=HORIZONTAL,width=10, length=250,from_=40,to=0,bg = "white", fg="black")
        Gain.pack(side=TOP)

        espacio1= Label(frame1, padx=15, pady=1, text=" ",fg = "white",bg = "black")
        espacio1.pack(side=TOP)

        # Comprimir
        ComprimirButton1 = Button(frame1, padx=30, pady=2, text="Comprimir",bg = "red",fg="white",command= compresoraudio4)
        ComprimirButton1.pack(side=TOP)

        compresor.mainloop()
Example #43
0
class TkApplicationWindow(AbstractApplicationWindow):

    def __init__(self, app):
        self.root = Tk()
        self.root.title("Llia")
        self.root.config(background=factory.bg())
        super(TkApplicationWindow, self).__init__(app, self.root)
        self.root.withdraw()
        if app.config()["enable-splash"]:
            splash = TkSplashWindow(self.root, app)
        self.root.deiconify()
        self.root.protocol("WM_DELETE_WINDOW", self.exit_app)
        self.llia_graph = None
        self._main = layout.BorderFrame(self.root)
        self._main.config(background=factory.bg())
        self._main.pack(anchor="nw", expand=True, fill=BOTH)
        self._progressbar = None
        self._init_status_panel()
        self._init_menu()
        self._init_center_frame(self._main.center)
        self.root.minsize(width=665, height=375)
        self.group_windows = []
        self.add_synth_group()
        self._scene_filename = ""
        
    def _init_status_panel(self):
        south = self._main.south
        south.configure(padx=4, pady=4)
        self._lab_status = factory.label(south, "", modal=False)
        b_panic = factory.panic_button(south)
        b_down = factory.button(south, "-")
        b_up = factory.button(south, "+")
        b_panic.grid(row=0, column=0)
        self._progressbar = Progressbar(south,mode="indeterminate")
        self._progressbar.grid(row=0,column=PROGRESSBAR_COLUMN, sticky='w', padx=8)
        self._lab_status.grid(row=0,column=4, sticky='w')
        south.config(background=factory.bg())
        b_down.configure(command=lambda: self.root.lower())
        b_up.configure(command=lambda: self.root.lift())
        self.update_progressbar(100, 0)
        
    def _tab_change_callback(self, event):
        self.llia_graph.sync()
    
    def _init_center_frame(self, master):
        nb = ttk.Notebook(master)
        nb.pack(expand=True, fill="both")
        frame_synths = layout.FlowGrid(nb, 6)
        frame_efx = layout.FlowGrid(nb, 6)
        frame_controllers = layout.FlowGrid(nb, 6)
        self.llia_graph = LliaGraph(nb, self.app)
        nb.add(frame_synths, text = "Synths")
        nb.add(frame_efx, text = "Effects")
        nb.add(frame_controllers, text = "Controllers")
        nb.add(self.llia_graph, text="Graph")
        nb.bind("<Button-1>", self._tab_change_callback)

        def display_info_callback(event):
            sp = event.widget.synth_spec
            msg = "%s:    %s" % (sp["format"],sp["description"])
            self.status(msg)

        def clear_info_callback(*_):
            self.status("")
        
        for st in con.SYNTH_TYPES:
            sp = specs[st]
            ttp = "Add %s Synthesizer (%s)" % (st, sp["description"])
            b = factory.logo_button(frame_synths, st, ttip=ttp)
            b.synth_spec = sp
            b.bind("<Button-1>", self._show_add_synth_dialog)
            b.bind("<Enter>", display_info_callback)
            b.bind("<Leave>", clear_info_callback)
            frame_synths.add(b)
        for st in con.EFFECT_TYPES:
            sp = specs[st]
            ttp = "Add %s Effect (%s)" % (st, sp["description"])
            b = factory.logo_button(frame_efx, st, ttip=ttp)
            b.synth_spec = sp
            b.bind("<Button-1>", self._show_add_efx_dialog)
            b.bind("<Enter>", display_info_callback)
            b.bind("<Leave>", clear_info_callback)
            frame_efx.add(b)
        for st in con.CONTROLLER_SYNTH_TYPES:
            sp = specs[st]
            ttp = "Add %s Effect (%s)" % (st, sp["description"])
            b = factory.logo_button(frame_controllers, st, ttip=ttp)
            b.synth_spec = sp
            b.bind("<Button-1>", self._show_add_controller_dialog)
            b.bind("<Enter>", display_info_callback)
            b.bind("<Leave>", clear_info_callback)
            frame_controllers.add(b)
    
    @staticmethod
    def menu(master):
        m = Menu(master, tearoff=0)
        m.config(background=factory.bg(), foreground=factory.fg())
        return m
    
    def _init_menu(self):
        main_menu = self.menu(self.root)
        self.root.config(menu=main_menu)
        file_menu = self.menu(main_menu)
        osc_menu = self.menu(main_menu)
        midi_menu = self.menu(main_menu)
        bus_menu = self.menu(main_menu)
        #buffer_menu = self.menu(main_menu)
        tune_menu = self.menu(main_menu)
        help_menu = self.menu(main_menu)
        main_menu.add_cascade(label="File", menu=file_menu)
        main_menu.add_cascade(label="OSC", menu=osc_menu)
        main_menu.add_cascade(label="MIDI", menu=midi_menu)
        #main_menu.add_cascade(label="Buses", menu=bus_menu)
        #main_menu.add_cascade(label="Buffers", menu=buffer_menu)
        #main_menu.add_cascade(label="Tune", menu=tune_menu)
        #main_menu.add_cascade(label="Help", menu=help_menu)
        self._init_file_menu(file_menu)
        self._init_osc_menu(osc_menu)
        self._init_midi_menu(midi_menu)
        self._init_bus_menu(bus_menu)
        #self._init_buffer_menu(buffer_menu)
        self._init_tune_menu(tune_menu)
        self._init_help_menu(help_menu)

    def _init_file_menu(self, fmenu):
        fmenu.add_command(label="Save Scene", command = self.save_scene)
        fmenu.add_command(label="Load Scene", command = self.load_scene)
        fmenu.add_separator()
        fmenu.add_command(label="Lliascript (Legacy)", command = self.show_history_editor)
        fmenu.add_separator()
        fmenu.add_command(label="New Synth Group", command = self._add_synth_group)
        fmenu.add_separator()
        fmenu.add_command(label="Restart", command = self._interactive_tabula_rasa)
        fmenu.add_command(label="Quit", command = self.exit_app)

    def _init_osc_menu(self, iomenu):
        iomenu.add_command(label="Ping", command = self.ping_global)
        iomenu.add_command(label="Dump", command = self.app.proxy.dump)
        iomenu.add_command(label="Toggle OSC Trace", command = self.toggle_osc_trace)

    def _init_midi_menu(self, mmenu):
        map_menu = self.menu(mmenu)
        mmenu.add_command(label = "Channel Names", command = self.show_channel_name_dialog)
        mmenu.add_command(label = "Controller Names", command = self.show_controller_name_dialog)
        mmenu.add_cascade(label = "MIDI Maps", menu = map_menu)
        mmenu.add_command(label = "Toggle MIDI Input Trace", command = self.toggle_midi_input_trace)
        mmenu.add_command(label = "Toggle MIDI Output Trace", command = self.toggle_midi_output_trace)
        mmenu.add_command(label = "Toggle Program Pretty Printer", command = self.toggle_program_pretty_printer)
        
    def _init_bus_menu(self, bmenu):
        bmenu.add_command(label="Audio", command=self.show_audiobus_dialog)
        bmenu.add_command(label="Control", command=self.show_controlbus_dialog)
        
    # def _init_buffer_menu(self, bmenu):
    #     bmenu.add_command(label="View Buffers", command=self.show_bufferlist_dialog)

    def _init_tune_menu(self, tmenu):
        tmenu.add_command(label = "FIX ME: Nothing to see here")

    def _init_help_menu(self, hmenu):
        pass
        
    def exit_gui(self):
        try:
            self.root.destroy()
        except:
            pass

    def confirm_exit(self):
        return tkMessageBox.askyesno("Exit Llia", "Exit Llia?")
        
    def exit_app(self):
        self.app.exit_()

    def as_widget(self):
        return self.root
        
    def status(self, msg):
        self._lab_status.config(text=str(msg))

    def warning(self, msg):
        msg = "WARNING: %s" % msg
        self._lab_status.config(text=msg)
        
    def clear_status(self):
        self.status("")
                                              
    def start_gui_loop(self):
        self.root.mainloop()

    def show_about_dialog(self):
        from llia.gui.tk.tk_about_dialog import TkAboutDialog
        dialog = TkAboutDialog(self.root, self.app)
        self.root.wait_window(dialog)

    def display_help(self, topic=None):
        pass
        
    def show_history_editor(self):
        from llia.gui.tk.tk_history import TkHistoryEditor
        dialog = TkHistoryEditor(self.root, self.app)
        self.root.wait_window(dialog)

    def ping_global(self):
        try:
            rs = self.app.proxy.ping()
            if rs:
                self.status("Ping OK")
            else:
                self.warning("Ping Error")
        except LliaPingError as err:
            self.warning(err.message)

    def toggle_osc_trace(self):
        LliaProxy.trace = not LliaProxy.trace
        if LliaProxy.trace:
            self.status("OSC transmission trace enabled")
        else:
            self.status("OSC transmission trace disabled")

    def show_channel_name_dialog(self):
        from llia.gui.tk.tk_channel_name_editor import TkChannelNameEditor
        dialog = TkChannelNameEditor(self.root, self.app)
        self.root.wait_window(dialog)
  
    def show_controller_name_dialog(self):
        from llia.gui.tk.tk_controller_name_editor import TkControllerNameEditor
        dialog = TkControllerNameEditor(self.root, self.app)
        self.root.wait_window(dialog)
    
    def toggle_midi_input_trace(self):
        flag = not self.app.midi_in_trace
        self.app.midi_in_trace = flag
        self.app.midi_receiver.enable_trace(flag)
        if flag:
            self.status("MIDI input trace enabled")
        else:
            self.status("MIDI output trace disabled")

    def toggle_midi_output_trace(self):
        self.status("MIDI output not available") # FIX ME

    def toggle_program_pretty_printer(self):
        self.app.pp_enabled = not self.app.pp_enabled
        if self.app.pp_enabled:
            self.status("Pretty printer enabled")
        else:
            self.status("Pretty printer disabled")
        
    def show_audiobus_dialog(self):
        from llia.gui.tk.tk_audiobus_editor import TkAudiobusEditor
        dialog = TkAudiobusEditor(self.root, self.app)
        self.root.wait_window(dialog)

    def show_controlbus_dialog(self):
        from llia.gui.tk.tk_controlbus_editor import TkControlbusEditor
        dialog = TkControlbusEditor(self.root, self.app)
        self.root.wait_window(dialog)

    # def show_bufferlist_dialog(self):
    #     from llia.gui.tk.tk_buffer_info import TkBufferListDialog
    #     dialog = TkBufferListDialog(self.root, self.app)
    #     self.root.wait_window(dialog)

    def _show_add_synth_dialog(self, event):
        w = event.widget
        st = w.config()["text"][-1]
        dialog = TkAddSynthDialog(self.root, self.app, st, False)
        self.root.wait_window(dialog)
        
    def _show_add_efx_dialog(self, event):
        w = event.widget
        st = w.config()["text"][-1]
        dialog = TkAddSynthDialog(self.root, self.app, st, is_efx=True, is_controller=False)
        self.root.wait_window(dialog)

    def _show_add_controller_dialog(self, event):
        w = event.widget
        st = w.config()["text"][-1]
        dialog = TkAddSynthDialog(self.root, self.app, st, is_efx=False, is_controller=True)
        self.root.wait_window(dialog)
        
    def _add_synth_group(self):
        sh = self.app.ls_parser.synthhelper
        sh.new_group()
        
    def add_synth_group(self, name=None):
        gw = GroupWindow(self.app, self.root, name)
        # gw.transient(self.root)  # If executed keeps main app window behind all other windows.
        self.group_windows.append(gw)
        self.status("Added new Synth Group Window")
        return gw

    def display_synth_editor(self, sid):
        try:
            swin = self[sid]
            grpid = swin.group_index
            grp = self.group_windows[grpid]
            #grp.deiconify()
            grp.show_synth_editor(sid)
        except (KeyError, IndexError):
            msg = "Can not find editor for %s" % sid
            self.warning(msg)

    def update_progressbar(self, count, value):
        self._progressbar.config(mode="determinate", maximum=count)
        self._progressbar.step()
        self.root.update_idletasks()
            
    def busy(self, flag, message=""):
        if message:
            self.status(message)
        self._progressbar.config(mode="indeterminate")
        if flag:
            self._progressbar.grid(row=0, column=PROGRESSBAR_COLUMN, sticky='w', padx=8)
            self._progressbar.start()
        else:
            self._progressbar.stop()
            # self._progressbar.grid_remove()
        self.root.update_idletasks()

    def save_scene(self, *_):
        options = {'defaultextension' : '.llia',
                   'filetypes' : [('Llia Scenes', '*.llia'),
                                  ('all files', '*')],
                   'initialfile' : self._scene_filename,
                   'parent' : self.root,
                   'title' : "Save Llia Scene"}
        filename = tkFileDialog.asksaveasfilename(**options)
        if filename:
            try:
                self.app.ls_parser.save_scene(filename)
                self._scene_filename = filename
                self.status("Scene saved as '%s'" % filename)
            except Exception as ex:
                self.warning(ex.message)
        else:
            self.status("Scene save canceld")    

    def load_scene(self, *_):
        options = {'defaultextension' : '.llia',
                   'filetypes' : [('Llia Scenes', '*.llia'),
                                  ('all files', '*')],
                   'initialfile' : self._scene_filename,
                   'parent' : self.root,
                   'title' : "Load Llia Scene"}
        filename = tkFileDialog.askopenfilename(**options)
        if filename:
            try:
                self.app.ls_parser.load_scene(filename)
                self.status("Scene '%s' loaded" % filename)
                self._scene_filename = filename
            except Exception as ex:
                self.warning(ex.message)
        else:
            self.status("Load scene canceld")
            
    def tabula_rasa(self):
        for grp in self.group_windows:
            grp.tabula_rasa()
        self.group_windows = []

    def _interactive_tabula_rasa(self, *_):
        # ISSUE: Check config and ask user confirmation before existing
        self.app.ls_parser.tabula_rasa()
class OSCMonitor(object):

    def __init__(self):
    
        self.editor_issue="1.3"

        # get command options
        self.command_options=remote_options()

        # get directory holding the code
        self.pp_dir=sys.path[0]
            
        if not os.path.exists(self.pp_dir+os.sep+"pipresents.py"):
            tkMessageBox.showwarning("Pi Presents","Bad Application Directory")
            exit()
            
          
        # Initialise logging
        Monitor.log_path=self.pp_dir
        self.mon=Monitor()
        self.mon.init()
        
        Monitor.classes  = ['OSCMonitor','OSCConfig','OSCEditor']

        Monitor.log_level = int(self.command_options['debug'])

        self.mon.log (self, "Pi Presents Monitor is starting")
        self.mon.log (self," OS and separator " + os.name +'  ' + os.sep)
        self.mon.log(self,"sys.path[0] -  location of code: code "+sys.path[0])

        self.setup_gui()

        # initialise OSC config class
        self.osc_config=OSCConfig()

        self.init()

        #and start the system
        self.root.after(1000,self.run_app)
        self.root.mainloop()


    def init(self):
        # read the options and allow their editing
        self.osc_config_file = self.pp_dir + os.sep + 'pp_config' + os.sep + 'pp_oscmonitor.cfg'
        self.read_create_osc()


    def add_status(self,text):
        self.status_display.insert(END,text+'\n')
        self.status_display.see(END)

    def run_app(self):
        self.client=None
        self.server=None
        self.st=None
        
        # initialise OSC variables
        self.prefix='/pipresents'
        self.this_unit='/' + self.osc_config.this_unit_name
        self.add_status('this unit is: '+self.this_unit)
        self.controlled_by_unit='/'+self.osc_config.controlled_by_name
        self.add_status('controlled by unit : '+self.controlled_by_unit)
       
        #connect client for replies then start server to listen for commands
        self.client = OSC.OSCClient()
        self.add_status('connecting to controlled by unit: '+self.osc_config.controlled_by_ip+':'+self.osc_config.controlled_by_port +' '+self.osc_config.controlled_by_name)
        self.client.connect((self.osc_config.controlled_by_ip,int(self.osc_config.controlled_by_port)))
        self.add_status('listening for commands on:'+self.osc_config.this_unit_ip+':'+self.osc_config.this_unit_port)
        self.init_server(self.osc_config.this_unit_ip,self.osc_config.this_unit_port,self.client)
        self.add_initial_handlers()
        self.start_server()



    # ***************************************
    # OSC CLIENT TO SEND REPLIES
    # ***************************************

    def disconnect_client(self):
        if self.client != None:
            self.client.close()
        return


    # ***************************************
    # OSC SERVER TO LISTEN TO COMMANDS
    # ***************************************

    def init_server(self,ip,port_text,client):
        self.add_status('Init Server: '+ip+':'+port_text)
        self.server = myOSCServer((ip,int(port_text)),client)

    def start_server(self):
        self.add_status('Start Server')
        self.st = threading.Thread( target = self.server.serve_forever )
        self.st.start()

    def close_server(self):
        if self.server != None:
            self.server.close()
        self.mon.log(self, 'Waiting for Server-thread to finish')
        if self.st != None:
            self.st.join() ##!!!
        self.mon.log(self,'server thread closed')


    def add_initial_handlers(self):
        pass
        self.server.addMsgHandler('default', self.no_match_handler)
        self.server.addMsgHandler(self.prefix+self.this_unit+"/system/server-info", self.server_info_handler)
        self.server.addMsgHandler(self.prefix+self.this_unit+"/system/loopback", self.loopback_handler)


    def no_match_handler(self,addr, tags, stuff, source):
        text= "Message from %s" % OSC.getUrlStr(source)+'\n'
        text+= "     %s" % addr+ self.pretty_list(stuff)
        self.add_status(text+'\n')


    def server_info_handler(self,addr, tags, stuff, source):
        msg = OSC.OSCMessage(self.prefix+self.controlled_by_unit+'/system/server-info-reply')
        msg.append('Unit: '+ self.osc_config.this_unit_name)
        self.add_status('Server Info Request from %s:' % OSC.getUrlStr(source))           
        return msg


    def loopback_handler(self,addr, tags, stuff, source):
         # send a reply to the client.
        msg = OSC.OSCMessage(self.prefix+self.controlled_by_unit+'/system/loopback-reply')
        self.add_status('Loopback Request from %s:' % OSC.getUrlStr(source))
        return msg      



    def pretty_list(self,fields):
        text=' '
        for field in fields:
            text += str(field) + ' '
        return text


    # ***************************************
    # INIT EXIT MISC
    # ***************************************


    def e_edit_osc(self):
        self.disconnect_client()
        self.close_server()
        self.edit_osc()
        self.init()
        self.add_status('\n\n\nRESTART')
        self.run_app()


    def app_exit(self):
        self.disconnect_client()
        self.close_server()
        if self.root is not None:
            self.root.destroy()
        self.mon.finish()
        sys.exit() 


    def show_help (self):
        tkMessageBox.showinfo("Help","Read 'manual.pdf'")
  

    def about (self):
        tkMessageBox.showinfo("About","Simple Remote Monitor for Pi Presents\n"
                              +"Author: Ken Thompson"
                              +"\nWebsite: http://pipresents.wordpress.com/")


    def setup_gui(self):
        # set up the gui
 
        # root is the Tkinter root widget
        self.root = Tk()
        self.root.title("Remote Monitor for Pi Presents")

        # self.root.configure(background='grey')

        self.root.resizable(False,False)

        # define response to main window closing
        self.root.protocol ("WM_DELETE_WINDOW", self.app_exit)

        # bind some display fields
        self.filename = StringVar()
        self.display_show = StringVar()
        self.results = StringVar()
        self.status = StringVar()

        # define menu
        menubar = Menu(self.root)

        toolsmenu = Menu(menubar, tearoff=0, bg="grey", fg="black")
        menubar.add_cascade(label='Tools', menu = toolsmenu)

        osc_configmenu = Menu(menubar, tearoff=0, bg="grey", fg="black")
        menubar.add_cascade(label='Options', menu = osc_configmenu)
        osc_configmenu.add_command(label='Edit', command = self.e_edit_osc)

        helpmenu = Menu(menubar, tearoff=0, bg="grey", fg="black")
        menubar.add_cascade(label='Help', menu = helpmenu)
        helpmenu.add_command(label='Help', command = self.show_help)
        helpmenu.add_command(label='About', command = self.about)
         
        self.root.config(menu=menubar)

        # status_frame      
        status_frame=Frame(self.root,padx=5,pady=5)
        status_frame.pack(side=TOP, fill=BOTH, expand=1)
        status_label = Label(status_frame, text="Status",font="arial 12 bold")
        status_label.pack(side=LEFT)
        scrollbar = Scrollbar(status_frame, orient=VERTICAL)
        self.status_display=Text(status_frame,height=10, yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.status_display.yview)
        scrollbar.pack(side=RIGHT, fill=Y)
        self.status_display.pack(side=LEFT,fill=BOTH, expand=1)


# ***************************************
#  OSC CONFIGURATION
# ***************************************

    def read_create_osc(self):
        if self.osc_config.read(self.osc_config_file) is False:
            self.osc_config.create(self.osc_config_file)
            eosc = OSCEditor(self.root, self.osc_config_file,'slave','Create OSC Monitor Configuration')
            self.osc_config.read(self.osc_config_file)


    def edit_osc(self):
        if self.osc_config.read(self.osc_config_file) is False:
            self.osc_config.create(self.osc_config_file)
        eosc = OSCEditor(self.root, self.osc_config_file,'slave','Edit OSC Monitor Configuration')
Example #45
0
                           textvariable=stage4Pos,
                           anchor=W,
                           bg="white",
                           fg="black",
                           font=("Times New Roman", 12))
    stage4Position.grid(row=1, column=0)
    return


def updatePositions():
    #import all of the labels for the positions.
    global ser
    global stage1Pos, stage2Pos, stage3Pos, stage4Pos
    dataManagement.setCurrentPositionLabel(ser, stage1Pos, stage2Pos,
                                           stage3Pos, stage4Pos)
    return


menubar = Menu(root)
fileMenu = Menu(menubar, tearoff=0)
fileMenu.add_command(label="Quit", command=quit)
menubar.add_cascade(label="File", menu=fileMenu)
root.config(menu=menubar)
setupFrames()
setupSerialSection()
setupHomeAndZeroSection()
setupMoveSection()
setupMovementLabels()
updateOptionMenu()

root.mainloop()
				if (data[0:4]=='exit'):
					del peersData[peer_id]
					root.event_generate('<<new>>', when='tail')

			if (data[0:6]=='mclear' and peer_id==my_ip):
				print "clear?"
				clear_request_received_time = time.time()
					
			
				

#layout initialization, start receiving thread
if __name__ == "__main__":	
	root = Tk()
	root.title('Shared whiteboard')
	root.config(bg='#ddd')
	root.columnconfigure(2, weight=1)
	root.rowconfigure(1, weight=1)
	root.protocol("WM_DELETE_WINDOW", callback)
	root.minsize(width=600, height=340)
		
	root.bind('<<openIt!>>', myDialog)	
	root.bind('<<sorry>>', sorryDialog)
	root.bind('<<new>>', refreshMessage)
	
	canvas = Canvas(root, width=canvasWidth, height=canvasHeight, bg='#fff')
	canvas.grid(column=0, row=1, sticky=(N, W, E, S), columnspan=7)
	
	clearButton = Button(root, text="Clear everyone's canvas",
		width = 20, command=clearCanvas)
	clearButton.grid(column=0, row=0, padx=5, pady=5)
def Main1():

    # Creacion de la ventana

    ventana = Tk()

    ventana.title("Ventana Principal")
    ventana.config(bg = "black")

    d = BooleanVar(ventana)
    e = BooleanVar(ventana)
    e.set(False)
    f = BooleanVar(ventana)
    f.set(False)

    global arreglo1

    arreglo1 = []


    # Uso de frames para organizar la ventana.
    frame1 = Frame(ventana,bg = "black")
    frame1.pack(side=TOP)
    frame2 = Frame(ventana,bg = "black")
    frame2.pack(side=TOP)
    frame3 = Frame(ventana,bg = "black")
    frame3.pack(side=TOP)
    frame4 = Frame(ventana,bg = "black")
    frame4.pack(side=TOP)
    frame5 = Frame(ventana,bg = "black")
    frame5.pack(side=TOP)
    frame6 = Frame(ventana,bg = "black")
    frame6.pack(side=TOP)
    frame7 = Frame(ventana,bg = "black")
    frame7.pack(side=TOP)


    def Delay():
        if e1.get() == '':
            print 'error'
            tkMessageBox._show('Error', 'No ingreso frecuencia a generar.')

        if e2.get() == '':
            print 'error'
            tkMessageBox._show('Error', 'No ingreso duracion del audio.')

        if e3.get() == '':
            print 'error'
            tkMessageBox._show('Error', 'No ingreso el numero de cuadros.')

        if e4.get() == '':
            print 'error'
            tkMessageBox._show('Error', 'No ingreso nombre del audio.')

        else:
            d.set(True)
            Frecuencia = int( e1.get())
            Time = int( e2.get())
            Frames = int( e3.get())
            Nombre = e4.get()
            Niveles = Nivel.get()

            Delay1 = GenerarRetraso(Time,Frecuencia,Frames)
            Delay1.generar()
            Delay1.NivelModificado(Niveles)
            Delay1.GenerarAudio1(Nombre)
            Delay1.graficar()

# funcion para cerrar la ventana actual y abrir el main
    def Ventana2():
        ventana.destroy()
        Main2()

# funcion que reproduce el audio final
    def ReproducirMain():
        nombre = e4.get()
        reproduce(nombre)

# Label para la interfraz grafica - definicion de los botones

    cuadro= Label(frame1, padx=15, pady=1, text="DELAY 1 ",fg = "red",bg = "black")
    cuadro.pack(side=TOP)
    cuadro1= Label(frame1, padx=15, pady=1, text="Luis Sandoval , Andres Palacio, Libardo Montealegre",fg = "red",bg = "black")
    cuadro1.pack(side=TOP)

    cuadro2= Label(frame2, padx=15, pady=10, text="Digite la frecuencia a generar:",fg = "white",bg = "black")
    cuadro2.pack(side=LEFT)
    e1 = Entry(frame2, bd=5, insertwidth=1)
    e1.pack(side=LEFT, padx=15, pady=10)

    cuadro3= Label(frame3, padx=15, pady=10, text="Digite la duracion del Audio:",fg = "white",bg = "black")
    cuadro3.pack(side=LEFT)
    e2 = Entry(frame3, bd=5, insertwidth=1)
    e2.pack(side=LEFT, padx=15, pady=10)

    cuadro4= Label(frame4, padx=15, pady=10, text="Cantidad de cuadros a retrasar",fg = "white",bg = "black")
    cuadro4.pack(side=LEFT)
    e3 = Entry(frame4, bd=5, insertwidth=1)
    e3.pack(side=LEFT, padx=15, pady=10)

    cuadro5= Label(frame5, padx=15, pady=10, text="Nombre del Archivo a generar",fg = "white",bg = "black")
    cuadro5.pack(side=LEFT)
    e4 = Entry(frame5, bd=5, insertwidth=1)
    e4.pack(side=LEFT, padx=15, pady=10)

    cuadro2= Label(frame6, padx=15, pady=10, text="VOLUMEN",fg = "blue",bg = "black")
    cuadro2.pack(side=TOP)

    Nivel = Scale(frame6, from_= -20.0, to=0.0,length = 200, orient= HORIZONTAL, resolution=0.1,bg = "black", fg="white")
    Nivel.pack(side=TOP, padx=1, pady=1)

    cuadro6= Label(frame6, padx=15, pady=2, text="",fg = "white",bg = "black")
    cuadro6.pack(side=TOP)

    GenerarButton1 = Button(frame7, padx=30, pady=2, text="Generar Archivo",bg = "red",fg="white",command=Delay)
    GenerarButton1.pack(side=LEFT)

    ReproducirButton1 = Button(frame7, padx=30, pady=2, text="Reproducir",bg = "green",fg="black",command=ReproducirMain )
    ReproducirButton1.pack(side=LEFT)

    NextButton1 = Button(frame7, padx=30, pady=2, text=" Delay 2",bg = "blue",fg="white", command= Ventana2)
    NextButton1.pack(side=LEFT)


    ventana.mainloop()
Example #48
0
    red = "cyan"
    white = "black"
    black = "white"
else:
    grey = "light slate grey"
    green = "green"
    yellow = "yellow"
    red = "red"
    white = "white"
    black = "black"

c_height = 476  #the border lines are approx 2px
c_width = 316  #316

root = Tk()
root.config(width=(c_width - 45), height=c_height, bg=black)
if not testMode:
    root.config(cursor="none")
    root.attributes("-fullscreen",
                    True)  #if not in test mode switch to fullscreen

textFont = tkFont.Font(family="Helvetica", size=36, weight="bold")

# Declare Variables
measuredItems = [
    "RPM", "Water TMP", "Oil Temp", "Oil Press", "EGT", "Fuel Flow",
    "Fuel(left)", "Voltage"
]
errorBoxItems = ["TEMP", "PRESS", "FUEL", "POWER", "ERROR"]
errorBoxItemsColor = ["red", "green", "green", "yellow", "green"]
measuredItemsColor = [red, green, yellow, green, green, green, green]
Example #49
0
class TreeView(object):
    def __init__(self, *trees):
        from math import sqrt, ceil

        self._trees = trees

        self._top = Tk()
        self._top.title('NLTK')
        self._top.bind('<Control-x>', self.destroy)
        self._top.bind('<Control-q>', self.destroy)

        cf = self._cframe = CanvasFrame(self._top)
        self._top.bind('<Control-p>', self._cframe.print_to_file)

        # Size is variable.
        self._size = IntVar(self._top)
        self._size.set(12)
        bold = ('helvetica', -self._size.get(), 'bold')
        helv = ('helvetica', -self._size.get())

        # Lay the trees out in a square.
        self._width = int(ceil(sqrt(len(trees))))
        self._widgets = []
        for i in range(len(trees)):
            widget = TreeWidget(cf.canvas(), trees[i], node_font=bold,
                                leaf_color='#008040', node_color='#004080',
                                roof_color='#004040', roof_fill='white',
                                line_color='#004040', draggable=1,
                                leaf_font=helv)
            widget.bind_click_trees(widget.toggle_collapsed)
            self._widgets.append(widget)
            cf.add_widget(widget, 0, 0)

        self._layout()
        self._cframe.pack(expand=1, fill='both')
        self._init_menubar()

    def _layout(self):
        i = x = y = ymax = 0
        width = self._width
        for i in range(len(self._widgets)):
            widget = self._widgets[i]
            (oldx, oldy) = widget.bbox()[:2]
            if i % width == 0:
                y = ymax
                x = 0
            widget.move(x-oldx, y-oldy)
            x = widget.bbox()[2] + 10
            ymax = max(ymax, widget.bbox()[3] + 10)

    def _init_menubar(self):
        menubar = Menu(self._top)

        filemenu = Menu(menubar, tearoff=0)
        filemenu.add_command(label='Print to Postscript', underline=0,
                             command=self._cframe.print_to_file,
                             accelerator='Ctrl-p')
        filemenu.add_command(label='Exit', underline=1,
                             command=self.destroy, accelerator='Ctrl-x')
        menubar.add_cascade(label='File', underline=0, menu=filemenu)

        zoommenu = Menu(menubar, tearoff=0)
        zoommenu.add_radiobutton(label='Tiny', variable=self._size,
                                 underline=0, value=10, command=self.resize)
        zoommenu.add_radiobutton(label='Small', variable=self._size,
                                 underline=0, value=12, command=self.resize)
        zoommenu.add_radiobutton(label='Medium', variable=self._size,
                                 underline=0, value=14, command=self.resize)
        zoommenu.add_radiobutton(label='Large', variable=self._size,
                                 underline=0, value=28, command=self.resize)
        zoommenu.add_radiobutton(label='Huge', variable=self._size,
                                 underline=0, value=50, command=self.resize)
        menubar.add_cascade(label='Zoom', underline=0, menu=zoommenu)

        self._top.config(menu=menubar)

    def resize(self, *e):
        bold = ('helvetica', -self._size.get(), 'bold')
        helv = ('helvetica', -self._size.get())
        xspace = self._size.get()
        yspace = self._size.get()
        for widget in self._widgets:
            widget['node_font'] = bold
            widget['leaf_font'] = helv
            widget['xspace'] = xspace
            widget['yspace'] = yspace
            if self._size.get() < 20: widget['line_width'] = 1
            elif self._size.get() < 30: widget['line_width'] = 2
            else: widget['line_width'] = 3
        self._layout()

    def destroy(self, *e):
        if self._top is None: return
        self._top.destroy()
        self._top = None

    def mainloop(self, *args, **kwargs):
        """
        Enter the Tkinter mainloop.  This function must be called if
        this demo is created from a non-interactive program (e.g.
        from a secript); otherwise, the demo will close as soon as
        the script completes.
        """
        if in_idle(): return
        self._top.mainloop(*args, **kwargs)
Example #50
0
class TkView(object):
    ''' TkView represents a window container for components '''

    def __init__(self):
        ''' Constructor: Excepts no arguments '''
        self.die = Die(6)
        self.root = Tk()
        self.root.wm_title(APP_NAME)
        self.root.resizable(False, False)
        self.set_up_menu()
        self.set_up_labels()
        self.set_up_entries_and_buttons()

    def set_up_menu(self):
        ''' Sets up the menu bar and its submenus '''
        menubar = Menu(self.root)
        filemenu = Menu(menubar, tearoff=0)
        filemenu.add_command(label="About", command=self.about)
        filemenu.add_separator()
        filemenu.add_command(label="Exit", command=self.root.quit)
        menubar.add_cascade(label="File", menu=filemenu)
        self.root.config(menu=menubar)

    def set_up_labels(self):
        ''' Sets up the text labels for components '''
        Label(self.root, text="Sides   ").grid()
        Label(self.root, text="Mod     ").grid(row=1)
        Label(self.root, text="Result :").grid(row=2)
        self.result = Label(self.root, text="~")
        self.result.grid(row=2, column=1, sticky=W)

    def set_up_entries_and_buttons(self):
        ''' Sets up entries and buttons the user interacts with '''
        self.sides = Entry(self.root)
        self.sides.grid(row=0, column=1, sticky=W)
        self.sides.insert(0, "6")

        self.mod = Entry(self.root)
        self.mod.grid(row=1, column=1, sticky=W)
        self.mod.insert(0, "0")

        Button(self.root, text="Roll ", command=self.roll).grid(row=0,
                                                                column=2,
                                                                rowspan=3,
                                                                sticky=(N, S))

    def run(self):
        ''' Begins the main GUI loop '''
        self.root.mainloop()

    def about(self):
        ''' Displays a pop up about the author and contact information '''
        new_pop_up(APP_NAME, "PyRoller: a simple die roller\n\n" +
                   "Wrote by Corey Prophitt <*****@*****.**>")

    def roll(self):
        ''' Rolls the die and sets the result '''
        # Avoid user entering blank values
        if self.sides.get() != '':
            # Only re-instantiate die if the side has changed
            if self.die.face != int(self.sides.get()):
                self.die = Die(int(self.sides.get()))

            text_ = str(self.die.roll()) + " + "
            # Only use mod entry if sides is defined and mod isn't blank
            if self.mod.get() != '':
                text_ += str(int(self.mod.get()))
                text_ += " = " + str(self.die.face+int(self.mod.get()))

            else:
                text_ += str(0) + " = " + str(self.die.face)
        else:
            text_ = 0

        self.result.config(text=text_)
Example #51
0
class GUI:

  def __init__(self, depth):
    self.depth = depth
    self._init_app()
    self._init_ai()
    self.update()

  def _init_app(self):
    self.app = Tk()
    self.app.title('Connect4')
    self.app.resizable(width=False, height=False)
    self.board = Board()
    self.buttons = {}
    self.frame = Frame(self.app, borderwidth=1, relief="raised")
    self.tiles = {}
    for x in range(self.board.width):
      handler = lambda x=x: self.move(x)
      button = Button(self.app, command=handler, font=Font(family="Helvetica", size=14), text=x+1)
      button.grid(row=0, column=x, sticky="WE")
      self.buttons[x] = button
    self.frame.grid(row=1, column=0, columnspan=self.board.width)
    for x,y in self.board.fields:
      tile = Canvas(self.frame, width=60, height=50, bg="navy", highlightthickness=0)
      tile.grid(row=self.board.height-1-y, column=x)
      self.tiles[x,y] = tile
    handler = lambda: self.reset()
    self.restart = Button(self.app, command=handler, text='reset')
    self.restart.grid(row=2, column=0, columnspan=self.board.width, sticky="WE")

  def _init_ai(self):
    ai_path = os.path.join(os.path.dirname(__file__), 'conn4.pl')
    # for widnows: self.ai = subprocess.Popen([r"C:\Program Files\swipl\bin\swipl.exe", ai_path], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
    print(ai_path)
    self.ai = subprocess.Popen(["swipl", ai_path, str(self.depth)], stdin=subprocess.PIPE, stdout=subprocess.PIPE)

  def reset(self):
    self.ai.terminate()
    self._init_ai()
    self.board = Board()
    self.update()

  def move(self,x):
    self.app.config(cursor="watch")
    self.app.update()
    try:
      # me
      self.ai.stdin.write(str(x + 1) + '\n')
      print self.ai.stdout.readline().strip()
      self.board = self.board.move(x)
      if self.update():
        return
      # him
      self.ai.stdin.write('0\n')
      y = self.ai.stdout.readline().strip()
      self.board = self.board.move(int(y[3]) - 1)
      self.update()
      print y
    finally:
      self.app.config(cursor="")

  def update(self):
    for (x,y) in self.board.fields:
      text = self.board.fields[x,y]
      if (text=='.'):
        self.tiles[x,y].create_oval(10, 5, 50, 45, fill="black", outline="blue", width=1)
      if (text=='X'):
        self.tiles[x,y].create_oval(10, 5, 50, 45, fill="yellow", outline="blue", width=1)
      if (text=='O'):
        self.tiles[x,y].create_oval(10, 5, 50, 45, fill="red", outline="blue", width=1)
    for x in range(self.board.width):
      if self.board.fields[x,self.board.height-1]==self.board.empty:
        self.buttons[x]['state'] = 'normal'
      else:
        self.buttons[x]['state'] = 'disabled'
    winning = self.board.won()
    if winning:
      self.ai.terminate()
      for x,y in winning:
        self.tiles[x,y].create_oval(25, 20, 35, 30, fill="black")
      for x in range(self.board.width):
        self.buttons[x]['state'] = 'disabled'
    return winning

  def mainloop(self):
    self.app.mainloop()
def main():
    Frecuenciadesampleo = 44100
    MaxBits = 16

    # Creacion de la ventana

    ventana = Tk()

    ventana.title("Ventana Principal")
    ventana.config(bg = "black")

    d = BooleanVar(ventana)
    e = BooleanVar(ventana)
    e.set(False)
    f = BooleanVar(ventana)
    f.set(False)

    global arreglo1

    arreglo1 = []


    # Uso de frames para organizar la ventana.
    frame1 = Frame(ventana,bg = "black")
    frame1.pack(side=TOP)
    frame2 = Frame(ventana,bg = "black")
    frame2.pack(side=TOP)
    frame3 = Frame(ventana,bg = "black")
    frame3.pack(side=TOP)
    frame4 = Frame(ventana,bg = "black")
    frame4.pack(side=TOP)
    frame5 = Frame(ventana,bg = "black")
    frame5.pack(side=TOP)

    def AbrirArchivo1():
        d.set(True)
        Abrir1()
        mensaje1.pack(side=LEFT)
        ReproButton1.pack(side=LEFT)


    def AbrirArchivo2():
        d.set(True)
        Abrir2()
        mensaje2.pack(side=LEFT)
        ReproButton2.pack(side=LEFT)

    def AbrirArchivo3():
        d.set(True)
        Abrir3()
        mensaje3.pack(side=LEFT)
        ReproButton3.pack(side=LEFT)

    def AbrirArchivo4():
        d.set(True)
        Abrir4()
        mensaje4.pack(side=LEFT)
        ReproButton4.pack(side=LEFT)

    def Reproducir1():
        d.set(True)
        reproduce1()

    def Reproducir2():
        d.set(True)
        reproduce2()

    def Reproducir3():
        d.set(True)
        reproduce3()

    def Reproducir4():
        d.set(True)
        reproduce4()

    def ReproducirMain():
        d.set(True)
        reproduce()



    # Creacion de botones.

    Titulo = Label(frame1, fg='red', padx=15, pady=10, text='Mixer Reproductor',bg = "black")
    Titulo.pack(side=TOP)
    Titulo1 = Label(frame1, fg='red', padx=15, pady=10, text='Luis Sandoval, Andres Palacio, Libardo Montealegre',bg = "black")
    Titulo1.pack(side=TOP)


    OpenButton1 = Button(frame1, padx=30, pady=2, text="Abrir Archivo 1", command=AbrirArchivo1,bg = "blue",fg="white")
    OpenButton1.pack(side=LEFT)
    OpenButton2 = Button(frame2, padx=30, pady=2, text="Abrir Archivo 2", command=AbrirArchivo2,bg = "blue",fg="white")
    OpenButton2.pack(side=LEFT)
    OpenButton3 = Button(frame3, padx=30, pady=2, text="Abrir Archivo 3", command=AbrirArchivo3,bg = "blue",fg="white")
    OpenButton3.pack(side=LEFT)
    OpenButton4 = Button(frame4, padx=30, pady=2, text="Abrir Archivo 4", command=AbrirArchivo4,bg = "blue",fg="white")
    OpenButton4.pack(side=LEFT)

    # Mensajes de grabacion activada.
    mensaje1 = Label(frame1, fg='green', padx=15, pady=10, text='Archivo 1 Cargado',bg = "black")
    mensaje2 = Label(frame2, fg='green', padx=15, pady=10, text='Archivo 2 Cargado',bg = "black")
    mensaje3 = Label(frame3, fg='green', padx=15, pady=10, text='Archivo 3 Cargado',bg = "black")
    mensaje4 = Label(frame4, fg='green', padx=15, pady=10, text='Archivo 4 Cargado',bg = "black")

    ReproButton1 = Button(frame1, padx=30, pady=2, text="Reproducir Archivo 1", command=Reproducir1,bg = "green",fg="black")
    ReproButton2 = Button(frame2, padx=30, pady=2, text="Reproducir Archivo 2", command=Reproducir2,bg = "green",fg="black")
    ReproButton3 = Button(frame3, padx=30, pady=2, text="Reproducir Archivo 3", command=Reproducir3,bg = "green",fg="black")
    ReproButton4 = Button(frame4, padx=30, pady=2, text="Reproducir Archivo 3", command=Reproducir4,bg = "green",fg="black")


     # Creacion e insercion del cuadro de texto 1.
    ReproMainButton1 = Button(frame5, padx=30, pady=2, text="Reproducir Mezcla",bg = "green",fg="black", command=ReproducirMain)
    ReproMainButton1.pack(side=TOP)

    ventana.mainloop()
Example #53
0
class OSCRemote(object):
    def __init__(self):

        self.editor_issue = "1.3"

        # get command options
        self.command_options = remote_options()

        # get directory holding the code
        self.pp_dir = sys.path[0]

        if not os.path.exists(self.pp_dir + os.sep + "pp_oscremote.py"):
            tkMessageBox.showwarning("Pi Presents",
                                     "Bad Application Directory")
            exit()

        # Initialise logging
        Monitor.log_path = self.pp_dir
        self.mon = Monitor()
        self.mon.init()

        Monitor.classes = ['OSCRemote', 'OSCConfig', 'OSCEditor']

        Monitor.log_level = int(self.command_options['debug'])

        self.mon.log(self, "Pi Presents Remote is starting")
        self.mon.log(self, " OS and separator " + os.name + '  ' + os.sep)
        self.mon.log(self,
                     "sys.path[0] -  location of code: code " + sys.path[0])

        self.setup_gui()

        # OSC config class
        self.osc_config = OSCConfig()

        self.init()

        #and start the system
        self.root.after(1000, self.run_app)
        self.root.mainloop()

    def init(self):
        self.osc_config_file = self.pp_dir + os.sep + 'pp_config' + os.sep + 'pp_oscremote.cfg'
        self.read_create_osc()
        self.pp_home_dir = self.osc_config.pp_home_dir
        self.pp_profiles_offset = self.osc_config.pp_profiles_offset
        self.mon.log(self, "Data Home from options is " + self.pp_home_dir)
        self.mon.log(
            self, "Current Profiles Offset from options is " +
            self.pp_profiles_offset)
        self.pp_profile_dir = ''

        self.current_showlist = None
        self.current_show = None
        self.current_show_ref = ''
        self.shows_display.delete(0, END)
        self.results.set('')

    def add_status(self, text):
        self.status_display.insert(END, text + '\n')
        self.status_display.see(END)

    def run_app(self):
        self.client = None
        self.server = None
        self.st = None

        # initialise OSC variables
        self.prefix = '/pipresents'
        self.this_unit = '/' + self.osc_config.this_unit_name
        self.add_status('this unit is: ' + self.this_unit)
        self.controlled_unit = '/' + self.osc_config.controlled_unit_1_name
        self.add_status('controlled unit is: ' + self.controlled_unit)

        #connect client then start server to listen for replies
        self.init_client()
        self.add_status('connecting to controlled unit: ' +
                        self.osc_config.controlled_unit_1_ip + ':' +
                        self.osc_config.controlled_unit_1_port + ' ' +
                        self.osc_config.controlled_unit_1_name)
        self.connect_client(self.osc_config.controlled_unit_1_ip,
                            self.osc_config.controlled_unit_1_port)
        self.add_status('listening for replies on:' +
                        self.osc_config.this_unit_ip + ':' +
                        self.osc_config.this_unit_port)
        self.init_server(self.osc_config.this_unit_ip,
                         self.osc_config.this_unit_port, self.client)
        self.add_initial_handlers()
        self.start_server()

# ***************************************
#  RESPOND TO BUTTONS
# ***************************************

    def open_show(self):
        self.msg_path = '/core/open '
        self.msg_arg_text = self.current_show_ref
        self.display_msg_text()

    def close_show(self):
        self.msg_path = '/core/close '
        self.msg_arg_text = self.current_show_ref
        self.display_msg_text()

    def exit_pipresents(self):
        self.msg_path = '/core/exitpipresents'
        self.msg_arg_text = ''
        self.display_msg_text()

    def play_event(self):
        self.msg_path = '/core/event'
        self.msg_arg_text = 'pp-play'
        self.display_msg_text()

    def pause_event(self):
        self.msg_path = '/core/event'
        self.msg_arg_text = 'pp-pause'
        self.display_msg_text()
        pass

    def stop_event(self):
        self.msg_path = '/core/event'
        self.msg_arg_text = 'pp-stop'
        self.display_msg_text()
        pass

    def up_event(self):
        self.msg_path = '/core/event'
        self.msg_arg_text = 'pp-up'
        self.display_msg_text()

    def down_event(self):
        self.msg_path = '/core/event'
        self.msg_arg_text = 'pp-down'
        self.display_msg_text()

    def output(self):
        self.msg_path = '/core/output'
        self.msg_arg_text = ''
        self.display_msg_text()

    def loopback(self):
        self.msg_path = '/system/loopback'
        self.msg_arg_text = ''
        self.display_msg_text()

    def server_info(self):
        self.msg_path = '/system/server-info'
        self.msg_arg_text = ''
        self.display_msg_text()

    # and put the created text in the results box in the gui
    def display_msg_text(self):
        self.results.set(self.prefix + self.controlled_unit + self.msg_path +
                         ' ' + self.msg_arg_text)

    #calback from the Send button
    # parses the message string into fields and sends - NO error checking
    def send_message(self):
        msg_text = self.results.get()
        self.add_status('Send message:' + msg_text)
        self.mon.log(self, 'send message: ' + msg_text)
        fields = msg_text.split()
        address = fields[0]
        arg_list = fields[1:]
        self.send(address, arg_list)

    # ***************************************
    # OSC CLIENT TO SEND MESSAGES
    # ***************************************

    def init_client(self):
        self.client = OSC.OSCClient()

    def connect_client(self, ip, port):
        self.mon.log(self, 'connect to: ' + ip + ':' + str(port))
        self.client.connect((ip, int(port)))

    def send(self, address, arg_list):
        msg = OSC.OSCMessage()
        msg.setAddress(address)
        for arg in arg_list:
            msg.append(arg)
        self.client.send(msg)

    def disconnect_client(self):
        self.client.close()
        return

    # ***************************************
    # OSC SERVER TO LISTEN TO REPLIES
    # ***************************************

    def init_server(self, ip, port_text, client):
        self.mon.log(self, 'Start Server: ' + ip + ':' + port_text)
        self.server = OSC.OSCServer((ip, int(port_text)), client)

    def start_server(self):
        self.st = threading.Thread(target=self.server.serve_forever)
        self.st.start()

    def close_server(self):
        if self.server != None:
            self.server.close()
        self.mon.log(self, 'Waiting for Server-thread to finish')
        if self.st != None:
            self.st.join()  ##!!!
        self.mon.log(self, 'server thread closed')

    def add_initial_handlers(self):
        self.server.addMsgHandler('default', self.no_match_handler)
        self.server.addMsgHandler(
            self.prefix + self.this_unit + "/system/loopback-reply",
            self.loopback_reply_handler)
        self.server.addMsgHandler(
            self.prefix + self.this_unit + "/system/server-info-reply",
            self.server_info_reply_handler)

    def no_match_handler(self, addr, tags, stuff, source):
        text = ''
        text += "no match for new osc msg from %s" % OSC.getUrlStr(
            source) + '\n'
        text += "with addr : %s" % addr + '\n'
        text += "typetags %s" % tags + '\n'
        text += "data %s" % stuff + '\n'
        self.add_status(text + '\n')

    def loopback_reply_handler(self, addr, tags, stuff, source):
        self.add_status('Loopback reply  received from: ' +
                        self.pretty_list(source))

    def server_info_reply_handler(self, addr, tags, stuff, source):
        self.add_status('Server Information from: ' +
                        self.pretty_list(source) + '\n   ' +
                        self.pretty_list(stuff))

    def pretty_list(self, fields):
        text = ' '
        for field in fields:
            text += str(field) + ' '
        return text

    # ***************************************
    # INIT EXIT MISC
    # ***************************************

    def e_edit_osc(self):
        self.disconnect_client()
        self.close_server()
        self.edit_osc()
        self.init()
        self.add_status('\n\n\nRESTART')
        self.run_app()

    def app_exit(self):
        self.disconnect_client()
        self.close_server()
        if self.root is not None:
            self.root.destroy()
        self.mon.finish()
        sys.exit()

    def show_help(self):
        tkMessageBox.showinfo("Help", "Read 'manual.pdf'")

    def about(self):
        tkMessageBox.showinfo(
            "About", "Simple Remote Control for Pi Presents\n" +
            "Author: Ken Thompson" +
            "\nWebsite: http://pipresents.wordpress.com/")

    def setup_gui(self):
        # set up the gui

        # root is the Tkinter root widget
        self.root = Tk()
        self.root.title("Remote Control for Pi Presents")

        # self.root.configure(background='grey')

        self.root.resizable(False, False)

        # define response to main window closing
        self.root.protocol("WM_DELETE_WINDOW", self.app_exit)

        # bind some display fields
        self.filename = StringVar()
        self.display_show = StringVar()
        self.results = StringVar()
        self.status = StringVar()

        # define menu
        menubar = Menu(self.root)

        profilemenu = Menu(menubar, tearoff=0, bg="grey", fg="black")
        profilemenu.add_command(label='Select',
                                command=self.open_existing_profile)
        menubar.add_cascade(label='Profile', menu=profilemenu)

        toolsmenu = Menu(menubar, tearoff=0, bg="grey", fg="black")
        menubar.add_cascade(label='Tools', menu=toolsmenu)

        osc_configmenu = Menu(menubar, tearoff=0, bg="grey", fg="black")
        menubar.add_cascade(label='OSC', menu=osc_configmenu)
        osc_configmenu.add_command(label='Edit', command=self.e_edit_osc)

        helpmenu = Menu(menubar, tearoff=0, bg="grey", fg="black")
        menubar.add_cascade(label='Help', menu=helpmenu)
        helpmenu.add_command(label='Help', command=self.show_help)
        helpmenu.add_command(label='About', command=self.about)

        self.root.config(menu=menubar)

        #top frame
        top_frame = Frame(self.root, padx=5, pady=5)
        top_frame.pack(side=TOP)

        results_label = Label(top_frame,
                              text="Message to Send",
                              font="arial 12 bold")
        results_label.pack(side=LEFT)
        results_display = Entry(top_frame, textvariable=self.results, width=70)
        results_display.pack(side=LEFT, fill=BOTH, expand=1)
        send_button = Button(top_frame,
                             width=5,
                             height=1,
                             text='Send',
                             fg='black',
                             command=self.send_message,
                             bg="light grey")
        send_button.pack(side=RIGHT)

        #bottom frame
        bottom_frame = Frame(self.root, padx=5, pady=5)
        bottom_frame.pack(side=TOP, fill=BOTH, expand=1)
        left_frame = Frame(bottom_frame, padx=5)
        left_frame.pack(side=LEFT)
        right_frame = Frame(bottom_frame, padx=5, pady=5)
        right_frame.pack(side=LEFT)

        suplabel_frame = Frame(right_frame, pady=5)
        suplabel_frame.pack(side=TOP)
        commands_label = Label(suplabel_frame,
                               text="Show Control",
                               font="arial 12 bold")
        commands_label.pack()

        supervisor_frame = Frame(right_frame, pady=5)
        supervisor_frame.pack(side=TOP)

        # supervisor buttons
        add_button = Button(supervisor_frame,
                            width=5,
                            height=1,
                            text='Open\nShow',
                            fg='black',
                            command=self.open_show,
                            bg="light grey")
        add_button.pack(side=LEFT)
        add_button = Button(supervisor_frame,
                            width=5,
                            height=1,
                            text='Close\nShow',
                            fg='black',
                            command=self.close_show,
                            bg="light grey")
        add_button.pack(side=LEFT)
        add_button = Button(supervisor_frame,
                            width=10,
                            height=1,
                            text='Exit\nPi Presents',
                            fg='black',
                            command=self.exit_pipresents,
                            bg="light grey")
        add_button.pack(side=LEFT)

        # events buttons
        oplabel_frame = Frame(right_frame, pady=5)
        oplabel_frame.pack(side=TOP)
        operations_label = Label(oplabel_frame,
                                 text="Input Events",
                                 font="arial 12 bold")
        operations_label.pack()

        operations_frame = Frame(right_frame, pady=5)
        operations_frame.pack(side=TOP)

        add_button = Button(operations_frame,
                            width=5,
                            height=1,
                            text='Play',
                            fg='black',
                            command=self.play_event,
                            bg="light grey")
        add_button.pack(side=LEFT)
        add_button = Button(operations_frame,
                            width=5,
                            height=1,
                            text='Pause',
                            fg='black',
                            command=self.pause_event,
                            bg="light grey")
        add_button.pack(side=LEFT)
        add_button = Button(operations_frame,
                            width=5,
                            height=1,
                            text='Stop',
                            fg='black',
                            command=self.stop_event,
                            bg="light grey")
        add_button.pack(side=LEFT)
        add_button = Button(operations_frame,
                            width=5,
                            height=1,
                            text='Up',
                            fg='black',
                            command=self.up_event,
                            bg="light grey")
        add_button.pack(side=LEFT)
        add_button = Button(operations_frame,
                            width=5,
                            height=1,
                            text='Down',
                            fg='black',
                            command=self.down_event,
                            bg="light grey")
        add_button.pack(side=LEFT)

        # animate buttons
        animate_frame = Frame(right_frame, pady=5)
        animate_frame.pack(side=TOP)
        animate_label = Label(animate_frame,
                              text="Control Outputs",
                              font="arial 12 bold")
        animate_label.pack()

        animate_frame = Frame(right_frame, pady=5)
        animate_frame.pack(side=TOP)

        add_button = Button(animate_frame,
                            width=5,
                            height=1,
                            text='Output',
                            fg='black',
                            command=self.output,
                            bg="light grey")
        add_button.pack(side=LEFT)

        # system buttons
        systemlabel_frame = Frame(right_frame, pady=5)
        systemlabel_frame.pack(side=TOP)
        system_label = Label(systemlabel_frame,
                             text="System",
                             font="arial 12 bold")
        system_label.pack()

        system_frame = Frame(right_frame, pady=5)
        system_frame.pack(side=TOP)

        add_button = Button(system_frame,
                            width=5,
                            height=1,
                            text='Loopback',
                            fg='black',
                            command=self.loopback,
                            bg="light grey")
        add_button.pack(side=LEFT)
        add_button = Button(system_frame,
                            width=10,
                            height=1,
                            text='Server Info',
                            fg='black',
                            command=self.server_info,
                            bg="light grey")
        add_button.pack(side=LEFT)

        # define display of showlist
        shows_title_frame = Frame(left_frame)
        shows_title_frame.pack(side=TOP)
        shows_label = Label(shows_title_frame, text="Shows")
        shows_label.pack()
        shows_frame = Frame(left_frame)
        shows_frame.pack(side=TOP)
        scrollbar = Scrollbar(shows_frame, orient=VERTICAL)
        self.shows_display = Listbox(shows_frame,
                                     selectmode=SINGLE,
                                     height=12,
                                     width=40,
                                     bg="white",
                                     activestyle=NONE,
                                     fg="black",
                                     yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.shows_display.yview)
        scrollbar.pack(side=RIGHT, fill=Y)
        self.shows_display.pack(side=LEFT, fill=BOTH, expand=1)
        self.shows_display.bind("<ButtonRelease-1>", self.e_select_show)

        # status_frame
        status_frame = Frame(self.root, padx=5, pady=5)
        status_frame.pack(side=TOP, fill=BOTH, expand=1)
        status_label = Label(status_frame, text="Status", font="arial 12 bold")
        status_label.pack(side=LEFT)
        scrollbar = Scrollbar(status_frame, orient=VERTICAL)
        self.status_display = Text(status_frame,
                                   height=10,
                                   yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.status_display.yview)
        scrollbar.pack(side=RIGHT, fill=Y)
        self.status_display.pack(side=LEFT, fill=BOTH, expand=1)

    # ***************************************
    # SHOWLIST
    # ***************************************

    def open_existing_profile(self):
        initial_dir = self.pp_home_dir + os.sep + "pp_profiles" + self.pp_profiles_offset
        if os.path.exists(initial_dir) is False:
            self.mon.err(
                self, "Profiles directory not found: " + initial_dir +
                "\n\nHint: Data Home option must end in pp_home")
            return
        dir_path = tkFileDialog.askdirectory(initialdir=initial_dir)
        # dir_path="C:\Users\Ken\pp_home\pp_profiles\\ttt"
        if len(dir_path) > 0:
            self.open_profile(dir_path)

    def open_profile(self, dir_path):
        showlist_file = dir_path + os.sep + "pp_showlist.json"
        if os.path.exists(showlist_file) is False:
            self.mon.err(
                self, "Not a Profile: " + dir_path +
                "\n\nHint: Have you opened the profile directory?")
            return
        self.pp_profile_dir = dir_path
        self.root.title("Remote for Pi Presents - " + self.pp_profile_dir)
        self.open_showlist(self.pp_profile_dir)

    def open_showlist(self, profile_dir):
        showlist_file = profile_dir + os.sep + "pp_showlist.json"
        if os.path.exists(showlist_file) is False:
            self.mon.err(
                self, "showlist file not found at " + profile_dir +
                "\n\nHint: Have you opened the profile directory?")
            self.app_exit()
        self.current_showlist = ShowList()
        self.current_showlist.open_json(showlist_file)
        if float(self.current_showlist.sissue()) != float(self.editor_issue):
            self.mon.err(
                self, "Version of profile does not match Remote: " +
                self.editor_issue)
            self.app_exit()
        self.refresh_shows_display()

    def refresh_shows_display(self):
        self.shows_display.delete(0, self.shows_display.size())
        for index in range(self.current_showlist.length()):
            self.shows_display.insert(
                END,
                self.current_showlist.show(index)['title'] + "   [" +
                self.current_showlist.show(index)['show-ref'] + "]")
        if self.current_showlist.show_is_selected():
            self.shows_display.itemconfig(
                self.current_showlist.selected_show_index(), fg='red')
            self.shows_display.see(self.current_showlist.selected_show_index())

    def e_select_show(self, event):
        print 'select show', self.current_showlist.length()
        if self.current_showlist is not None and self.current_showlist.length(
        ) > 0:
            mouse_item_index = int(event.widget.curselection()[0])
            self.current_showlist.select(mouse_item_index)
            self.current_show_ref = self.current_showlist.selected_show(
            )['show-ref']
            self.refresh_shows_display()
        else:
            self.current_show_ref = ''


# ***************************************
#  OSC CONFIGURATION
# ***************************************

    def read_create_osc(self):
        if self.osc_config.read(self.osc_config_file) is False:
            self.osc_config.create(self.osc_config_file)
            eosc = OSCEditor(self.root, self.osc_config_file, 'remote',
                             'Create OSC Remote Configuration')
            self.osc_config.read(self.osc_config_file)

    def edit_osc(self):
        if self.osc_config.read(self.osc_config_file) is False:
            self.osc_config.create(self.osc_config_file)
        eosc = OSCEditor(self.root, self.osc_config_file, 'remote',
                         'Edit OSC Reomote Configuration')
Example #54
0
File: tree.py Project: sp00/nltk
class TreeView(object):
    def __init__(self, *trees):
        from math import sqrt, ceil

        self._trees = trees

        self._top = Tk()
        self._top.title('NLTK')
        self._top.bind('<Control-x>', self.destroy)
        self._top.bind('<Control-q>', self.destroy)

        cf = self._cframe = CanvasFrame(self._top)
        self._top.bind('<Control-p>', self._cframe.print_to_file)

        # Size is variable.
        self._size = IntVar(self._top)
        self._size.set(12)
        bold = ('helvetica', -self._size.get(), 'bold')
        helv = ('helvetica', -self._size.get())

        # Lay the trees out in a square.
        self._width = int(ceil(sqrt(len(trees))))
        self._widgets = []
        for i in range(len(trees)):
            widget = TreeWidget(cf.canvas(), trees[i], node_font=bold,
                                leaf_color='#008040', node_color='#004080',
                                roof_color='#004040', roof_fill='white',
                                line_color='#004040', draggable=1,
                                leaf_font=helv)
            widget.bind_click_trees(widget.toggle_collapsed)
            self._widgets.append(widget)
            cf.add_widget(widget, 0, 0)

        self._layout()
        self._cframe.pack(expand=1, fill='both')
        self._init_menubar()

    def _layout(self):
        i = x = y = ymax = 0
        width = self._width
        for i in range(len(self._widgets)):
            widget = self._widgets[i]
            (oldx, oldy) = widget.bbox()[:2]
            if i % width == 0:
                y = ymax
                x = 0
            widget.move(x-oldx, y-oldy)
            x = widget.bbox()[2] + 10
            ymax = max(ymax, widget.bbox()[3] + 10)

    def _init_menubar(self):
        menubar = Menu(self._top)

        filemenu = Menu(menubar, tearoff=0)
        filemenu.add_command(label='Print to Postscript', underline=0,
                             command=self._cframe.print_to_file,
                             accelerator='Ctrl-p')
        filemenu.add_command(label='Exit', underline=1,
                             command=self.destroy, accelerator='Ctrl-x')
        menubar.add_cascade(label='File', underline=0, menu=filemenu)

        zoommenu = Menu(menubar, tearoff=0)
        zoommenu.add_radiobutton(label='Tiny', variable=self._size,
                                 underline=0, value=10, command=self.resize)
        zoommenu.add_radiobutton(label='Small', variable=self._size,
                                 underline=0, value=12, command=self.resize)
        zoommenu.add_radiobutton(label='Medium', variable=self._size,
                                 underline=0, value=14, command=self.resize)
        zoommenu.add_radiobutton(label='Large', variable=self._size,
                                 underline=0, value=28, command=self.resize)
        zoommenu.add_radiobutton(label='Huge', variable=self._size,
                                 underline=0, value=50, command=self.resize)
        menubar.add_cascade(label='Zoom', underline=0, menu=zoommenu)

        self._top.config(menu=menubar)

    def resize(self, *e):
        bold = ('helvetica', -self._size.get(), 'bold')
        helv = ('helvetica', -self._size.get())
        xspace = self._size.get()
        yspace = self._size.get()
        for widget in self._widgets:
            widget['node_font'] = bold
            widget['leaf_font'] = helv
            widget['xspace'] = xspace
            widget['yspace'] = yspace
            if self._size.get() < 20: widget['line_width'] = 1
            elif self._size.get() < 30: widget['line_width'] = 2
            else: widget['line_width'] = 3
        self._layout()

    def destroy(self, *e):
        if self._top is None: return
        self._top.destroy()
        self._top = None

    def mainloop(self, *args, **kwargs):
        """
        Enter the Tkinter mainloop.  This function must be called if
        this demo is created from a non-interactive program (e.g.
        from a secript); otherwise, the demo will close as soon as
        the script completes.
        """
        if in_idle(): return
        self._top.mainloop(*args, **kwargs)
Example #55
-1
class PiPresents(object):

    def pipresents_version(self):
        vitems=self.pipresents_issue.split('.')
        if len(vitems)==2:
            # cope with 2 digit version numbers before 1.3.2
            return 1000*int(vitems[0])+100*int(vitems[1])
        else:
            return 1000*int(vitems[0])+100*int(vitems[1])+int(vitems[2])


    def __init__(self):
        # gc.set_debug(gc.DEBUG_UNCOLLECTABLE|gc.DEBUG_INSTANCES|gc.DEBUG_OBJECTS|gc.DEBUG_SAVEALL)
        gc.set_debug(gc.DEBUG_UNCOLLECTABLE|gc.DEBUG_SAVEALL)
        self.pipresents_issue="1.3.5"
        self.pipresents_minorissue = '1.3.5d'
        # position and size of window without -f command line option
        self.nonfull_window_width = 0.45 # proportion of width
        self.nonfull_window_height= 0.7 # proportion of height
        self.nonfull_window_x = 0 # position of top left corner
        self.nonfull_window_y=0   # position of top left corner


        StopWatch.global_enable=False

        # set up the handler for SIGTERM
        signal.signal(signal.SIGTERM,self.handle_sigterm)
        

# ****************************************
# Initialisation
# ***************************************
        # get command line options
        self.options=command_options()

        # get Pi Presents code directory
        pp_dir=sys.path[0]
        self.pp_dir=pp_dir
        
        if not os.path.exists(pp_dir+"/pipresents.py"):
            if self.options['manager']  is False:
                tkMessageBox.showwarning("Pi Presents","Bad Application Directory")
            exit(102)

        
        # Initialise logging and tracing
        Monitor.log_path=pp_dir
        self.mon=Monitor()
        # Init in PiPresents only
        self.mon.init()

        # uncomment to enable control of logging from within a class
        # Monitor.enable_in_code = True # enables control of log level in the code for a class  - self.mon.set_log_level()

        
        # make a shorter list to log/trace only some classes without using enable_in_code.
        Monitor.classes  = ['PiPresents',
                            
                            'HyperlinkShow','RadioButtonShow','ArtLiveShow','ArtMediaShow','MediaShow','LiveShow','MenuShow',
                            'GapShow','Show','ArtShow',
                            'AudioPlayer','BrowserPlayer','ImagePlayer','MenuPlayer','MessagePlayer','VideoPlayer','Player',
                            'MediaList','LiveList','ShowList',
                            'PathManager','ControlsManager','ShowManager','PluginManager','IOPluginManager',
                            'MplayerDriver','OMXDriver','UZBLDriver',
                            'TimeOfDay','ScreenDriver','Animate','OSCDriver','CounterManager',
                            'Network','Mailer'
                            ]
        

        # Monitor.classes=['PiPresents','MediaShow','GapShow','Show','VideoPlayer','Player','OMXDriver']
        # Monitor.classes=['OSCDriver']
        
        # get global log level from command line
        Monitor.log_level = int(self.options['debug'])
        Monitor.manager = self.options['manager']
        # print self.options['manager']
        self.mon.newline(3)
        self.mon.sched (self,None, "Pi Presents is starting, Version:"+self.pipresents_minorissue + ' at '+time.strftime("%Y-%m-%d %H:%M.%S"))
        self.mon.log (self, "Pi Presents is starting, Version:"+self.pipresents_minorissue+ ' at '+time.strftime("%Y-%m-%d %H:%M.%S"))
        # self.mon.log (self," OS and separator:" + os.name +'  ' + os.sep)
        self.mon.log(self,"sys.path[0] -  location of code: "+sys.path[0])

        # log versions of Raspbian and omxplayer, and GPU Memory
        with open("/boot/issue.txt") as ifile:
            self.mon.log(self,'\nRaspbian: '+ifile.read())

        self.mon.log(self,'\n'+check_output(["omxplayer", "-v"]))
        self.mon.log(self,'\nGPU Memory: '+check_output(["vcgencmd", "get_mem", "gpu"]))

        if os.geteuid() == 0:
            print 'Do not run Pi Presents with sudo'
            self.mon.log(self,'Do not run Pi Presents with sudo')
            self.mon.finish()
            sys.exit(102)

        
        if "DESKTOP_SESSION" not in os.environ:
            print 'Pi Presents must be run from the Desktop'
            self.mon.log(self,'Pi Presents must be run from the Desktop')
            self.mon.finish()
            sys.exit(102)
        else:
            self.mon.log(self,'Desktop is '+ os.environ['DESKTOP_SESSION'])
        
        # optional other classes used
        self.root=None
        self.ppio=None
        self.tod=None
        self.animate=None
        self.ioplugin_manager=None
        self.oscdriver=None
        self.osc_enabled=False
        self.tod_enabled=False
        self.email_enabled=False
        
        user=os.getenv('USER')

        if user is None:
            tkMessageBox.showwarning("You must be logged in to run Pi Presents")
            exit(102)

        if user !='pi':
            self.mon.warn(self,"You must be logged as pi to use GPIO")

        self.mon.log(self,'User is: '+ user)
        # self.mon.log(self,"os.getenv('HOME') -  user home directory (not used): " + os.getenv('HOME')) # does not work
        # self.mon.log(self,"os.path.expanduser('~') -  user home directory: " + os.path.expanduser('~'))   # does not work



        # check network is available
        self.network_connected=False
        self.network_details=False
        self.interface=''
        self.ip=''
        self.unit=''
        
        # sets self.network_connected and self.network_details
        self.init_network()

        
        # start the mailer and send email when PP starts
        self.email_enabled=False
        if self.network_connected is True:
            self.init_mailer()
            if self.email_enabled is True and self.mailer.email_at_start is True:
                subject= '[Pi Presents] ' + self.unit + ': PP Started on ' + time.strftime("%Y-%m-%d %H:%M")
                message = time.strftime("%Y-%m-%d %H:%M") + '\nUnit: ' + self.unit + '   Profile: '+ self.options['profile']+ '\n ' + self.interface + '\n ' + self.ip 
                self.send_email('start',subject,message) 

         
        # get profile path from -p option
        if self.options['profile'] != '':
            self.pp_profile_path="/pp_profiles/"+self.options['profile']
        else:
            self.mon.err(self,"Profile not specified in command ")
            self.end('error','Profile not specified with the commands -p option')
        
       # get directory containing pp_home from the command,
        if self.options['home']  == "":
            home = os.sep+ 'home' + os.sep + user + os.sep+"pp_home"
        else:
            home = self.options['home'] + os.sep+ "pp_home"         
        self.mon.log(self,"pp_home directory is: " + home)


        # check if pp_home exists.
        # try for 10 seconds to allow usb stick to automount
        found=False
        for i in range (1, 10):
            self.mon.log(self,"Trying pp_home at: " + home +  " (" + str(i)+')')
            if os.path.exists(home):
                found=True
                self.pp_home=home
                break
            time.sleep (1)
        if found is True:
            self.mon.log(self,"Found Requested Home Directory, using pp_home at: " + home)
        else:
            self.mon.err(self,"Failed to find pp_home directory at " + home)
            self.end('error',"Failed to find pp_home directory at " + home)


        # check profile exists
        self.pp_profile=self.pp_home+self.pp_profile_path
        if os.path.exists(self.pp_profile):
            self.mon.sched(self,None,"Running profile: " + self.pp_profile_path)
            self.mon.log(self,"Found Requested profile - pp_profile directory is: " + self.pp_profile)
        else:
            self.mon.err(self,"Failed to find requested profile: "+ self.pp_profile)
            self.end('error',"Failed to find requested profile: "+ self.pp_profile)

        self.mon.start_stats(self.options['profile'])
        
        if self.options['verify'] is True:
            self.mon.err(self,"Validation option not supported - use the editor")
            self.end('error','Validation option not supported - use the editor')

         
        # initialise and read the showlist in the profile
        self.showlist=ShowList()
        self.showlist_file= self.pp_profile+ "/pp_showlist.json"
        if os.path.exists(self.showlist_file):
            self.showlist.open_json(self.showlist_file)
        else:
            self.mon.err(self,"showlist not found at "+self.showlist_file)
            self.end('error',"showlist not found at "+self.showlist_file)

        # check profile and Pi Presents issues are compatible
        if self.showlist.profile_version() != self.pipresents_version():
            self.mon.err(self,"Version of showlist " + self.showlist.profile_version_string + " is not  same as Pi Presents")
            self.end('error',"Version of showlist " + self.showlist.profile_version_string + " is not  same as Pi Presents")


        # get the 'start' show from the showlist
        index = self.showlist.index_of_start_show()
        if index >=0:
            self.showlist.select(index)
            self.starter_show=self.showlist.selected_show()
        else:
            self.mon.err(self,"Show [start] not found in showlist")
            self.end('error',"Show [start] not found in showlist")


# ********************
# SET UP THE GUI
# ********************
        # turn off the screenblanking and saver
        if self.options['noblank'] is True:
            call(["xset","s", "off"])
            call(["xset","s", "-dpms"])

        self.root=Tk()   
       
        self.title='Pi Presents - '+ self.pp_profile
        self.icon_text= 'Pi Presents'
        self.root.title(self.title)
        self.root.iconname(self.icon_text)
        self.root.config(bg=self.starter_show['background-colour'])

        self.mon.log(self, 'monitor screen dimensions are ' + str(self.root.winfo_screenwidth()) + ' x ' + str(self.root.winfo_screenheight()) + ' pixels')
        if self.options['screensize'] =='':        
            self.screen_width = self.root.winfo_screenwidth()
            self.screen_height = self.root.winfo_screenheight()
        else:
            reason,message,self.screen_width,self.screen_height=self.parse_screen(self.options['screensize'])
            if reason =='error':
                self.mon.err(self,message)
                self.end('error',message)

        self.mon.log(self, 'forced screen dimensions (--screensize) are ' + str(self.screen_width) + ' x ' + str(self.screen_height) + ' pixels')
       
        # set window dimensions and decorations
        if self.options['fullscreen'] is False:
            self.window_width=int(self.root.winfo_screenwidth()*self.nonfull_window_width)
            self.window_height=int(self.root.winfo_screenheight()*self.nonfull_window_height)
            self.window_x=self.nonfull_window_x
            self.window_y=self.nonfull_window_y
            self.root.geometry("%dx%d%+d%+d" % (self.window_width,self.window_height,self.window_x,self.window_y))
        else:
            self.window_width=self.screen_width
            self.window_height=self.screen_height
            self.root.attributes('-fullscreen', True)
            os.system('unclutter &')
            self.window_x=0
            self.window_y=0  
            self.root.geometry("%dx%d%+d%+d"  % (self.window_width,self.window_height,self.window_x,self.window_y))
            self.root.attributes('-zoomed','1')

        # canvas cover the whole screen whatever the size of the window. 
        self.canvas_height=self.screen_height
        self.canvas_width=self.screen_width
  
        # make sure focus is set.
        self.root.focus_set()

        # define response to main window closing.
        self.root.protocol ("WM_DELETE_WINDOW", self.handle_user_abort)

        # setup a canvas onto which will be drawn the images or text
        self.canvas = Canvas(self.root, bg=self.starter_show['background-colour'])


        if self.options['fullscreen'] is True:
            self.canvas.config(height=self.canvas_height,
                               width=self.canvas_width,
                               highlightthickness=0)
        else:
            self.canvas.config(height=self.canvas_height,
                    width=self.canvas_width,
                        highlightthickness=1,
                               highlightcolor='yellow')
            
        self.canvas.place(x=0,y=0)
        # self.canvas.config(bg='black')
        self.canvas.focus_set()


                
# ****************************************
# INITIALISE THE TOUCHSCREEN DRIVER
# ****************************************

        # each driver takes a set of inputs, binds them to symboic names
        # and sets up a callback which returns the symbolic name when an input event occurs

        self.sr=ScreenDriver()
        # read the screen click area config file
        reason,message = self.sr.read(pp_dir,self.pp_home,self.pp_profile)
        if reason == 'error':
            self.end('error','cannot find, or error in screen.cfg')


        # create click areas on the canvas, must be polygon as outline rectangles are not filled as far as find_closest goes
        # click areas are made on the Pi Presents canvas not the show canvases.
        reason,message = self.sr.make_click_areas(self.canvas,self.handle_input_event)
        if reason == 'error':
            self.mon.err(self,message)
            self.end('error',message)


# ****************************************
# INITIALISE THE APPLICATION AND START
# ****************************************
        self.shutdown_required=False
        self.reboot_required=False
        self.terminate_required=False
        self.exitpipresents_required=False

        # initialise the I/O plugins by importing their drivers
        self.ioplugin_manager=IOPluginManager()
        reason,message=self.ioplugin_manager.init(self.pp_dir,self.pp_profile,self.root,self.handle_input_event)
        if reason == 'error':
            # self.mon.err(self,message)
            self.end('error',message)

        
        # kick off animation sequencer
        self.animate = Animate()
        self.animate.init(pp_dir,self.pp_home,self.pp_profile,self.canvas,200,self.handle_output_event)
        self.animate.poll()

        #create a showmanager ready for time of day scheduler and osc server
        show_id=-1
        self.show_manager=ShowManager(show_id,self.showlist,self.starter_show,self.root,self.canvas,self.pp_dir,self.pp_profile,self.pp_home)
        # first time through set callback to terminate Pi Presents if all shows have ended.
        self.show_manager.init(self.canvas,self.all_shows_ended_callback,self.handle_command,self.showlist)
        # Register all the shows in the showlist
        reason,message=self.show_manager.register_shows()
        if reason == 'error':
            self.mon.err(self,message)
            self.end('error',message)


        # Init OSCDriver, read config and start OSC server
        self.osc_enabled=False
        if self.network_connected is True:
            if os.path.exists(self.pp_profile + os.sep + 'pp_io_config'+ os.sep + 'osc.cfg'):
                self.oscdriver=OSCDriver()
                reason,message=self.oscdriver.init(self.pp_profile,
                                                   self.unit,self.interface,self.ip,
                                                   self.handle_command,self.handle_input_event,self.e_osc_handle_animate)
                if reason == 'error':
                    self.mon.err(self,message)
                    self.end('error',message)
                else:
                    self.osc_enabled=True
                    self.root.after(1000,self.oscdriver.start_server())

        
        # initialise ToD scheduler calculating schedule for today
        self.tod=TimeOfDay()
        reason,message,self.tod_enabled = self.tod.init(pp_dir,self.pp_home,self.pp_profile,self.showlist,self.root,self.handle_command)
        if reason == 'error':
            self.mon.err(self,message)
            self.end('error',message)
            
        # warn if the network not available when ToD required
        if self.tod_enabled is True and self.network_connected is False:
            self.mon.warn(self,'Network not connected  so Time of Day scheduler may be using the internal clock')

        # init the counter manager
        self.counter_manager=CounterManager()
        self.counter_manager.init()


        # warn about start shows and scheduler

        if self.starter_show['start-show']=='' and self.tod_enabled is False:
            self.mon.sched(self,None,"No Start Shows in Start Show and no shows scheduled") 
            self.mon.warn(self,"No Start Shows in Start Show and no shows scheduled")

        if self.starter_show['start-show'] !='' and self.tod_enabled is True:
            self.mon.sched(self,None,"Start Shows in Start Show and shows scheduled - conflict?") 
            self.mon.warn(self,"Start Shows in Start Show and shows scheduled - conflict?")

        # run the start shows
        self.run_start_shows()           

        # kick off the time of day scheduler which may run additional shows
        if self.tod_enabled is True:
            self.tod.poll()

        # start the I/O plugins input event generation
        self.ioplugin_manager.start()


        # start Tkinters event loop
        self.root.mainloop( )


    def parse_screen(self,size_text):
        fields=size_text.split('*')
        if len(fields)!=2:
            return 'error','do not understand --screensize comand option',0,0
        elif fields[0].isdigit()  is False or fields[1].isdigit()  is False:
            return 'error','dimensions are not positive integers in --screensize',0,0
        else:
            return 'normal','',int(fields[0]),int(fields[1])
        

# *********************
#  RUN START SHOWS
# ********************   
    def run_start_shows(self):
        self.mon.trace(self,'run start shows')
        # parse the start shows field and start the initial shows       
        show_refs=self.starter_show['start-show'].split()
        for show_ref in show_refs:
            reason,message=self.show_manager.control_a_show(show_ref,'open')
            if reason == 'error':
                self.mon.err(self,message)
                


# *********************
# User inputs
# ********************

    def e_osc_handle_animate(self,line):
        #jump  out of server thread
        self.root.after(1, lambda arg=line: self.osc_handle_animate(arg))

    def osc_handle_animate(self,line):
        self.mon.log(self,"animate command received: "+ line)
        #osc sends output events as a string
        reason,message,delay,name,param_type,param_values=self.animate.parse_animate_fields(line)
        if reason == 'error':
            self.mon.err(self,message)
            self.end(reason,message)
        self.handle_output_event(name,param_type,param_values,0)

    # output events are animate commands       
    def handle_output_event(self,symbol,param_type,param_values,req_time):
            reason,message=self.ioplugin_manager.handle_output_event(symbol,param_type,param_values,req_time)
            if reason =='error':
                self.mon.err(self,message)
                self.end(reason,message)



    # all input events call this callback providing a symbolic name.
    # handle events that affect PP overall, otherwise pass to all active shows
    def handle_input_event(self,symbol,source):
        self.mon.log(self,"event received: "+symbol + ' from '+ source)
        if symbol == 'pp-terminate':
            self.handle_user_abort()
            
        elif symbol == 'pp-shutdown':
            self.mon.err(self,'pp-shutdown removed in version 1.3.3a, see Release Notes')
            self.end('error','pp-shutdown removed in version 1.3.3a, see Release Notes')

            
        elif symbol == 'pp-shutdownnow':
            # need root.after to grt out of st thread
            self.root.after(1,self.shutdownnow_pressed)
            return
        
        elif symbol == 'pp-exitpipresents':
            self.exitpipresents_required=True
            if self.show_manager.all_shows_exited() is True:
                # need root.after to grt out of st thread
                self.root.after(1,self.e_all_shows_ended_callback)
                return
            reason,message= self.show_manager.exit_all_shows()
        else:
            # pass the input event to all registered shows
            for show in self.show_manager.shows:
                show_obj=show[ShowManager.SHOW_OBJ]
                if show_obj is not None:
                    show_obj.handle_input_event(symbol)



    # commands are generaed by tracks and shows
    # they can open or close shows, generate input events and do special tasks
    # commands also generate osc outputs to other computers
    # handles one command provided as a line of text
    
    def handle_command(self,command_text,source='',show=''):
        # print 'PIPRESENTS ',command_text,'\n   Source',source,'from',show
        self.mon.log(self,"command received: " + command_text)
        if command_text.strip()=="":
            return

        fields= command_text.split()

        if fields[0] in ('osc','OSC'): 
            if self.osc_enabled is True:
                status,message=self.oscdriver.parse_osc_command(fields[1:])
                if status=='warn':
                    self.mon.warn(self,message)
                if status=='error':
                    self.mon.err(self,message)
                    self.end('error',message)
                return
        

        if fields[0] =='counter':
            status,message=self.counter_manager.parse_counter_command(fields[1:])
            if status=='error':
                self.mon.err(self,message)
                self.end('error',message)
            return

                           
        show_command=fields[0]
        if len(fields)>1:
            show_ref=fields[1]
        else:
            show_ref=''
        if show_command in ('open','close','closeall','openexclusive'):
            self.mon.sched(self, TimeOfDay.now,command_text + ' received from show:'+show)
            if self.shutdown_required is False and self.terminate_required is False:
                reason,message=self.show_manager.control_a_show(show_ref,show_command)
            else:
                return
            
        elif show_command =='monitor':
            self.handle_monitor_command(show_ref)
            return

        elif show_command =='cec':
            self.handle_cec_command(show_ref)
            return
        
        elif show_command == 'event':
            self.handle_input_event(show_ref,'Show Control')
            return
        
        elif show_command == 'exitpipresents':
            self.exitpipresents_required=True
            if self.show_manager.all_shows_exited() is True:
                # need root.after to get out of st thread
                self.root.after(1,self.e_all_shows_ended_callback)
                return
            else:
                reason,message= self.show_manager.exit_all_shows()

        elif show_command == 'shutdownnow':
            # need root.after to get out of st thread
            self.root.after(1,self.shutdownnow_pressed)
            return

        elif show_command == 'reboot':
            # need root.after to get out of st thread
            self.root.after(1,self.reboot_pressed)
            return
        
        else:
            reason='error'
            message = 'command not recognised: '+ show_command
            
        if reason=='error':
            self.mon.err(self,message)
        return


    def handle_monitor_command(self,command):
        if command == 'on':
            os.system('vcgencmd display_power 1 >/dev/null')
        elif command == 'off':
            os.system('vcgencmd display_power 0 >/dev/null')

    def handle_cec_command(self,command):
        if command == 'on':
            os.system('echo "on 0" | cec-client -s')
        elif command == 'standby':
            os.system('echo "standby 0" | cec-client -s')

        elif command == 'scan':
            os.system('echo scan | cec-client -s -d 1')
                      
    # deal with differnt commands/input events

    def shutdownnow_pressed(self):
        self.shutdown_required=True
        if self.show_manager.all_shows_exited() is True:
           self.all_shows_ended_callback('normal','no shows running')
        else:
            # calls exit method of all shows, results in all_shows_closed_callback
            self.show_manager.exit_all_shows()

    def reboot_pressed(self):
        self.reboot_required=True
        if self.show_manager.all_shows_exited() is True:
           self.all_shows_ended_callback('normal','no shows running')
        else:
            # calls exit method of all shows, results in all_shows_closed_callback
            self.show_manager.exit_all_shows() 


    def handle_sigterm(self,signum,fframe):
        self.mon.log(self,'SIGTERM received - '+ str(signum))
        self.terminate()


    def handle_user_abort(self):
        self.mon.log(self,'User abort received')
        self.terminate()

    def terminate(self):
        self.mon.log(self, "terminate received")
        self.terminate_required=True
        needs_termination=False
        for show in self.show_manager.shows:
            # print  show[ShowManager.SHOW_OBJ], show[ShowManager.SHOW_REF]
            if show[ShowManager.SHOW_OBJ] is not None:
                needs_termination=True
                self.mon.log(self,"Sent terminate to show "+ show[ShowManager.SHOW_REF])
                # call shows terminate method
                # eventually the show will exit and after all shows have exited all_shows_callback will be executed.
                show[ShowManager.SHOW_OBJ].terminate()
        if needs_termination is False:
            self.end('killed','killed - no termination of shows required')



# ******************************
# Ending Pi Presents after all the showers and players are closed
# **************************

    def e_all_shows_ended_callback(self):
        self.all_shows_ended_callback('normal','no shows running')

    # callback from ShowManager when all shows have ended
    def all_shows_ended_callback(self,reason,message):
        self.canvas.config(bg=self.starter_show['background-colour'])
        if reason in ('killed','error') or self.shutdown_required is True or self.exitpipresents_required is True or self.reboot_required is True:
            self.end(reason,message)

    def end(self,reason,message):
        self.mon.log(self,"Pi Presents ending with reason: " + reason)
        if self.root is not None:
            self.root.destroy()
        self.tidy_up()
        if reason == 'killed':
            if self.email_enabled is True and self.mailer.email_on_terminate is True:
                subject= '[Pi Presents] ' + self.unit + ': PP Exited with reason: Terminated'
                message = time.strftime("%Y-%m-%d %H:%M") + '\n ' + self.unit + '\n ' + self.interface + '\n ' + self.ip 
                self.send_email(reason,subject,message)
            self.mon.sched(self, None,"Pi Presents Terminated, au revoir\n")
            self.mon.log(self, "Pi Presents Terminated, au revoir")
                          
            # close logging files
            self.mon.finish()
            print 'Uncollectable Garbage',gc.collect()
            # objgraph.show_backrefs(objgraph.by_type('Monitor'))
            sys.exit(101)
                          
        elif reason == 'error':
            if self.email_enabled is True and self.mailer.email_on_error is True:
                subject= '[Pi Presents] ' + self.unit + ': PP Exited with reason: Error'
                message_text = 'Error message: '+ message + '\n'+ time.strftime("%Y-%m-%d %H:%M") + '\n ' + self.unit + '\n ' + self.interface + '\n ' + self.ip 
                self.send_email(reason,subject,message_text)   
            self.mon.sched(self,None, "Pi Presents closing because of error, sorry\n")
            self.mon.log(self, "Pi Presents closing because of error, sorry")
                          
            # close logging files 
            self.mon.finish()
            print 'uncollectable garbage',gc.collect()
            sys.exit(102)

        else:           
            self.mon.sched(self,None,"Pi Presents  exiting normally, bye\n")
            self.mon.log(self,"Pi Presents  exiting normally, bye")
            
            # close logging files 
            self.mon.finish()
            if self.reboot_required is True:
                # print 'REBOOT'
                call (['sudo','reboot'])
            if self.shutdown_required is True:
                # print 'SHUTDOWN'
                call (['sudo','shutdown','now','SHUTTING DOWN'])
            print 'uncollectable garbage',gc.collect()
            sys.exit(100)


    # tidy up all the peripheral bits of Pi Presents
    def tidy_up(self):
        self.handle_monitor_command('on')
        self.mon.log(self, "Tidying Up")
        # turn screen blanking back on
        if self.options['noblank'] is True:
            call(["xset","s", "on"])
            call(["xset","s", "+dpms"])
            
        # tidy up animation
        if self.animate is not None:
            self.animate.terminate()

        # tidy up i/o plugins
        if self.ioplugin_manager != None:
            self.ioplugin_manager.terminate()

        if self.osc_enabled is True:
            self.oscdriver.terminate()
            
        # tidy up time of day scheduler
        if self.tod_enabled is True:
            self.tod.terminate()



# *******************************
# Connecting to network and email
# *******************************

    def init_network(self):

        timeout=int(self.options['nonetwork'])
        if timeout== 0:
            self.network_connected=False
            self.unit=''
            self.ip=''
            self.interface=''
            return
        
        self.network=Network()
        self.network_connected=False

        # try to connect to network
        self.mon.log (self, 'Waiting up to '+ str(timeout) + ' seconds for network')
        success=self.network.wait_for_network(timeout)
        if success is False:
            self.mon.warn(self,'Failed to connect to network after ' + str(timeout) + ' seconds')
            # tkMessageBox.showwarning("Pi Presents","Failed to connect to network so using fake-hwclock")
            return

        self.network_connected=True
        self.mon.sched (self, None,'Time after network check is '+ time.strftime("%Y-%m-%d %H:%M.%S"))
        self.mon.log (self, 'Time after network check is '+ time.strftime("%Y-%m-%d %H:%M.%S"))

        # Get web configuration
        self.network_details=False
        network_options_file_path=self.pp_dir+os.sep+'pp_config'+os.sep+'pp_web.cfg'
        if not os.path.exists(network_options_file_path):
            self.mon.warn(self,"pp_web.cfg not found at "+network_options_file_path)
            return
        self.mon.log(self, 'Found pp_web.cfg in ' + network_options_file_path)

        self.network.read_config(network_options_file_path)
        self.unit=self.network.unit

        # get interface and IP details of preferred interface
        self.interface,self.ip = self.network.get_preferred_ip()
        if self.interface == '':
            self.network_connected=False
            return
        self.network_details=True
        self.mon.log (self, 'Network details ' + self.unit + ' ' + self.interface + ' ' +self.ip)


    def init_mailer(self):

        self.email_enabled=False
        email_file_path = self.pp_dir+os.sep+'pp_config'+os.sep+'pp_email.cfg'
        if not os.path.exists(email_file_path):
            self.mon.log(self,'pp_email.cfg not found at ' + email_file_path)
            return
        self.mon.log(self,'Found pp_email.cfg at ' + email_file_path)
        self.mailer=Mailer()
        self.mailer.read_config(email_file_path)
        # all Ok so can enable email if config file allows it.
        if self.mailer.email_allowed is True:
            self.email_enabled=True
            self.mon.log (self,'Email Enabled')


    def try_connect(self):
        tries=1
        while True:
            success, error = self.mailer.connect()
            if success is True:
                return True
            else:
                self.mon.log(self,'Failed to connect to email SMTP server ' + str(tries) +  '\n ' +str(error))
                tries +=1
                if tries >5:
                    self.mon.log(self,'Failed to connect to email SMTP server after ' + str(tries))
                    return False


    def send_email(self,reason,subject,message):
        if self.try_connect() is False:
            return False
        else:
            success,error = self.mailer.send(subject,message)
            if success is False:
                self.mon.log(self, 'Failed to send email: ' + str(error))
                success,error=self.mailer.disconnect()
                if success is False:
                    self.mon.log(self,'Failed disconnect after send:' + str(error))
                return False
            else:
                self.mon.log(self,'Sent email for ' + reason)
                success,error=self.mailer.disconnect()
                if success is False:
                    self.mon.log(self,'Failed disconnect from email server ' + str(error))
                return True
Example #56
-4
class ConcordanceSearchView(object):
    _BACKGROUND_COLOUR='#FFF' #white

    #Colour of highlighted results
    _HIGHLIGHT_WORD_COLOUR='#F00' #red
    _HIGHLIGHT_WORD_TAG='HL_WRD_TAG'

    _HIGHLIGHT_LABEL_COLOUR='#C0C0C0' # dark grey
    _HIGHLIGHT_LABEL_TAG='HL_LBL_TAG'


    #Percentage of text left of the scrollbar position
    _FRACTION_LEFT_TEXT=0.30

    def __init__(self):
        self.model = ConcordanceSearchModel()
        self.model.add_listener(self)
        self.top = Tk()
        self._init_top(self.top)
        self._init_menubar()
        self._init_widgets(self.top)
        self._bind_event_handlers()
        self.load_corpus(self.model.DEFAULT_CORPUS)

    def _init_top(self, top):
        top.geometry('950x680+50+50')
        top.title('NLTK Concordance Search')
        top.bind('<Control-q>', self.destroy)
        top.minsize(950,680)

    def _init_widgets(self, parent):
        self.main_frame = Frame(parent, dict(background=self._BACKGROUND_COLOUR, padx=1, pady=1, border=1))
        self._init_corpus_select(self.main_frame)
        self._init_query_box(self.main_frame)
        self._init_results_box(self.main_frame)
        self._init_paging(self.main_frame)
        self._init_status(self.main_frame)
        self.main_frame.pack(fill='both', expand=True)

    def _init_menubar(self):
        self._result_size = IntVar(self.top)
        self._cntx_bf_len = IntVar(self.top)
        self._cntx_af_len = IntVar(self.top)
        menubar = Menu(self.top)

        filemenu = Menu(menubar, tearoff=0, borderwidth=0)
        filemenu.add_command(label='Exit', underline=1,
                             command=self.destroy, accelerator='Ctrl-q')
        menubar.add_cascade(label='File', underline=0, menu=filemenu)

        editmenu = Menu(menubar, tearoff=0)
        rescntmenu = Menu(editmenu, tearoff=0)
        rescntmenu.add_radiobutton(label='20', variable=self._result_size,
                                   underline=0, value=20,
                                   command=self.set_result_size)
        rescntmenu.add_radiobutton(label='50', variable=self._result_size,
                                   underline=0, value=50,
                                   command=self.set_result_size)
        rescntmenu.add_radiobutton(label='100', variable=self._result_size,
                                   underline=0, value=100,
                                   command=self.set_result_size)
        rescntmenu.invoke(1)
        editmenu.add_cascade(label='Result Count', underline=0, menu=rescntmenu)

        cntxmenu = Menu(editmenu, tearoff=0)
        cntxbfmenu = Menu(cntxmenu, tearoff=0)
        cntxbfmenu.add_radiobutton(label='60 characters',
                                   variable=self._cntx_bf_len,
                                   underline=0, value=60,
                                   command=self.set_cntx_bf_len)
        cntxbfmenu.add_radiobutton(label='80 characters',
                                   variable=self._cntx_bf_len,
                                   underline=0, value=80,
                                   command=self.set_cntx_bf_len)
        cntxbfmenu.add_radiobutton(label='100 characters',
                                   variable=self._cntx_bf_len,
                                   underline=0, value=100,
                                   command=self.set_cntx_bf_len)
        cntxbfmenu.invoke(1)
        cntxmenu.add_cascade(label='Before', underline=0, menu=cntxbfmenu)

        cntxafmenu = Menu(cntxmenu, tearoff=0)
        cntxafmenu.add_radiobutton(label='70 characters',
                                   variable=self._cntx_af_len,
                                   underline=0, value=70,
                                   command=self.set_cntx_af_len)
        cntxafmenu.add_radiobutton(label='90 characters',
                                   variable=self._cntx_af_len,
                                   underline=0, value=90,
                                   command=self.set_cntx_af_len)
        cntxafmenu.add_radiobutton(label='110 characters',
                                   variable=self._cntx_af_len,
                                   underline=0, value=110,
                                   command=self.set_cntx_af_len)
        cntxafmenu.invoke(1)
        cntxmenu.add_cascade(label='After', underline=0, menu=cntxafmenu)

        editmenu.add_cascade(label='Context', underline=0, menu=cntxmenu)

        menubar.add_cascade(label='Edit', underline=0, menu=editmenu)

        self.top.config(menu=menubar)

    def set_result_size(self, **kwargs):
        self.model.result_count = self._result_size.get()

    def set_cntx_af_len(self, **kwargs):
        self._char_after = self._cntx_af_len.get()

    def set_cntx_bf_len(self, **kwargs):
        self._char_before = self._cntx_bf_len.get()

    def _init_corpus_select(self, parent):
        innerframe = Frame(parent, background=self._BACKGROUND_COLOUR)
        self.var = StringVar(innerframe)
        self.var.set(self.model.DEFAULT_CORPUS)
        Label(innerframe, justify=LEFT, text=' Corpus: ',
              background=self._BACKGROUND_COLOUR, padx = 2, pady = 1, border = 0).pack(side='left')

        other_corpora = self.model.CORPORA.keys().remove(self.model.DEFAULT_CORPUS)
        om = OptionMenu(innerframe, self.var, self.model.DEFAULT_CORPUS, command=self.corpus_selected, *self.model.non_default_corpora())
        om['borderwidth'] = 0
        om['highlightthickness'] = 1
        om.pack(side='left')
        innerframe.pack(side='top', fill='x', anchor='n')

    def _init_status(self, parent):
        self.status = Label(parent, justify=LEFT, relief=SUNKEN, background=self._BACKGROUND_COLOUR, border=0, padx = 1, pady = 0)
        self.status.pack(side='top', anchor='sw')

    def _init_query_box(self, parent):
        innerframe = Frame(parent, background=self._BACKGROUND_COLOUR)
        another = Frame(innerframe, background=self._BACKGROUND_COLOUR)
        self.query_box = Entry(another, width=60)
        self.query_box.pack(side='left', fill='x', pady=25, anchor='center')
        self.search_button = Button(another, text='Search', command=self.search, borderwidth=1, highlightthickness=1)
        self.search_button.pack(side='left', fill='x', pady=25, anchor='center')
        self.query_box.bind('<KeyPress-Return>', self.search_enter_keypress_handler)
        another.pack()
        innerframe.pack(side='top', fill='x', anchor='n')

    def search_enter_keypress_handler(self, *event):
        self.search()

    def _init_results_box(self, parent):
        innerframe = Frame(parent)
        i1 = Frame(innerframe)
        i2 = Frame(innerframe)
        vscrollbar = Scrollbar(i1, borderwidth=1)
        hscrollbar = Scrollbar(i2, borderwidth=1, orient='horiz')
        self.results_box = Text(i1,
                                font=tkFont.Font(family='courier', size='16'),
                                state='disabled', borderwidth=1,
                                                            yscrollcommand=vscrollbar.set,
                                xscrollcommand=hscrollbar.set, wrap='none', width='40', height = '20', exportselection=1)
        self.results_box.pack(side='left', fill='both', expand=True)
        self.results_box.tag_config(self._HIGHLIGHT_WORD_TAG, foreground=self._HIGHLIGHT_WORD_COLOUR)
        self.results_box.tag_config(self._HIGHLIGHT_LABEL_TAG, foreground=self._HIGHLIGHT_LABEL_COLOUR)
        vscrollbar.pack(side='left', fill='y', anchor='e')
        vscrollbar.config(command=self.results_box.yview)
        hscrollbar.pack(side='left', fill='x', expand=True, anchor='w')
        hscrollbar.config(command=self.results_box.xview)
        #there is no other way of avoiding the overlap of scrollbars while using pack layout manager!!!
        Label(i2, text='   ', background=self._BACKGROUND_COLOUR).pack(side='left', anchor='e')
        i1.pack(side='top', fill='both', expand=True, anchor='n')
        i2.pack(side='bottom', fill='x', anchor='s')
        innerframe.pack(side='top', fill='both', expand=True)

    def _init_paging(self, parent):
        innerframe = Frame(parent, background=self._BACKGROUND_COLOUR)
        self.prev = prev = Button(innerframe, text='Previous', command=self.previous, width='10', borderwidth=1, highlightthickness=1, state='disabled')
        prev.pack(side='left', anchor='center')
        self.next = next = Button(innerframe, text='Next', command=self.next, width='10', borderwidth=1, highlightthickness=1, state='disabled')
        next.pack(side='right', anchor='center')
        innerframe.pack(side='top', fill='y')
        self.current_page = 0

    def previous(self):
        self.clear_results_box()
        self.freeze_editable()
        self.model.prev(self.current_page - 1)

    def next(self):
        self.clear_results_box()
        self.freeze_editable()
        self.model.next(self.current_page + 1)

    def about(self, *e):
        ABOUT = ("NLTK Concordance Search Demo\n")
        TITLE = 'About: NLTK Concordance Search Demo'
        try:
            from tkMessageBox import Message
            Message(message=ABOUT, title=TITLE, parent=self.main_frame).show()
        except:
            ShowText(self.top, TITLE, ABOUT)

    def _bind_event_handlers(self):
        self.top.bind(CORPUS_LOADED_EVENT, self.handle_corpus_loaded)
        self.top.bind(SEARCH_TERMINATED_EVENT, self.handle_search_terminated)
        self.top.bind(SEARCH_ERROR_EVENT, self.handle_search_error)
        self.top.bind(ERROR_LOADING_CORPUS_EVENT, self.handle_error_loading_corpus)

    def handle_error_loading_corpus(self, event):
        self.status['text'] = 'Error in loading ' + self.var.get()
        self.unfreeze_editable()
        self.clear_all()
        self.freeze_editable()

    def handle_corpus_loaded(self, event):
        self.status['text'] = self.var.get() + ' is loaded'
        self.unfreeze_editable()
        self.clear_all()
        self.query_box.focus_set()

    def handle_search_terminated(self, event):
        #todo: refactor the model such that it is less state sensitive
        results = self.model.get_results()
        self.write_results(results)
        self.status['text'] = ''
        if len(results) == 0:
            self.status['text'] = 'No results found for ' + self.model.query
        else:
                self.current_page = self.model.last_requested_page
        self.unfreeze_editable()
        self.results_box.xview_moveto(self._FRACTION_LEFT_TEXT)


    def handle_search_error(self, event):
        self.status['text'] = 'Error in query ' + self.model.query
        self.unfreeze_editable()

    def corpus_selected(self, *args):
        new_selection = self.var.get()
        self.load_corpus(new_selection)

    def load_corpus(self, selection):
        if self.model.selected_corpus != selection:
            self.status['text'] = 'Loading ' + selection + '...'
            self.freeze_editable()
            self.model.load_corpus(selection)

    def search(self):
        self.current_page = 0
        self.clear_results_box()
        self.model.reset_results()
        query = self.query_box.get()
        if (len(query.strip()) == 0): return
        self.status['text']  = 'Searching for ' + query
        self.freeze_editable()
        self.model.search(query, self.current_page + 1, )


    def write_results(self, results):
        self.results_box['state'] = 'normal'
        row = 1
        for each in results:
            sent, pos1, pos2 = each[0].strip(), each[1], each[2]
            if len(sent) != 0:
                if (pos1 < self._char_before):
                    sent, pos1, pos2 = self.pad(sent, pos1, pos2)
                sentence = sent[pos1-self._char_before:pos1+self._char_after]
                if not row == len(results):
                    sentence += '\n'
                self.results_box.insert(str(row) + '.0', sentence)
                word_markers, label_markers = self.words_and_labels(sent, pos1, pos2)
                for marker in word_markers: self.results_box.tag_add(self._HIGHLIGHT_WORD_TAG, str(row) + '.' + str(marker[0]), str(row) + '.' + str(marker[1]))
                for marker in label_markers: self.results_box.tag_add(self._HIGHLIGHT_LABEL_TAG, str(row) + '.' + str(marker[0]), str(row) + '.' + str(marker[1]))
                row += 1
        self.results_box['state'] = 'disabled'

    def words_and_labels(self, sentence, pos1, pos2):
        search_exp = sentence[pos1:pos2]
        words, labels = [], []
        labeled_words = search_exp.split(' ')
        index = 0
        for each in labeled_words:
            if each == '':
                index += 1
            else:
                word, label = each.split('/')
                words.append((self._char_before + index, self._char_before + index + len(word)))
                index += len(word) + 1
                labels.append((self._char_before + index, self._char_before + index + len(label)))
                index += len(label)
            index += 1
        return words, labels

    def pad(self, sent, hstart, hend):
        if hstart >= self._char_before:
            return sent, hstart, hend
        d = self._char_before - hstart
        sent = ''.join([' '] * d) + sent
        return sent, hstart + d, hend + d

    def destroy(self, *e):
        if self.top is None: return
        self.top.destroy()
        self.top = None

    def clear_all(self):
        self.query_box.delete(0, END)
        self.model.reset_query()
        self.clear_results_box()

    def clear_results_box(self):
        self.results_box['state'] = 'normal'
        self.results_box.delete("1.0", END)
        self.results_box['state'] = 'disabled'

    def freeze_editable(self):
        self.query_box['state'] = 'disabled'
        self.search_button['state'] = 'disabled'
        self.prev['state'] = 'disabled'
        self.next['state'] = 'disabled'

    def unfreeze_editable(self):
        self.query_box['state'] = 'normal'
        self.search_button['state'] = 'normal'
        self.set_paging_button_states()

    def set_paging_button_states(self):
        if self.current_page == 0 or self.current_page == 1:
            self.prev['state'] = 'disabled'
        else:
            self.prev['state'] = 'normal'
        if self.model.has_more_pages(self.current_page):
            self.next['state'] = 'normal'
        else:
            self.next['state'] = 'disabled'

    def fire_event(self, event):
        #Firing an event so that rendering of widgets happen in the mainloop thread
        self.top.event_generate(event, when='tail')

    def mainloop(self, *args, **kwargs):
        if in_idle(): return
        self.top.mainloop(*args, **kwargs)