예제 #1
0
    def __init__(self, parent, saveCallback=None):

        KeystoneEditFrame.__init__(self, parent)

        self.lastItem = None
        self.editor = None
        self.selectedItem = None
        self.EditedItems = None
        self.SaveCallback = saveCallback

        self.Pane = KeystonePanedWindow(self, orient=tk.HORIZONTAL)
        self.Pane.pack(fill=tk.BOTH, expand=1)

        self.viewFrame = BindFileCollectionView(self.Pane)
        self.viewFrame.Tree.OnSelect.append(self.selectItem)
        self.Pane.add(self.viewFrame)

        self.editFrame = KeystoneFrame(self.Pane,
                                       style='editStyle.TFrame',
                                       width=1000)
        self.editFrame.columnconfigure(0, weight=1)
        self.editFrame.rowconfigure(0, weight=1)
        self.Pane.add(self.editFrame)

        self._showingTree = None
        self.ShowTree = tk.BooleanVar(value=False)
        self.ShowTree.trace("w", self.OnShowTree)

        self.Reset()
예제 #2
0
    def __init__(self, parent, text, *args, **kwargs):

        KeystoneFrame.__init__(self, parent, *args, **kwargs)

        #setup grid
        self.columnconfigure(1, weight=1)
        self.rowconfigure(0, weight=1)
        self.rowconfigure(1)

        parts = text.split("\n", 1)
        self.ShortText = parts[0]
        if (len(parts) > 1):
            self.LongText = "\n".join(parts)
        else:
            self.LongText = None

        self.ShortLabel = KeystoneLabel(self, text=self.ShortText)
        self.ShortLabel.grid(row=0, column=0, sticky='nsew')
        self.LongLabel = None
        self.Button = None
        self.ButtonText = None
        if (self.LongText != None):
            self.LongLabel = KeystoneLabel(self, text=self.LongText)
            self.ButtonText = tk.StringVar(value=self.MORE)
            self.Button = KeystoneButton(self,
                                         textvariable=self.ButtonText,
                                         command=self.ToggleText)
            self.Button.grid(row=1, column=0, sticky='sw')
예제 #3
0
    def __init__(self, parent, macro: Macro = None):

        tk.Toplevel.__init__(self, parent)
        self.attributes("-topmost", 1)

        self.title("Create a Macro")
        icon = GetResourcePath('.\\Resources\\keystone.ico')
        if (icon != None):
            self.iconbitmap(icon)
        self.protocol("WM_DELETE_WINDOW", self.OnClose)
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)

        frame = KeystoneFrame(self)
        frame.columnconfigure(0, weight=0)
        frame.columnconfigure(1, weight=1, minsize='205')
        frame.rowconfigure(0, weight=1)
        frame.rowconfigure(1, weight=0)

        if (macro == None):
            macro = Macro("Name", [SlashCommand(repr="powexec_name power")])
        self.Editor = EditMacro(frame, macro)
        self.Editor.grid(column = 1, row = 0, rowspan=2, sticky='nsew')
        self.Close = KeystoneButton(frame)
        self.Close.configure(text="Close",  command=self.OnClose)
        self.Close.Color('red', 'black')
        self.Close.grid(column=0, row=1, sticky='nsew')
        self.Copy = KeystoneButton(frame, text="Copy to Clipboard", command=self.OnCopy)
        self.Copy.Color('green', 'black')
        self.Copy.grid(column=0, row=0, sticky='nsew')
        frame.grid(column=0, row=0, sticky='nsew')
예제 #4
0
    def __init__(self, parent, *args, **kwargs):

        tk.Toplevel.__init__(self, parent, *args, **kwargs)
        self.maxsize(324, 180)
        self.attributes("-toolwindow", 1)
        self.attributes("-topmost", 1)

        icon = GetResourcePath('.\\Resources\\keystone.ico')
        if (icon != None):
            self.iconbitmap(icon)

        self.title("About")

        frame = KeystoneFrame(self)

        #setup grid
        self.columnconfigure(0, weight=1, minsize=324)
        self.rowconfigure(0, weight=1, minsize=180)
        frame.columnconfigure(0, minsize=108)
        frame.columnconfigure(1, minsize=216)
        frame.rowconfigure(0, minsize=60)
        frame.rowconfigure(1, minsize=120)

        frame.grid(row=0, column=0, sticky='nsew')

        #logo
        imgPath = GetResourcePath('.\\Resources\\Keystone.png')
        if (imgPath != None):
            img = Image.open(imgPath)
            img = img.resize((54, 54))
            self.Logo = ImageTk.PhotoImage(img)
            logoLabel = KeystoneLabel(frame, image=self.Logo)
            logoLabel.grid(row=0, column=0, padx=3, pady=3)

        #name
        nameLabel = KeystoneLabel(frame,
                                  text='Keystone',
                                  font=(TEXT_FONT, LARGE_FONT_SIZE))
        nameLabel.grid(row=0, column=1, sticky='nw')
        subtextLabel = KeystoneLabel(frame,
                                     text='City of Heroes Keybind Editor')
        subtextLabel.grid(row=0, column=1, sticky='sw')

        #version
        versionPath = GetResourcePath('VERSION.txt')
        if (versionPath != None):
            file = open(versionPath, "r")
            try:
                version = file.read()
            finally:
                file.close()
            version = version.split("\n")
            versionLabel = KeystoneLabel(frame,
                                         text=version[0],
                                         font=(TEXT_FONT, LARGE_FONT_SIZE))
            versionLabel.grid(row=1, column=0, columnspan=2)
            dateLabel = KeystoneLabel(frame, text=version[1])
            dateLabel.grid(row=1, column=0, columnspan=2, sticky='s', pady=3)
예제 #5
0
class EditMacro(KeystoneFrame):

    def Load(self, macro: Macro):
        self.Name.set(macro.Name)
        self.Commands.Load(SlashCommandEditor, macro.Commands, SlashCommand(repr=DEFAULT_COMMAND))

    def Get(self) -> Macro:
        commands = [item.Item.Get() for item in self.Commands.Items]
        if (self.CommandOnly.get()):
            name = None
        else:
            name = self.Name.get()
        return Macro(name, commands)
    
    def __init__(self, parent, macro: Macro):
        KeystoneFrame.__init__(self, parent)

        #StringVar for Name
        self.Name = ""

        #List of commands view frame
        self.Commands = None

        #layout grid
        self.columnconfigure(0, weight=1, minsize=200)
        self.columnconfigure(1, weight=0)
        self.columnconfigure(2, weight=7)
        self.rowconfigure(0, weight=1)

        #add controls
        
        self.NameFrame = KeystoneFrame(self)
        self.NameFrame.columnconfigure(1, weight=1)
        self.NameFrame.columnconfigure(2, weight=0)
        self.NameFrame.rowconfigure(4, weight=1)
        self.NameFrame.grid(row=0, column=0, sticky='nsew') 

        self.CommandsFrame=KeystoneFrame(self)
        self.CommandsFrame.columnconfigure(0, weight=1)
        self.CommandsFrame.grid(row=0, column=2, sticky='nsew', padx="3", pady="3")
        
        self.Commands = FrameListView(self.CommandsFrame)
        self.Commands.grid(row=0, column=0, sticky='new')

        nameLabel = KeystoneLabel(self.NameFrame, anchor='nw', text="Name", width=5)
        nameLabel.grid(row=1, column=0, sticky="nw", padx="3", pady="3")
        self.Name = tk.StringVar()
        self.NameBox = KeystoneEntry(self.NameFrame, textvariable=self.Name)
        self.NameBox.grid(row=1, column=1, sticky="nsew", padx="3", pady="3")

        self.CommandOnly = tk.BooleanVar(value=False)
        self.CommandOnlyCheck = KeystoneCheckbutton(self.NameFrame, variable=self.CommandOnly)
        self.CommandOnlyCheck.grid(row=2, column=0, sticky="ne", padx="3", pady="3")
        commandOnlyLabel = KeystoneLabel(self.NameFrame, anchor='nw', text='Copy command only')
        commandOnlyLabel.grid(row=2, column=1, sticky="nw", padx="3", pady="3")
        
        self.Load(macro)
예제 #6
0
    def __init__(self, wizard, allowBack = False, allowNext = False, allowClose = False, onBack = None, onNext = None, onClose = None, *args, **kwargs):

        KeystoneFrame.__init__(self, wizard.Frame, *args, **kwargs)
        self.Wizard = wizard
        self.OnBack = onBack
        self.OnNext = onNext
        self.OnClose = onClose
        self.AllowBack = tk.BooleanVar(value = allowBack)
        self.AllowBack.trace("w", self._setAllowBack)
        self.AllowNext = tk.BooleanVar(value = allowNext)
        self.AllowNext.trace("w", self._setAllowNext)
        self.AllowClose = tk.BooleanVar(value = allowClose)
        self.AllowClose.trace("w", self._setAllowClose)
예제 #7
0
    def __init__(self, parent):
        KeystoneFrame.__init__(self, parent)

        #List of functions to run on SetDirty
        self.OnSetDirty = []

        #List of functions to run on SetClean
        self.OnSetClean = []

        #Loading flag, set to prevent flag changes while loading form
        self.Loading = False

        #init Dirty flag
        self.Dirty = tk.BooleanVar()
        self.Dirty.set(False)

        #init thread lock
        self.Lock = threading.Lock()
    def __init__(self,
                 wizard: KeystoneWizard,
                 text: str,
                 urls=None,
                 *args,
                 **kwargs):

        KeystoneWizardPage.__init__(self,
                                    wizard,
                                    allowBack=True,
                                    allowClose=True,
                                    allowNext=True,
                                    *args,
                                    **kwargs)

        self.columnconfigure(0, weight=0)
        self.columnconfigure(1, weight=1, minsize=510)
        self.rowconfigure(0, weight=1)

        label = KeystoneLabel(self, text=text, wraplength=500, justify=tk.LEFT)
        label.grid(row=0, column=1, sticky='n', padx=5, pady=5)
        global LeadBrickImage
        if (LeadBrickImage == None):
            imgPath = GetResourcePath('.\\Resources\\LeadBrick1.jpg')
            if (imgPath != None):
                LeadBrickImage = ImageTk.PhotoImage(Image.open(imgPath))
            else:
                LeadBrickImage = 0
        if (LeadBrickImage != 0):
            self.Image = LeadBrickImage
            self.ImagePanel = tk.Label(self, image=self.Image)
            self.ImagePanel.grid(row=0, column=0, sticky='nsew')

        if (urls != None):
            urlFrame = KeystoneFrame(self)
            for idx, eachURL in enumerate(urls):
                link = KeystoneLabel(urlFrame, text=eachURL)
                link.bind("<Button-1>",
                          lambda e, url=eachURL: self.callback(url))
                link.grid(row=idx, column=0, sticky='nsew')
            urlFrame.grid(row=0, column=1)
    def __init__(self, parent, showScroll=False):

        KeystoneFrame.__init__(self, parent)
        self.columnconfigure(0, weight=1)
        self.columnconfigure(1, weight=0)
        self.rowconfigure(0, weight=0)
        self.rowconfigure(1, weight=1)

        # creating a scrollbars
        self.yscrlbr = ttk.Scrollbar(self)
        if showScroll:
            self.yscrlbr.grid(column=1, row=1, sticky='ns')

        #create tree
        self.Tree = KeystoneTree(self,
                                 selectmode=tk.BROWSE,
                                 yscrollcommand=self.yscrlbr.set)
        self.Tree.grid(row=1, column=0, sticky='nsew')

        self.Tree['columns'] = ('bound_files')
        self.Tree.heading("#0", text="Keybind Collection", anchor='w')
        self.Tree.column("#0", stretch=True, width=300)
        self.Tree.column("#1", stretch=False, width=0)

        # accociating scrollbar comands to tree scroling
        self.yscrlbr.config(command=self.Tree.yview)

        self.yscrlbr.lift(self.Tree)

        #create file browse frame
        browseFrame = KeystoneFrame(self)
        browseFrame.grid(row=0, column=0, columnspan=2, sticky='nsew')
        browseFrame.columnconfigure(0, weight=1)
        browseFrame.columnconfigure(1, weight=0)
        self.Directory = ""

        self.Tree.OnSelect.append(self.OnSelectItem)
예제 #10
0
    def __init__(self, parent, macro: Macro):
        KeystoneFrame.__init__(self, parent)

        #StringVar for Name
        self.Name = ""

        #List of commands view frame
        self.Commands = None

        #layout grid
        self.columnconfigure(0, weight=1, minsize=200)
        self.columnconfigure(1, weight=0)
        self.columnconfigure(2, weight=7)
        self.rowconfigure(0, weight=1)

        #add controls
        
        self.NameFrame = KeystoneFrame(self)
        self.NameFrame.columnconfigure(1, weight=1)
        self.NameFrame.columnconfigure(2, weight=0)
        self.NameFrame.rowconfigure(4, weight=1)
        self.NameFrame.grid(row=0, column=0, sticky='nsew') 

        self.CommandsFrame=KeystoneFrame(self)
        self.CommandsFrame.columnconfigure(0, weight=1)
        self.CommandsFrame.grid(row=0, column=2, sticky='nsew', padx="3", pady="3")
        
        self.Commands = FrameListView(self.CommandsFrame)
        self.Commands.grid(row=0, column=0, sticky='new')

        nameLabel = KeystoneLabel(self.NameFrame, anchor='nw', text="Name", width=5)
        nameLabel.grid(row=1, column=0, sticky="nw", padx="3", pady="3")
        self.Name = tk.StringVar()
        self.NameBox = KeystoneEntry(self.NameFrame, textvariable=self.Name)
        self.NameBox.grid(row=1, column=1, sticky="nsew", padx="3", pady="3")

        self.CommandOnly = tk.BooleanVar(value=False)
        self.CommandOnlyCheck = KeystoneCheckbutton(self.NameFrame, variable=self.CommandOnly)
        self.CommandOnlyCheck.grid(row=2, column=0, sticky="ne", padx="3", pady="3")
        commandOnlyLabel = KeystoneLabel(self.NameFrame, anchor='nw', text='Copy command only')
        commandOnlyLabel.grid(row=2, column=1, sticky="nw", padx="3", pady="3")
        
        self.Load(macro)
예제 #11
0
class EditBindFileCollection(KeystoneEditFrame):
    def SetEditedItem(self, *args):
        editor = args[0]
        item = self.viewFrame.GetEditedItem(editor)
        self.viewFrame.SetEdited(item, True)
        hasChildren = (not (self.viewFrame.Dictionary[KEY_CHAINS] == NONE))
        self.ShowTree.set(hasChildren)
        if (self.EditedItems == None):
            self.EditedItems = [editor]
        elif (not (editor in self.EditedItems)):
            self.EditedItems.append(editor)
        self.SetDirty()

    def ClearEditedItem(self, *args):
        editor = args[0]
        item = self.viewFrame.GetEditedItem(editor)
        self.viewFrame.SetEdited(item, False)
        if (self.EditedItems != None):
            if (editor in self.EditedItems):
                self.EditedItems.remove(editor)
                if (len(self.EditedItems) == 0):
                    self.EditedItems = None
                    self.SetClean()

    def selectItem(self, *args):
        self.selectedItem = self.viewFrame.Tree.focus()
        if (self.selectedItem == self.lastItem):
            return
        if (not self.viewFrame.Tree.HasTag(self.selectedItem, FILE_TAG)):
            self.lastItem = None
            if (self.editor != None):
                self.editor.grid_forget()
                self.editor = None
            return
        self.lastItem = self.selectedItem

        fileTag = self.viewFrame.Tree.GetTags(self.selectedItem)[1]
        editor = self.viewFrame.GetEditor(fileTag)
        if (self.editor != None):
            self.editor.grid_forget()
        if (editor != None):
            self.editor = editor
        else:
            bindFile = self.viewFrame.Get(fileTag)
            self.editor = EditBindFile(self.editFrame, bindFile)
            self.editor.OnSetDirty.append(self.SetEditedItem)
            self.editor.OnSetClean.append(self.ClearEditedItem)
            self.viewFrame.SetEditor(fileTag, self.editor)

        self.editor.grid(row=0, column=0, sticky='nsew')

    def OnShowTree(self, *args):
        value = self.ShowTree.get()
        if (value and (self._showingTree != True)):
            self.Pane.insert(0, self.viewFrame)
            self._showingTree = True
        elif ((not value) and (self._showingTree != False)):
            self.Pane.forget(self.viewFrame)
            self._showingTree = False

    def Reset(self):
        if (self.editor != None):
            self.editor.grid_forget()
        self.EditedItems = None
        self.FilePath = None
        self.viewFrame.Reset()
        self.ShowTree.set(False)

    def Load(self, bindFileCollection):
        self.Reset()
        self.FilePath = bindFileCollection.FilePath
        self.viewFrame.Load(bindFileCollection)
        self.viewFrame.SelectRoot()
        hasChildren = (not (self.viewFrame.Dictionary[KEY_CHAINS] == NONE))
        self.ShowTree.set(hasChildren)
        if ((self.FilePath != None) and os.path.exists(self.FilePath)):
            self.SetClean(self)
        else:
            self.SetDirty(self)

    def Get(self):
        return self.viewFrame.GetCollection()

    def New(self, defaults: bool = False):
        editor = EditBindFile(self.editFrame)
        editor.New(defaults)
        bindFile = editor.Get()
        collection = BindFileCollection(None, bindFile)
        self.Load(collection)

    def Open(self, fileName=None):
        if (fileName == None):
            options = {}
            filePath = self.FilePath
            if (filePath != None):
                options['initialfile'] = filePath
                options['initialdir'] = os.path.dirname(filePath)
            options['title'] = "Open Keybind File"
            options['filetypes'] = (("Text Files", "*.txt"), ("All Files",
                                                              "*.*"))
            options['defaultextension'] = "txt"
            options['multiple'] = False
            self.master.update()
            fileName = filedialog.askopenfilename(**options)
            self.master.update()

        if (fileName != ''):
            self.Reset()
            collection = BindFileCollection()
            collection.Load(fileName)
            self.Load(collection)

    def Save(self, promptForPath: bool = False):

        if (self.viewFrame.Dictionary == None):
            return

        currentFilePath = self.FilePath
        if (promptForPath or (currentFilePath == None)):
            options = {}
            options['initialfile'] = "keybinds.txt"
            options['title'] = "Save Keybind File As"
            options['filetypes'] = (("Text Files", "*.txt"), ("All Files",
                                                              "*.*"))
            options['defaultextension'] = "txt"
            self.master.update()
            filePath = filedialog.asksaveasfilename(**options)
            self.master.update()
            if (filePath == ''):
                return
        else:
            filePath = currentFilePath

        self.FilePath = os.path.abspath(filePath)

        collection = self.Get()
        collection.Save(filePath)
        self.Reset()
        self.Load(collection)

        if (self.SaveCallback != None):
            self.SaveCallback(self)

    def ImportBinds(self, filePath):

        if (self.editor == None):
            return
        importCollection = BindFileCollection()
        importCollection.Deserialize(filePath)
        boundFiles = importCollection.GetBoundFiles()
        if (((self.editor.FilePath == None) or
             (self.editor.FilePath == NEW_FILE)) and (len(boundFiles) > 0)):
            response = messagebox.askokcancel(
                'Path Needed For Linked Files',
                'You must choose a target path for this file to set paths for linked files.\n'
                + 'The paths will be set, but no files will be saved yet.')
            if (not response):
                return
            options = {}
            options['initialfile'] = "keybinds.txt"
            options['title'] = "Select Target Destination for Linked Files"
            options['filetypes'] = (("Keybind Files", "*.txt"), ("All Files",
                                                                 "*.*"))
            options['defaultextension'] = "txt"
            self.master.update()
            pointPath = filedialog.asksaveasfilename(**options)
            self.master.update()
            if (pointPath == ''):
                return False
            self.FilePath = pointPath
        else:
            pointPath = self.editor.FilePath

        importCollection.RepointFilePaths(pointPath)
        if (pointPath != None):
            self.editor.FilePath = pointPath
            self.editor.PathLabel.configure(text=self.editor.FilePath)
            self.FilePath = self.editor.FilePath
            self.viewFrame.Directory = os.path.dirname(self.editor.FilePath)
            self.viewFrame.Dictionary[PATH] = self.editor.FilePath

        boundFiles = importCollection.GetBoundFiles()
        if (len(boundFiles) > 0):
            #put them in the orphange so refresh can find them
            orphans = [{
                PATH: boundFile.FilePath,
                REPR: boundFile.__repr__(),
                EDITOR: None,
                SELECTED_TAG: False
            } for boundFile in boundFiles]
            self.viewFrame.GetOrphanage(True, orphans)

        for bind in importCollection.File.Binds:
            self.editor.NewBindCallback(True, bind)

    def __init__(self, parent, saveCallback=None):

        KeystoneEditFrame.__init__(self, parent)

        self.lastItem = None
        self.editor = None
        self.selectedItem = None
        self.EditedItems = None
        self.SaveCallback = saveCallback

        self.Pane = KeystonePanedWindow(self, orient=tk.HORIZONTAL)
        self.Pane.pack(fill=tk.BOTH, expand=1)

        self.viewFrame = BindFileCollectionView(self.Pane)
        self.viewFrame.Tree.OnSelect.append(self.selectItem)
        self.Pane.add(self.viewFrame)

        self.editFrame = KeystoneFrame(self.Pane,
                                       style='editStyle.TFrame',
                                       width=1000)
        self.editFrame.columnconfigure(0, weight=1)
        self.editFrame.rowconfigure(0, weight=1)
        self.Pane.add(self.editFrame)

        self._showingTree = None
        self.ShowTree = tk.BooleanVar(value=False)
        self.ShowTree.trace("w", self.OnShowTree)

        self.Reset()
    def __init__(self, *args, **kwargs):

        tk.Tk.__init__(self, *args, **kwargs)

        win = self
        win.title("Keystone")
        icon = GetResourcePath('.\\Resources\\keystone.ico')
        if (icon != None):
            win.iconbitmap(icon)

        speedBar = KeystoneFrame(win)
        speedBar.config(height=45)
        speedBar.pack(anchor='n', fill=tk.X, expand=False, side=tk.TOP)

        menu = tk.Menu(win)

        fileMenu = tk.Menu(menu, tearoff=0)
        self.AddCommand(menu=fileMenu,
                        frame=speedBar,
                        label="Open",
                        command=self.OnFileOpen)
        self.AddCommand(menu=fileMenu,
                        frame=speedBar,
                        label="New (Empty)",
                        command=self.OnFileNew)
        self.AddCommand(menu=fileMenu,
                        frame=speedBar,
                        label="New (Defaults)",
                        command=self.OnFileNewDefaults)
        self.AddCommand(menu=fileMenu,
                        frame=speedBar,
                        label="Save",
                        command=self.OnFileSave)
        self.AddCommand(menu=fileMenu,
                        frame=speedBar,
                        label="Save As...",
                        command=self.OnFileSaveAs)
        fileMenu.add_command(label="Save All", command=self.OnSaveAll)
        self.AddCommand(menu=fileMenu,
                        frame=speedBar,
                        label="Close",
                        command=self.OnFileClose)
        fileMenu.add_command(label="Close All", command=self.OnCloseAll)
        menu.add_cascade(label="File", menu=fileMenu)

        cohMenu = tk.Menu(menu, tearoff=0)
        cohMenu.add_command(label="Download File", command=self.OnDownloadFile)
        cohMenu.add_command(label="Upload File", command=self.OnUploadFile)
        cohMenu.add_command(label="Create Macro", command=self.OnCreateMacro)
        menu.add_cascade(label="Game Commands", menu=cohMenu)

        importExportMenu = tk.Menu(menu, tearoff=0)
        importExportMenu.add_command(label="Import Binds",
                                     command=self.OnImportBinds)
        importExportMenu.add_command(label="Export Binds",
                                     command=self.OnExportBinds)
        importExportMenu.add_command(label="Add Upload Bind",
                                     command=self.OnAddUploadBind)
        importExportMenu.add_command(
            label="Predefined Binds...",
            command=lambda parent=win, callback=self.OnPredefinedBindsCallback:
            ShowSelectKeybindImportWindow(parent, importCallback=callback))
        menu.add_cascade(label="Import\\Export", menu=importExportMenu)

        helpMenu = tk.Menu(menu, tearoff=0)
        helpMenu.add_command(
            label='Getting Started',
            command=lambda parent=win: ShowWalkthrough(parent))
        helpMenu.add_command(label='Import and Export',
                             command=lambda parent=win: ShowWalkthrough(
                                 parent,
                                 title="Import and Export Walkthrough",
                                 walkthrough=IMPORT_EXPORT_WALKTHROUGH))
        helpMenu.add_command(
            label='Collections and Loaded Files',
            command=lambda parent=win: ShowWalkthrough(
                parent,
                title="Collections and Loaded Files Walkthrough",
                walkthrough=COLLECTIONS_AND_KEYCHAINS_WALKTHROUGH,
                endPages=COLLECTIONS_AND_KEYCHAINS_WALKTHROUGH_END_PAGES))
        self.AddCommand(menu=helpMenu,
                        frame=speedBar,
                        label="About",
                        command=lambda parent=win: ShowHelpAbout(parent))
        menu.add_cascade(label='Help', menu=helpMenu)

        SetOpenLinkedFileCallback(self._openLinkedFileCallback)

        self.FirstFrame = KeystoneFrame(win)
        self.FirstFrame.columnconfigure(0, weight=1, minsize=800)
        self.FirstFrame.rowconfigure(0, weight=1, minsize=400)
        walkthroughButton = KeystoneButton(
            self.FirstFrame,
            text='Intro Walkthrough',
            command=lambda parent=win: ShowWalkthrough(parent))
        walkthroughButton.Color('lightskyblue', 'black')
        walkthroughButton.configure(relief=tk.RAISED)
        walkthroughButton.grid()
        self.FirstFrame.pack(fill=tk.BOTH, expand=True, side=tk.TOP)

        self.Notebook = FrameNotebook(win, EditBindFileCollection,
                                      [self.OnSaveCallback])
        self.ShowingNotebook = False
        self.SuppressCallback = False

        win.config(menu=menu, width=800, height=400)

        win.protocol("WM_DELETE_WINDOW", self.OnClosing)

        self.TabLock = threading.Lock()
class BindFileEditorWindow(tk.Tk):
    def _isOpenFile(self, path):
        if (self.Notebook.Items == None):
            return None
        thisPath = ComparableFilePath(path)
        for item in self.Notebook.Items:
            openPath = item.FilePath
            if (openPath == None):
                continue
            openPath = ComparableFilePath(openPath)

            if (thisPath == openPath):
                return item

        return None

    def NewTab(self, mode, path=None, bindFile=None):
        with self.TabLock:
            setDirty = False
            self.config(cursor="wait")
            self.update()
            try:
                if ((mode == "open") and (path != None)
                        and (self.Notebook.Items != None)):
                    if (self._isOpenFile(path) != None):
                        return
                self.Notebook.NewFrame("")
                editor = self.Notebook.SelectedFrame()
                if (mode == "open"):
                    editor.Open(fileName=path)
                    if (editor.FilePath == None):
                        self.Notebook.RemoveSelectedFrame()
                        return
                elif (mode == "new"):
                    editor.New(defaults=False)
                    if (bindFile != None):
                        editor.Load(bindFile)
                        setDirty = True
                elif (mode == "default"):
                    editor.New(defaults=True)
                self.SetTabName()
                if setDirty:
                    editor.SetDirty()
            finally:
                self.config(cursor="")
            self._showNotebook()
        print("Unlock")

    def SetTabName(self, editor=None):
        if (editor == None):
            editor = self.Notebook.SelectedFrame()
            if (editor == None):
                return
        else:
            tab = self.Notebook.GetTabNameFromItem(editor)
            self.Notebook.select(tab)

        filePath = editor.FilePath
        if (filePath == None):
            fileName = NEW_FILE
        else:
            fileName = GetFileName(filePath)
        self.Notebook.tab(self.Notebook.select(), text=fileName)

    def OnFileOpen(self):
        self.NewTab("open")

    def OnFileNew(self):
        self.NewTab("new")

    def OnFileNewDefaults(self):
        self.NewTab("default")

    def OnSaveCallback(self, editor, *args):
        self.SetTabName(editor=editor)

    def OnFileSave(self):
        collectionEditor = self.Notebook.SelectedFrame()
        if (collectionEditor == None):
            return
        editor = self.Notebook.SelectedFrame()
        if (editor == None):
            return
        editor.Save()

    def OnFileSaveAs(self):
        collectionEditor = self.Notebook.SelectedFrame()
        if (collectionEditor == None):
            return
        editor = self.Notebook.SelectedFrame()
        if (editor == None):
            return
        editor.Save(True)

    def CancelFromSavePrompt(self) -> bool:
        collectionEditor = self.Notebook.SelectedFrame()
        if (collectionEditor == None):
            return
        editor = self.Notebook.SelectedFrame()
        if (editor == None):
            return False
        if (editor.Dirty.get()):
            response = messagebox.askyesnocancel(
                "Edited File", "Save changes before proceeding?")
            if (response):
                self.OnFileSaveAs()
                if (editor.Dirty.get()):
                    #didn't save, abort
                    return True
            elif (response == None):
                return True
        return False

    def OnFileClose(self):
        collectionEditor = self.Notebook.SelectedFrame()
        if (collectionEditor == None):
            return
        editor = self.Notebook.SelectedFrame()
        if (editor == None):
            return
        if (self.CancelFromSavePrompt()):
            return
        self.Notebook.RemoveSelectedFrame()

    def OnDownloadFile(self):
        options = {}
        options['initialfile'] = "keybinds.txt"
        options['title'] = "Select File Destination"
        options['filetypes'] = (("Text Files", "*.txt"), ("All Files", "*.*"))
        options['defaultextension'] = "txt"
        self.update()
        filePath = filedialog.asksaveasfilename(**options)
        self.update()
        if (filePath == ''):
            return
        command = SlashCommand(name=SAVE_COMMAND,
                               text="\"%s\"" % os.path.abspath(filePath))
        self.clipboard_clear()
        self.clipboard_append("/" + str(command))
        response = messagebox.askokcancel(
            "Download from City of Heroes",
            "The command:\n\n" + "/%s\n\n" % str(command) +
            "has been copied to  the clipboard.\n\n" +
            "Paste and execute this command in the game to save the current keybinds to the selected location\n\n"
            + "Click OK to open the saved file.")
        if (response):
            self.NewTab("open", filePath)

    def OnUploadFile(self):
        collectionEditor = self.Notebook.SelectedFrame()
        if (collectionEditor == None):
            return
        editor = self.Notebook.SelectedFrame().editor
        if (editor == None):
            return
        if (self.CancelFromSavePrompt()):
            return
        if (editor.FilePath == None):
            return
        filePath = os.path.abspath(editor.FilePath)
        command = SlashCommand(name=LOAD_COMMAND,
                               text="\"%s\"" % os.path.abspath(filePath))
        self.clipboard_clear()
        self.clipboard_append("/" + str(command))
        messagebox.showinfo(
            "Upload to City of Heroes",
            "The command:\n\n" + "/%s\n\n" % str(command) +
            "has been copied to  the clipboard.\n\n" +
            "Paste and execute this command in the game to load the current keybinds from the selected location\n"
            +
            "You can add this command as a bind using the Add Upload Bind menu item."
        )

    def OnAddUploadBind(self):
        collectionEditor = self.Notebook.SelectedFrame()
        if (collectionEditor == None):
            return
        editor = self.Notebook.SelectedFrame().editor
        if (editor == None):
            return
        if ((editor.FilePath == None) and self.CancelFromSavePrompt()):
            return
        if (editor.FilePath == None):
            return
        editor.AddUploadBind()

    def OnClosing(self):
        if (self.Notebook.Dirty == True):
            response = messagebox.askyesnocancel(
                "Edited Files", "Save all changes before closing?")
            if (response):
                self.OnSaveAll()
            elif (response == None):
                return
        self.destroy()

    def OnSaveAll(self):
        if (self.Notebook.Dirty == True):
            if (self.Notebook.Items != None):
                for editor in self.Notebook.Items:
                    if editor.Dirty.get():
                        editor.Save()

    def OnCloseAll(self):
        while ((self.Notebook.Items != None)
               and (len(self.Notebook.Items) > 0)):
            self.CancelFromSavePrompt()
            self.Notebook.RemoveSelectedFrame()

    def _getBoundFilesSource(self):
        return [e.Get() for e in self.Notebook.Items if e.FilePath != None]

    def _onSelectCallback(self, binds, *args):

        editor = self.Notebook.SelectedFrame().editor
        bindFilePath = editor.FilePath
        options = {}
        options['initialfile'] = "keybinds.kst"
        options['title'] = "Select File Destination"
        options['filetypes'] = (("Keybind Export Files", "*.kst"),
                                ("All Files", "*.*"))
        options['defaultextension'] = "kst"
        self.update()
        filePath = filedialog.asksaveasfilename(**options)
        self.update()
        if (filePath == ''):
            return False

        bindFile = BindFile(binds, filePath=bindFilePath)
        boundFilesSource = self._getBoundFilesSource()
        bindFileCollection = BindFileCollection()
        bindFileCollection.Load(bindFilePath,
                                bindFile=bindFile,
                                boundFilesSource=boundFilesSource)
        bindFileCollection.Serialize(filePath)

        return True

    def OnImportBinds(self):
        collectionEditor = self.Notebook.SelectedFrame()
        if (collectionEditor == None):
            return
        bindFileEditor = self.Notebook.SelectedFrame().editor
        if (bindFileEditor == None):
            return
        if (self.CancelFromSavePrompt()):
            return

        options = {}

        options['title'] = "Open Keybind Export File"
        options['filetypes'] = (("Keybind Export Files", "*.kst"),
                                ("All Files", "*.*"))
        options['defaultextension'] = "kst"
        options['multiple'] = False
        self.update()
        fileName = filedialog.askopenfilename(**options)
        self.update()
        if (fileName == ''):
            return

        collectionEditor.ImportBinds(fileName)
        self.SetTabName(collectionEditor)

    def OnExportBinds(self):
        collectionEditor = self.Notebook.SelectedFrame()
        if (collectionEditor == None):
            return
        editor = self.Notebook.SelectedFrame().editor
        if (editor == None):
            return
        if (self.CancelFromSavePrompt()):
            return
        editor.OnSelectCallback = self._onSelectCallback
        editor.SetSelectMode(not editor.SelectMode)

    def OnCreateMacro(self):
        EditMacroWindow(self)

    def OnPredefinedBindsCallback(self, importWindow, filePath):
        collectionEditor = self.Notebook.SelectedFrame()
        if (collectionEditor == None):
            return
        bindFileEditor = self.Notebook.SelectedFrame().editor
        if (bindFileEditor == None):
            return
        if (self.CancelFromSavePrompt()):
            return

        collectionEditor.ImportBinds(filePath)
        self.SetTabName(collectionEditor)

    def AddCommand(self, menu: tk.Menu, frame, label, command):
        menu.add_command(label=label, command=command)
        KeystoneButton(frame, text=label, command=command).pack(anchor='nw',
                                                                side=tk.LEFT)

    def _openLinkedFileCallback(self, path):
        if not self.SuppressCallback:
            self.NewTab("open", path)

    def _showNotebook(self):
        if (not self.ShowingNotebook):
            self.Notebook.pack(fill=tk.BOTH, expand=True, side=tk.TOP)
            self.FirstFrame.pack_forget()
            self.ShowingNotebook = True

    def __init__(self, *args, **kwargs):

        tk.Tk.__init__(self, *args, **kwargs)

        win = self
        win.title("Keystone")
        icon = GetResourcePath('.\\Resources\\keystone.ico')
        if (icon != None):
            win.iconbitmap(icon)

        speedBar = KeystoneFrame(win)
        speedBar.config(height=45)
        speedBar.pack(anchor='n', fill=tk.X, expand=False, side=tk.TOP)

        menu = tk.Menu(win)

        fileMenu = tk.Menu(menu, tearoff=0)
        self.AddCommand(menu=fileMenu,
                        frame=speedBar,
                        label="Open",
                        command=self.OnFileOpen)
        self.AddCommand(menu=fileMenu,
                        frame=speedBar,
                        label="New (Empty)",
                        command=self.OnFileNew)
        self.AddCommand(menu=fileMenu,
                        frame=speedBar,
                        label="New (Defaults)",
                        command=self.OnFileNewDefaults)
        self.AddCommand(menu=fileMenu,
                        frame=speedBar,
                        label="Save",
                        command=self.OnFileSave)
        self.AddCommand(menu=fileMenu,
                        frame=speedBar,
                        label="Save As...",
                        command=self.OnFileSaveAs)
        fileMenu.add_command(label="Save All", command=self.OnSaveAll)
        self.AddCommand(menu=fileMenu,
                        frame=speedBar,
                        label="Close",
                        command=self.OnFileClose)
        fileMenu.add_command(label="Close All", command=self.OnCloseAll)
        menu.add_cascade(label="File", menu=fileMenu)

        cohMenu = tk.Menu(menu, tearoff=0)
        cohMenu.add_command(label="Download File", command=self.OnDownloadFile)
        cohMenu.add_command(label="Upload File", command=self.OnUploadFile)
        cohMenu.add_command(label="Create Macro", command=self.OnCreateMacro)
        menu.add_cascade(label="Game Commands", menu=cohMenu)

        importExportMenu = tk.Menu(menu, tearoff=0)
        importExportMenu.add_command(label="Import Binds",
                                     command=self.OnImportBinds)
        importExportMenu.add_command(label="Export Binds",
                                     command=self.OnExportBinds)
        importExportMenu.add_command(label="Add Upload Bind",
                                     command=self.OnAddUploadBind)
        importExportMenu.add_command(
            label="Predefined Binds...",
            command=lambda parent=win, callback=self.OnPredefinedBindsCallback:
            ShowSelectKeybindImportWindow(parent, importCallback=callback))
        menu.add_cascade(label="Import\\Export", menu=importExportMenu)

        helpMenu = tk.Menu(menu, tearoff=0)
        helpMenu.add_command(
            label='Getting Started',
            command=lambda parent=win: ShowWalkthrough(parent))
        helpMenu.add_command(label='Import and Export',
                             command=lambda parent=win: ShowWalkthrough(
                                 parent,
                                 title="Import and Export Walkthrough",
                                 walkthrough=IMPORT_EXPORT_WALKTHROUGH))
        helpMenu.add_command(
            label='Collections and Loaded Files',
            command=lambda parent=win: ShowWalkthrough(
                parent,
                title="Collections and Loaded Files Walkthrough",
                walkthrough=COLLECTIONS_AND_KEYCHAINS_WALKTHROUGH,
                endPages=COLLECTIONS_AND_KEYCHAINS_WALKTHROUGH_END_PAGES))
        self.AddCommand(menu=helpMenu,
                        frame=speedBar,
                        label="About",
                        command=lambda parent=win: ShowHelpAbout(parent))
        menu.add_cascade(label='Help', menu=helpMenu)

        SetOpenLinkedFileCallback(self._openLinkedFileCallback)

        self.FirstFrame = KeystoneFrame(win)
        self.FirstFrame.columnconfigure(0, weight=1, minsize=800)
        self.FirstFrame.rowconfigure(0, weight=1, minsize=400)
        walkthroughButton = KeystoneButton(
            self.FirstFrame,
            text='Intro Walkthrough',
            command=lambda parent=win: ShowWalkthrough(parent))
        walkthroughButton.Color('lightskyblue', 'black')
        walkthroughButton.configure(relief=tk.RAISED)
        walkthroughButton.grid()
        self.FirstFrame.pack(fill=tk.BOTH, expand=True, side=tk.TOP)

        self.Notebook = FrameNotebook(win, EditBindFileCollection,
                                      [self.OnSaveCallback])
        self.ShowingNotebook = False
        self.SuppressCallback = False

        win.config(menu=menu, width=800, height=400)

        win.protocol("WM_DELETE_WINDOW", self.OnClosing)

        self.TabLock = threading.Lock()
예제 #14
0
    def __init__(self, parent, bind: Bind, lockKey=False, dirty=False):
        KeystoneEditFrame.__init__(self, parent)

        #StringVar for Key
        self.Key = None

        #StringVar for Chord
        self.Chord = None

        #StringVar for Key Description
        self.KeyDescription = None

        #StringVar for Chord Description
        self.ChordDescription = None

        #List of commands view frame
        self.Commands = None

        #Indicates keys cannot be edited
        self._lockKey = lockKey

        #layout grid
        self.columnconfigure(0, weight=1, minsize=200)
        self.columnconfigure(1, weight=0)
        self.columnconfigure(2, weight=7)
        self.rowconfigure(0, weight=1)

        #add controls

        self.KeyFrame = KeystoneFrame(self)
        self.KeyFrame.columnconfigure(1, weight=1)
        self.KeyFrame.columnconfigure(2, weight=0)
        self.KeyFrame.rowconfigure(4, weight=1)

        self.CommandsFrame = KeystoneFrame(self)
        self.CommandsFrame.columnconfigure(0, weight=1)

        self.Commands = FrameListView(self.CommandsFrame)
        self.Commands.OnSetDirty.append(self.SetDirty)
        self.Commands.grid(row=0, column=0, sticky='new')

        self.TextFrame = KeystoneFrame(self)
        self.TextFrame.rowconfigure(0, weight=1, minsize='55')
        self.TextFrame.columnconfigure(0, weight=1, minsize='405')

        self.Delete = tk.Button(self,
                                text=self.DELETE_TEXT,
                                background=self.DELETE_COLOR,
                                foreground=self.DELETE_TEXT_COLOR,
                                font=(TEXT_FONT, 7, "bold"),
                                relief=self.DELETE_STYLE,
                                width=1,
                                wraplength=1,
                                command=self.OnDelete)

        self.Assign = tk.Button(self,
                                text=self.ASSIGN_TEXT,
                                background=self.ASSIGN_COLOR,
                                foreground=self.ASSIGN_TEXT_COLOR,
                                font=(TEXT_FONT, 7, "bold"),
                                relief=self.DELETE_STYLE,
                                width=1,
                                wraplength=1,
                                command=self.AssignCommand)

        self.UIToTextButton = KeystoneButton(self,
                                             text="Edit As Text",
                                             command=self.SynchUIToText)

        keyLabel = KeystoneLabel(self.KeyFrame,
                                 anchor='nw',
                                 text="Key",
                                 width=5)
        keyLabel.grid(row=1, column=0, sticky="nw", padx="3", pady="3")
        self.Key = tk.StringVar()
        self.KeyValue = KeystoneLabel(self.KeyFrame,
                                      anchor='nw',
                                      textvariable=self.Key,
                                      width=5)
        self.KeyBox = KeystoneKeyCombo(self.KeyFrame,
                                       textvariable=self.Key,
                                       values=" ".join(
                                           [c[0] for c in KEY_NAMES]))
        self.Key.trace("w", self.SelectKey)

        self.KeyDescription = tk.StringVar()
        keyDescription = KeystoneLabel(self.KeyFrame,
                                       anchor="nw",
                                       textvariable=self.KeyDescription,
                                       wraplength=200)
        keyDescription.grid(row=2,
                            column=0,
                            columnspan=2,
                            sticky="nsew",
                            padx="3",
                            pady="3")

        self.Key.set(bind.Key)
        self.Key.trace("w", self.SetDirty)

        chordLabel = KeystoneLabel(self.KeyFrame,
                                   anchor='nw',
                                   text="Chord",
                                   width=5)
        chordLabel.grid(row=3, column=0, sticky="nw", padx="3", pady="3")
        self.Chord = tk.StringVar()
        self.ChordValue = KeystoneLabel(self.KeyFrame,
                                        anchor='nw',
                                        textvariable=self.Chord,
                                        width=5)
        self.ChordBox = KeystoneKeyCombo(self.KeyFrame,
                                         textvariable=self.Chord,
                                         values=" ".join(
                                             [c[0] for c in CHORD_KEYS]))
        self.Chord.trace("w", self.SelectChord)

        self.ChordDescription = tk.StringVar()
        chordDescription = KeystoneLabel(self.KeyFrame,
                                         anchor="nw",
                                         textvariable=self.ChordDescription,
                                         wraplength=200)
        chordDescription.grid(row=4,
                              column=0,
                              columnspan=2,
                              sticky="nsew",
                              padx="3",
                              pady="3")

        self.Chord.set(bind.Chord)
        self.Chord.trace("w", self.SetDirty)

        self.UnlockKeysButton = KeystoneButton(self,
                                               text="Change Assigned Key",
                                               command=self.UnlockKeys)
        self.UnlockKeysButton.Color(FOREGROUND, BACKGROUND)

        self.ShowCommands = tk.BooleanVar()
        self.ShowCommands.trace("w", self.OnShowCommands)

        self.TextEntry = KeystoneTextEntry(self.TextFrame, height=5)
        self.TextEntry.grid(row=0, column=0, sticky="nsew", padx="3", pady="3")
        self.TextEntry.bind("<Key>", self.SetDirty)

        self.ShowTextEditor = tk.BooleanVar()
        self.ShowTextEditor.set(False)
        self.ShowTextEditor.trace("w", self.OnShowTextEditor)

        self.TextToUIButton = KeystoneButton(self.TextFrame,
                                             text="Editor",
                                             command=self.SynchTextToUI)
        self.TextToUIButton.grid(row=1,
                                 column=0,
                                 sticky="nsew",
                                 padx="3",
                                 pady="3")

        self.OnShowTextEditor()
        self.UnlockKeys(not lockKey)

        self.Load(bind)
        self.Dirty.set(dirty)
    def __init__(self,
                 parent,
                 title=None,
                 icon=None,
                 onBack=None,
                 onNext=None,
                 onClose=None,
                 *args,
                 **kwargs):

        #initialize
        tk.Toplevel.__init__(self, parent, *args, **kwargs)

        if (title == None):
            title = type(parent).__name__ + " Wizard"
        self.title(title)

        if (icon == None):
            icon = GetResourcePath('.\\Resources\\keystone.ico')
        if (icon != None):
            self.iconbitmap(icon)

        self.Frame = KeystoneFrame(self)

        self.Pages = None
        self.CurrentPage = None

        self.PageIndex = tk.IntVar(value=0)
        self.PageIndex.trace("w", self.ShowPage)

        #callbacks
        self.OnBackCallback = onBack
        self.OnNexCallback = onNext
        self.OnCloseCallback = onClose

        #setup grid
        self.rowconfigure(0, weight=1, minsize=200)
        self.columnconfigure(0, weight=1, minsize=400)
        self.Frame.columnconfigure(0, weight=0, minsize=50)
        self.Frame.columnconfigure(1, weight=1)
        self.Frame.columnconfigure(2, weight=0, minsize=50)
        self.Frame.columnconfigure(3, weight=1)
        self.Frame.columnconfigure(4, weight=0, minsize=50)
        self.Frame.rowconfigure(0, weight=1)
        self.Frame.rowconfigure(1, weight=0)

        #setup controls
        self.Frame.grid(row=0, column=0, sticky='nsew')

        self.Back = KeystoneButton(self.Frame,
                                   text="Back",
                                   command=self.OnBack)
        self.Back.Color('green', 'black')
        self.ShowBack = tk.BooleanVar(value=False)
        self.ShowBack.trace("w", self.OnShowBack)

        self.Next = KeystoneButton(self.Frame,
                                   text="Next",
                                   command=self.OnNext)
        self.Next.Color('green', 'black')
        self.ShowNext = tk.BooleanVar(value=False)
        self.ShowNext.trace("w", self.OnShowNext)

        self.Close = KeystoneButton(self.Frame,
                                    text="Close",
                                    command=self.OnClose)
        self.Close.Color('red', 'black')
        self.ShowClose = tk.BooleanVar(value=False)
        self.ShowClose.trace("w", self.OnShowClose)
    def __init__(self, parent, command: SlashCommand):
        KeystoneEditFrame.__init__(self, parent)

        #Frame for formatting controls
        self.FormatFrame = None

        #Frame for decscription
        self.DescriptionFrame = None

        #StringVar for command name
        self.CommandName = None

        #text entry object
        self.TextEntry = None

        #color entry objects
        self.ColorEntry = None
        self.BackgroundEntry = None
        self.BorderEntry = None

        #StringVar for transparency
        self.TransparencyEntryText = None

        #StringVar for scale
        self.ScaleEntryText = None

        #StringVar for repeat selection
        self.RepeatText = None

        #StringVar for duration
        self.DurationText = None

        #StringVar for power description text
        self.DescriptionText = None

        #The text prompt for the last selected command, e.g. "power" for powexec_name
        self.TextPrompt = None

        #layout grid and frames
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=0)
        self.rowconfigure(1, weight=0)
        self.rowconfigure(2, weight=1)
        commandFrame = KeystoneFrame(self)
        commandFrame.grid(row=0, column=0, sticky='nsew')
        commandFrame.columnconfigure(0, weight=0)
        commandFrame.columnconfigure(1, weight=1)
        commandFrame.columnconfigure(2, weight=0)
        commandFrame.columnconfigure(3, weight=0)
        self.FormatFrame = formatFrame = KeystoneFrame(self)
        self.DescriptionFrame = descriptionFrame = KeystoneFrame(self)

        #add controls
        self.CommandName = tk.StringVar()
        commandBox = KeystoneCombo(commandFrame, textvariable=self.CommandName, values=" ".join([ c[0] for c in LIST_OF_SLASH_COMMANDS]), postcommand=self.LockShowFormat)
        commandBox.grid(row=0, column=0, sticky="w", padx="3", pady="3")
        self.CommandName.trace("w", self.SelectCommand)
        self.CommandName.trace("w", self.SetDirty)

        self.TextEntry = KeystoneTextEntry(commandFrame)
        self.TextEntry.grid(row=0, column=1, sticky="nsew", padx="3", pady="3")     
        self.TextEntry.bind("<Key>", self.SetDirty)

        self.BrowseButton = KeystoneButton(commandFrame, text=" ... ", command=self.OnBrowseButton)
        self.NewButton = KeystoneButton(commandFrame, text="New", command=self.OnNewButton)
        self.IsLoadFileCommand = tk.BooleanVar()
        self.IsLoadFileCommand.set(False)
        self.IsLoadFileCommand.trace("w", self.OnSetIsLoadFileCommand)

        label = KeystoneLabel(formatFrame, text="Repeat Mode", anchor='n')
        label.grid(row=0, column=0, pady="3")
        repeatModes = [("Once", ""), ("Repeat [%s]" % REPEAT_STR, REPEAT_STR), ("Toggle [%s]" %TOGGLE_STR , TOGGLE_STR)]
        self.RepeatText = tk.StringVar()
        for idx, (text, mode) in enumerate(repeatModes):
            b = KeystoneRadio(formatFrame, text=text, value=mode, variable=self.RepeatText)
            b.grid(row=1+idx, column=0, sticky='w')
        self.RepeatText.set("")
        self.RepeatText.trace("w", self.SetDirty)

        editLabels = ["Text Color", "Background Color", "Transparency", "Border Color", "Scale", "Duration"]
        for idx, text in enumerate(editLabels):
            label = KeystoneLabel(formatFrame, text=text, anchor='n', width=30)
            if (idx < 3):
                row = 1
            else:
                row = 3
            label.grid(row=row, column=1+(idx % 3))

        self.ColorEntry = ColorPicker(formatFrame)
        self.ColorEntry.Combo.configure(postcommand=self.LockShowFormat)
        self.ColorEntry.grid(row=0, column=1, padx="3", pady="3")
        self.ColorEntry.ColorEntryText.trace("w", self.FormatText)

        self.BackgroundEntry = ColorPicker(formatFrame)
        self.BackgroundEntry.Combo.configure(postcommand=self.LockShowFormat)
        self.BackgroundEntry.grid(row=0, column=2, padx="3", pady="3")
        self.BackgroundEntry.ColorEntryText.trace("w", self.FormatText)

        self.TransparencyEntryText = tk.StringVar()
        self.TransparencyEntry = KeystoneCombo(formatFrame, textvariable=self.TransparencyEntryText, values=" ".join([str(p) for p in range(0,101)]), width=3, postcommand=self.LockShowFormat)
        self.TransparencyEntry.grid(row=0, column=3)
        self.TransparencyEntryText.trace("w", self.FormatText)

        self.BorderEntry = ColorPicker(formatFrame)
        self.BorderEntry.Combo.configure(postcommand=self.LockShowFormat)
        self.BorderEntry.grid(row=2, column=1, padx="3", pady="3")
        self.BorderEntry.ColorEntryText.trace("w", self.FormatText)

        self.ScaleEntryText = tk.StringVar()
        scaleEntry = KeystoneEntry(formatFrame, textvariable=self.ScaleEntryText, width=5)
        scaleEntry.grid(row=2, column=2)
        self.ScaleEntryText.trace("w", self.FormatText)

        self.DurationText = tk.StringVar()
        durationEntry = KeystoneEntry(formatFrame, textvariable=self.DurationText, width=5)
        durationEntry.grid(row=2, column=3)
        self.DurationText.trace("w", self.FormatText)

        self.DescriptionText = tk.StringVar()
        description = KeystoneLabel(descriptionFrame, anchor="nw", textvariable=self.DescriptionText, wraplength=800)
        description.grid(sticky="nsew", padx="3", pady="3")

        #load model
        self.Load(command)

        #bind to hide format and desc
        self.BindWidgetToShowFormat(self)
예제 #17
0
    def __init__(self,
                 parent,
                 resourceDir=None,
                 importCallback=None,
                 *args,
                 **kwargs):

        tk.Toplevel.__init__(self, parent, *args, **kwargs)
        self.maxsize(900, 700)
        self.attributes("-toolwindow", 1)
        self.attributes("-topmost", 1)

        icon = GetResourcePath('.\\Resources\\keystone.ico')
        if (icon != None):
            self.iconbitmap(icon)

        self.title("Some Key Binds...")

        #setup grid

        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)
        self.scroll = ScrollingFrame(self)
        self.scroll.grid(row=0, column=0, sticky='nsew')
        self.frame = KeystoneFrame(self.scroll.scrollwindow)
        self.frame.pack(fill=tk.BOTH, expand=1)
        self.frame.columnconfigure(0)
        self.frame.columnconfigure(1)
        self.frame.columnconfigure(2, weight=1)
        row = 0

        self.frame.grid(row=0, column=0, sticky='nsew')

        #get list of kst files from Resources
        if (resourceDir == None):
            self.ResourceDir = os.path.abspath(
                GetResourcePath('.\\Resources\\'))
        else:
            self.ResourceDir = resourceDir
        self.fileList = [
            f for f in os.listdir(self.ResourceDir) if f.endswith(".kst")
        ]
        self.buttons = []
        self.labels = []
        self.descriptions = []
        for filename in self.fileList:
            filePath = os.path.join(self.ResourceDir, filename)
            with open(filePath, "r") as json_file:
                data = json.load(json_file)
            self.buttons.append(
                KeystoneButton(self.frame,
                               text="Import",
                               command=lambda row=row: self.OnImportCallback(
                                   self.fileList[row])))
            self.buttons[-1].Color('yellow', 'black')
            self.buttons[-1].grid(row=row,
                                  column=0,
                                  sticky='nw',
                                  padx=3,
                                  pady=3)
            self.labels.append(KeystoneLabel(self.frame, text=filename))
            self.labels[-1].grid(row=row,
                                 column=1,
                                 sticky='new',
                                 padx=3,
                                 pady=3)
            self.descriptions.append(
                KeystoneMoreLabel(self.frame, text=data[DESCRIPTION]))
            self.descriptions[-1].grid(row=row, column=2, sticky='nsew')
            row = row + 1

        self.ImportCallback = importCallback
예제 #18
0
    def __init__(self, parent, constructor, *args, **kwargs):
        KeystoneFrame.__init__(self, parent)

        self.Parent = parent

        #layout grid
        self.columnconfigure(0, weight=0)
        self.columnconfigure(1, weight=1)
        self.columnconfigure(2, weight=0)
        self.rowconfigure(0, weight=0)
        self.rowconfigure(1, weight=1)
        self.rowconfigure(2, weight=0)

        #init show controls vars
        self.ShowControls = tk.BooleanVar()
        self.ShowControls.set(False)
        self.ShowControls.trace("w", self.OnShowControls)
        self.IsLast = tk.BooleanVar()
        self.IsLast.set(False)
        self.SelectMode = tk.BooleanVar()
        self.SelectMode.set(False)
        self.SelectMode.trace("w", self.OnSelectMode)

        #add controls
        self.TopInsert = tk.Button(self,
                                   text=self.INSERT_TEXT,
                                   background=self.INSERT_COLOR,
                                   foreground=self.INSERT_TEXT_COLOR,
                                   font=(TEXT_FONT, 7, "bold"),
                                   relief=self.INSERT_STYLE,
                                   height=1,
                                   pady=0,
                                   command=self.OnInsertAbove)
        self.BottomInsert = tk.Button(self,
                                      text=self.INSERT_TEXT,
                                      background=self.INSERT_COLOR,
                                      foreground=self.INSERT_TEXT_COLOR,
                                      font=(TEXT_FONT, 7, "bold"),
                                      relief=self.INSERT_STYLE,
                                      height=1,
                                      pady=0,
                                      command=self.OnInsertBelow)
        self.Delete = tk.Button(self,
                                text=self.DELETE_TEXT,
                                background=self.DELETE_COLOR,
                                foreground=self.DELETE_TEXT_COLOR,
                                font=(TEXT_FONT, 7, "bold"),
                                relief=self.DELETE_STYLE,
                                width=1,
                                wraplength=1,
                                command=self.OnDelete)
        self.Move = tk.Button(self,
                              text=self.MOVE_TEXT,
                              background=self.MOVE_COLOR,
                              foreground=self.MOVE_TEXT_COLOR,
                              font=(TEXT_FONT, 10, "bold"),
                              relief=self.MOVE_STYLE,
                              command=self.OnMove)
        self.Selected = tk.BooleanVar()
        self.Select = KeystoneCheckbutton(self, variable=self.Selected)
        self.Item = constructor(self, *args, **kwargs)
        self.Item.grid(column=1, row=1, sticky='nsew')

        #bind focus controls
        self.Focused = False
        self.bind("<FocusIn>", self._on_enter)
        self.bind("<FocusOut>", self._on_leave)

        #bind Dirty if available
        if isinstance(self.Item, KeystoneEditFrame):
            self.Item.OnSetDirty.append(parent.SetDirty)

        self.OnShowControls()
class KeystoneWizard(tk.Toplevel):
    def __init__(self,
                 parent,
                 title=None,
                 icon=None,
                 onBack=None,
                 onNext=None,
                 onClose=None,
                 *args,
                 **kwargs):

        #initialize
        tk.Toplevel.__init__(self, parent, *args, **kwargs)

        if (title == None):
            title = type(parent).__name__ + " Wizard"
        self.title(title)

        if (icon == None):
            icon = GetResourcePath('.\\Resources\\keystone.ico')
        if (icon != None):
            self.iconbitmap(icon)

        self.Frame = KeystoneFrame(self)

        self.Pages = None
        self.CurrentPage = None

        self.PageIndex = tk.IntVar(value=0)
        self.PageIndex.trace("w", self.ShowPage)

        #callbacks
        self.OnBackCallback = onBack
        self.OnNexCallback = onNext
        self.OnCloseCallback = onClose

        #setup grid
        self.rowconfigure(0, weight=1, minsize=200)
        self.columnconfigure(0, weight=1, minsize=400)
        self.Frame.columnconfigure(0, weight=0, minsize=50)
        self.Frame.columnconfigure(1, weight=1)
        self.Frame.columnconfigure(2, weight=0, minsize=50)
        self.Frame.columnconfigure(3, weight=1)
        self.Frame.columnconfigure(4, weight=0, minsize=50)
        self.Frame.rowconfigure(0, weight=1)
        self.Frame.rowconfigure(1, weight=0)

        #setup controls
        self.Frame.grid(row=0, column=0, sticky='nsew')

        self.Back = KeystoneButton(self.Frame,
                                   text="Back",
                                   command=self.OnBack)
        self.Back.Color('green', 'black')
        self.ShowBack = tk.BooleanVar(value=False)
        self.ShowBack.trace("w", self.OnShowBack)

        self.Next = KeystoneButton(self.Frame,
                                   text="Next",
                                   command=self.OnNext)
        self.Next.Color('green', 'black')
        self.ShowNext = tk.BooleanVar(value=False)
        self.ShowNext.trace("w", self.OnShowNext)

        self.Close = KeystoneButton(self.Frame,
                                    text="Close",
                                    command=self.OnClose)
        self.Close.Color('red', 'black')
        self.ShowClose = tk.BooleanVar(value=False)
        self.ShowClose.trace("w", self.OnShowClose)

    def LoadPages(self, pages: [KeystoneWizardPage]):
        if (self.CurrentPage != None):
            self.CurrentPage.grid_forget()
            self.CurrentPage = None
        self.Pages = pages
        for eachPage in pages:
            eachPage.Wizard = self
        self.PageIndex.set(0)

    def PageCount(self) -> int:
        if (self.Pages == None):
            return 0
        return len(self.Pages)

    def OnShowBack(self, *args):
        if (self.PageIndex.get() == 0):
            show = False
        else:
            show = self.ShowBack.get()
        if (show):
            self.Back.grid(column=0, row=1, sticky='nsew')
        else:
            self.Back.grid_forget()

    def OnShowNext(self, *args):
        if (self.PageIndex.get() == (self.PageCount() - 1)):
            show = False
        else:
            show = self.ShowNext.get()
        if (show):
            self.Next.grid(column=4, row=1, sticky='nsew')
        else:
            self.Next.grid_forget()

    def OnShowClose(self, *args):
        show = self.ShowClose.get()
        if (show):
            self.Close.grid(column=2, row=1, sticky='nsew')
        else:
            self.Close.grid_forget()

    def ShowPage(self, *args):

        if (self.PageCount() == 0):
            return

        #get index
        index = self.PageIndex.get()
        if (index >= self.PageCount()):
            index = self.PageCount() - 1
            self.PageIndex.set(index)
            return  #as set will callback due to trace
        elif (index < 0):
            index = 0
            self.PageIndex.set(index)
            return  #as set will callback due to trace

        #drop current page
        if (self.CurrentPage != None):
            self.CurrentPage.grid_forget()

        #show page and buttons
        page = self.Pages[index]
        page.grid(row=0, column=0, columnspan=5, sticky='nsew')
        self.CurrentPage = page
        self.ShowBack.set(page.AllowBack.get())
        self.ShowNext.set(page.AllowNext.get())
        self.ShowClose.set(page.AllowClose.get())

    def _onButton(self, callback, pageCallback, allowVar, showVar,
                  indexChange):
        if (pageCallback != None):
            pageCallback(self, self.CurrentPage)
        allow = allowVar.get()
        showVar.set(allow)
        index = self.PageIndex.get() + indexChange
        if (index > self.PageCount()):
            index = self.PageCount() - 1
        elif (index < 0):
            index = 0
        if (index != self.PageIndex.get()):
            self.PageIndex.set(index)
            if (callback != None):
                callback(self)

    def OnBack(self, *args):
        page = self.CurrentPage
        self._onButton(self.OnBackCallback, page.OnBack, page.AllowBack,
                       self.ShowBack, -1)

    def OnNext(self, *args):
        page = self.CurrentPage
        self._onButton(self.OnNexCallback, page.OnNext, page.AllowClose,
                       self.ShowClose, 1)

    def OnClose(self, *args):
        page = self.CurrentPage
        if (page.OnClose != None):
            page.OnClose(self)
        if (page.AllowClose.get()):
            self.destroy()
        if (self.OnCloseCallback != None):
            self.OnCloseCallback(self)
예제 #20
0
class BindEditor(KeystoneEditFrame):

    DELETE_TEXT = 'UNBIND'
    DELETE_COLOR = 'black'
    DELETE_TEXT_COLOR = 'red'
    DELETE_STYLE = tk.FLAT

    ASSIGN_TEXT = 'BIND'
    UNASSIGN_TEXT = 'Unassign Bind'
    UNASSIGN_MESSAGE = 'Include no assignment?  Use "nop" to  assign a key to do nothing.  Use /unbind <key> to restore a default in the UI'
    DEFAULT_TEXT = 'Default Bind'
    DEFAULT_COLOR = 'yellow'
    DEFAULT_TEXT_COLOR = 'black'
    CANCEL_TEXT = 'Cancel'
    ASSIGN_COLOR = 'black'
    ASSIGN_TEXT_COLOR = 'green'

    def SetKeyDescription(self, keyVar: tk.StringVar, descVar: tk.StringVar,
                          list):
        keyName = keyVar.get()
        key = MatchKeyName(keyName, list)
        if (key != None):
            desc = key[2]
            altname = key[1]
            if ((desc == '') and (altname != '')):
                desc = altname
            descVar.set(desc)
        else:
            descVar.set('')

    def SelectKey(self, *args):
        self.SetKeyDescription(self.Key, self.KeyDescription, KEY_NAMES)

    def SelectChord(self, *args):
        self.SetKeyDescription(self.Chord, self.ChordDescription, CHORD_KEYS)

    def AssignCommand(self, *args):
        model = Bind(key=self.Key.get(),
                     chord=self.Chord.get(),
                     commands=[SlashCommand(repr=DEFAULT_COMMAND)])
        self.Load(model)
        self.SetDirty()

    def UnassignCommand(self, *args):
        text = args[0]
        if (text == self.UNASSIGN_TEXT):
            self.ShowCommands.set(False)
            self.SetDirty()
        elif (text == self.DEFAULT_TEXT):
            bind = GetDefaultBindForKey(self.Key.get(), self.Chord.get())
            self.Commands.Load(SlashCommandEditor, bind.Commands,
                               SlashCommand(repr=DEFAULT_COMMAND))
            self.ShowCommands.set(True)
            self.SetDirty()
        else:  #Cancel
            self.ShowCommands.set(True)

    def OnDelete(self, *args):
        self.CommandsFrame.grid_forget()
        self.Delete.grid_forget()
        buttons = [self.UNASSIGN_TEXT, self.DEFAULT_TEXT, self.CANCEL_TEXT]
        colors = [[self.DELETE_TEXT_COLOR, self.DELETE_COLOR],
                  [self.DEFAULT_COLOR, self.DEFAULT_TEXT_COLOR],
                  [self.ASSIGN_TEXT_COLOR, self.ASSIGN_COLOR]]
        results = [self.UNASSIGN_TEXT, self.DEFAULT_TEXT, self.CANCEL_TEXT]
        commands = [
            self.UnassignCommand, self.UnassignCommand, self.UnassignCommand
        ]
        unassignPrompt = KeystonePromptFrame(self,
                                             self.UNASSIGN_MESSAGE,
                                             buttons=buttons,
                                             colors=colors,
                                             results=results,
                                             commands=commands)
        unassignPrompt.grid(row=0, column=1, sticky='nsew')

    def OnShowCommands(self, *args):
        show = self.ShowCommands.get()
        if (show):
            self.Assign.grid_forget()
            self.Delete.grid(row=0, column=1, sticky='nsw')
            self.CommandsFrame.grid(row=0,
                                    column=2,
                                    sticky='nsew',
                                    padx="3",
                                    pady="3")
        else:
            self.Assign.grid(row=0, column=1, sticky='nsw')
            self.CommandsFrame.grid_forget()
            self.Delete.grid_forget()

    def OnShowTextEditor(self, *args):
        show = self.ShowTextEditor.get()
        if (show):
            self.Assign.grid_forget()
            self.Delete.grid_forget()
            self.KeyFrame.grid_forget()
            self.CommandsFrame.grid_forget()
            self.UIToTextButton.grid_forget()
            self.UnlockKeysButton.grid_forget()
            self.TextFrame.grid(row=0,
                                column=0,
                                rowspan="2",
                                columnspan="3",
                                sticky='nsew')
        else:
            self.TextFrame.grid_forget()
            self.KeyFrame.grid(row=0, column=0, sticky='nsew')
            if (self._lockKey):
                self.UIToTextButton.grid(row=1,
                                         column=1,
                                         columnspan="2",
                                         sticky="nsew",
                                         padx="3",
                                         pady="3")
                self.UnlockKeysButton.grid(row=1, column=0, sticky="sw")
            else:
                self.UIToTextButton.grid(row=1,
                                         column=0,
                                         columnspan="3",
                                         sticky="nsew",
                                         padx="3",
                                         pady="3")
            self.OnShowCommands()

    def UnlockKeys(self, unlock=True):
        if unlock:
            self._lockKey = False
            self.KeyBox.grid(row=1,
                             column=1,
                             sticky="nsew",
                             padx="3",
                             pady="3")
            self.ChordBox.grid(row=3,
                               column=1,
                               sticky="nsew",
                               padx="3",
                               pady="3")
            self.KeyValue.grid_forget()
            self.ChordValue.grid_forget()
            self.UnlockKeysButton.grid_forget()
        else:
            self._lockKey = True
            self.KeyBox.grid_forget()
            self.ChordBox.grid_forget()
            self.KeyValue.grid(row=1,
                               column=1,
                               sticky="nsew",
                               padx="3",
                               pady="3")
            self.ChordValue.grid(row=3,
                                 column=1,
                                 sticky="nsew",
                                 padx="3",
                                 pady="3")

    def Load(self, bind: Bind):
        self.Loading = True
        try:
            if (self._lockKey):
                self.TextEntry.SetText(bind.GetCommands())
            else:
                self.TextEntry.SetText(bind.__repr__())
            self.SynchTextToUI()
        finally:
            self.Loading = False
        self.SetClean(self)

    def SynchTextToUI(self):
        key = self.Key.get()
        chord = self.Chord.get()
        text = self.TextEntry.GetText()
        if (self._lockKey):
            text = "%s %s" % (FormatKeyWithChord(key, chord), text)
        bind = Bind(repr=text)
        if (key != bind.Key):
            self.Key.set(bind.Key)
        if (chord != bind.Chord):
            self.Chord.set(bind.Chord)
        if (bind.Commands != None):
            self.Commands.Load(SlashCommandEditor, bind.Commands,
                               SlashCommand(repr=DEFAULT_COMMAND))
            self.ShowCommands.set(True)
        else:
            self.ShowCommands.set(False)
        self.ShowTextEditor.set(False)

    def SynchUIToText(self):
        bind = self.GetBindFromUI()
        if (self._lockKey):
            self.TextEntry.SetText(bind.GetCommands())
        else:
            self.TextEntry.SetText(bind)
        self.ShowTextEditor.set(True)

    def GetBindFromUI(self) -> Bind:
        bind = Bind()
        if (self.ShowCommands.get()):
            bind.Commands = [item.Item.Get() for item in self.Commands.Items]
        else:
            bind.Commands = None
        bind.Key = self.Key.get()
        bind.Chord = self.Chord.get()
        return bind

    def Get(self) -> Bind:
        if (self.ShowTextEditor.get()):
            self.SynchTextToUI()
        model = self.GetBindFromUI()
        return model

    def __init__(self, parent, bind: Bind, lockKey=False, dirty=False):
        KeystoneEditFrame.__init__(self, parent)

        #StringVar for Key
        self.Key = None

        #StringVar for Chord
        self.Chord = None

        #StringVar for Key Description
        self.KeyDescription = None

        #StringVar for Chord Description
        self.ChordDescription = None

        #List of commands view frame
        self.Commands = None

        #Indicates keys cannot be edited
        self._lockKey = lockKey

        #layout grid
        self.columnconfigure(0, weight=1, minsize=200)
        self.columnconfigure(1, weight=0)
        self.columnconfigure(2, weight=7)
        self.rowconfigure(0, weight=1)

        #add controls

        self.KeyFrame = KeystoneFrame(self)
        self.KeyFrame.columnconfigure(1, weight=1)
        self.KeyFrame.columnconfigure(2, weight=0)
        self.KeyFrame.rowconfigure(4, weight=1)

        self.CommandsFrame = KeystoneFrame(self)
        self.CommandsFrame.columnconfigure(0, weight=1)

        self.Commands = FrameListView(self.CommandsFrame)
        self.Commands.OnSetDirty.append(self.SetDirty)
        self.Commands.grid(row=0, column=0, sticky='new')

        self.TextFrame = KeystoneFrame(self)
        self.TextFrame.rowconfigure(0, weight=1, minsize='55')
        self.TextFrame.columnconfigure(0, weight=1, minsize='405')

        self.Delete = tk.Button(self,
                                text=self.DELETE_TEXT,
                                background=self.DELETE_COLOR,
                                foreground=self.DELETE_TEXT_COLOR,
                                font=(TEXT_FONT, 7, "bold"),
                                relief=self.DELETE_STYLE,
                                width=1,
                                wraplength=1,
                                command=self.OnDelete)

        self.Assign = tk.Button(self,
                                text=self.ASSIGN_TEXT,
                                background=self.ASSIGN_COLOR,
                                foreground=self.ASSIGN_TEXT_COLOR,
                                font=(TEXT_FONT, 7, "bold"),
                                relief=self.DELETE_STYLE,
                                width=1,
                                wraplength=1,
                                command=self.AssignCommand)

        self.UIToTextButton = KeystoneButton(self,
                                             text="Edit As Text",
                                             command=self.SynchUIToText)

        keyLabel = KeystoneLabel(self.KeyFrame,
                                 anchor='nw',
                                 text="Key",
                                 width=5)
        keyLabel.grid(row=1, column=0, sticky="nw", padx="3", pady="3")
        self.Key = tk.StringVar()
        self.KeyValue = KeystoneLabel(self.KeyFrame,
                                      anchor='nw',
                                      textvariable=self.Key,
                                      width=5)
        self.KeyBox = KeystoneKeyCombo(self.KeyFrame,
                                       textvariable=self.Key,
                                       values=" ".join(
                                           [c[0] for c in KEY_NAMES]))
        self.Key.trace("w", self.SelectKey)

        self.KeyDescription = tk.StringVar()
        keyDescription = KeystoneLabel(self.KeyFrame,
                                       anchor="nw",
                                       textvariable=self.KeyDescription,
                                       wraplength=200)
        keyDescription.grid(row=2,
                            column=0,
                            columnspan=2,
                            sticky="nsew",
                            padx="3",
                            pady="3")

        self.Key.set(bind.Key)
        self.Key.trace("w", self.SetDirty)

        chordLabel = KeystoneLabel(self.KeyFrame,
                                   anchor='nw',
                                   text="Chord",
                                   width=5)
        chordLabel.grid(row=3, column=0, sticky="nw", padx="3", pady="3")
        self.Chord = tk.StringVar()
        self.ChordValue = KeystoneLabel(self.KeyFrame,
                                        anchor='nw',
                                        textvariable=self.Chord,
                                        width=5)
        self.ChordBox = KeystoneKeyCombo(self.KeyFrame,
                                         textvariable=self.Chord,
                                         values=" ".join(
                                             [c[0] for c in CHORD_KEYS]))
        self.Chord.trace("w", self.SelectChord)

        self.ChordDescription = tk.StringVar()
        chordDescription = KeystoneLabel(self.KeyFrame,
                                         anchor="nw",
                                         textvariable=self.ChordDescription,
                                         wraplength=200)
        chordDescription.grid(row=4,
                              column=0,
                              columnspan=2,
                              sticky="nsew",
                              padx="3",
                              pady="3")

        self.Chord.set(bind.Chord)
        self.Chord.trace("w", self.SetDirty)

        self.UnlockKeysButton = KeystoneButton(self,
                                               text="Change Assigned Key",
                                               command=self.UnlockKeys)
        self.UnlockKeysButton.Color(FOREGROUND, BACKGROUND)

        self.ShowCommands = tk.BooleanVar()
        self.ShowCommands.trace("w", self.OnShowCommands)

        self.TextEntry = KeystoneTextEntry(self.TextFrame, height=5)
        self.TextEntry.grid(row=0, column=0, sticky="nsew", padx="3", pady="3")
        self.TextEntry.bind("<Key>", self.SetDirty)

        self.ShowTextEditor = tk.BooleanVar()
        self.ShowTextEditor.set(False)
        self.ShowTextEditor.trace("w", self.OnShowTextEditor)

        self.TextToUIButton = KeystoneButton(self.TextFrame,
                                             text="Editor",
                                             command=self.SynchTextToUI)
        self.TextToUIButton.grid(row=1,
                                 column=0,
                                 sticky="nsew",
                                 padx="3",
                                 pady="3")

        self.OnShowTextEditor()
        self.UnlockKeys(not lockKey)

        self.Load(bind)
        self.Dirty.set(dirty)