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)
def test_FrameListView(self): win = tk.Tk() constructor = TestFrame args = ("1", "2", "3") view = FrameListView(win) view.Load(constructor, args, "X") view.pack(anchor='n', fill=tk.BOTH, expand=True, side='left') #tk.mainloop() win.destroy()
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)
def test_FrameListViewSelectMode(self): win = tk.Tk() constructor = TestFrame args = ("1", "2", "3") view = FrameListView(win, selectMode = True) view.Load(constructor, args, "X") view.pack(anchor='n', fill=tk.BOTH, expand=True, side='left') #tk.mainloop() result = [p.Text.get() for p in view.GetSelected()] print(result) win.destroy()
def test_FrameListViewMoves(self): win = tk.Tk() constructor = TestFrame args = ("1", "2", "3") view = FrameListView(win) view.Load(constructor, args, "X") view.pack(anchor='n', fill=tk.BOTH, expand=True, side='left') view.Insert(2, FrameListViewItem(view, TestFrame, "A")) view.Insert(3, FrameListViewItem(view, TestFrame, "B")) view.Insert(4, FrameListViewItem(view, TestFrame, "C")) actual = [item.Item.Text.get() for item in view.Items] expected = ['1', '2', 'A', 'B', 'C', '3'] self.assertEqual(str(actual), str(expected), "Insert of items mid list failed") view.MovingObject = view.Items[2] view.MoveOrCreate(view.Items[0]) actual = [item.Item.Text.get() for item in view.Items] expected = ['A', '1', '2', 'B', 'C', '3'] self.assertEqual(str(actual), str(expected), "Move of item to start of list failed") view.MovingObject = view.Items[0] view.MoveOrCreate(view.Items[5]) actual = [item.Item.Text.get() for item in view.Items] expected = ['1', '2', 'B', 'C', 'A', '3'] self.assertEqual(str(actual), str(expected), "Move of item to before end of list failed") view.MovingObject = view.Items[4] view.MoveOrCreate(view.Items[5], True) actual = [item.Item.Text.get() for item in view.Items] expected = ['1', '2', 'B', 'C', '3', 'A'] self.assertEqual(str(actual), str(expected), "Move of item to end of list failed") view.MovingObject = view.Items[-1] view.MoveOrCreate(view.Items[4]) actual = [item.Item.Text.get() for item in view.Items] expected = ['1', '2', 'B', 'C', 'A', '3'] self.assertEqual(str(actual), str(expected), "Move of item to middle of list failed") view.MovingObject = None view.MoveOrCreate(view.Items[-1], True) actual = [item.Item.Text.get() for item in view.Items] expected = ['1', '2', 'B', 'C', 'A', '3', 'X'] self.assertEqual(str(actual), str(expected), "Add of item to end of list failed") view.Remove(view.Items[-1]) view.Remove(view.Items[4]) view.Remove(view.Items[3]) view.Remove(view.Items[2]) actual = [item.Item.Text.get() for item in view.Items] expected = ['1', '2', '3'] self.assertEqual(str(actual), str(expected), "Removing items failed") win.destroy()
class EditBindFile(KeystoneEditFrame): def ShowSaveButtons(self, *args): if (self.LoadedFile == None): return self.SaveButton.grid(row=0, column=1, sticky='nse') if (self.FilePath != None): self.CancelButton.grid(row=0, column=2, sticky='nse') def HideSaveButtons(self, *args): self.SaveButton.grid_forget() self.CancelButton.grid_forget() def Load(self, bindFile): self.LoadedFile = bindFile.Clone() self.Loading = True try: if (self.LoadedFile.Binds != None): binds = [] if (self.List.get()): binds = self.LoadedFile.Binds else: #load in expeded order chords = [''] for chord, altname, desc in CHORD_KEYS: dummy = altname dummy = desc chords.append(chord) for key, altname, desc in KEY_NAMES: dummy = altname dummy = desc for chord in chords: keyBinds = self.LoadedFile.GetBindForKey( key, chord) if (len(keyBinds) > 0): binds.append(keyBinds[0]) #load anything in the file we didn't match at the end for bind in self.LoadedFile.Binds: loaded = [ b for b in binds if (bind.GetKeyWithChord( defaultNames=True) == b.GetKeyWithChord( defaultNames=True)) ] if (len(loaded) == 0): binds.append(bind) self.view.Load(BindListItem, binds, Bind(repr=DEFAULT_BIND)) finally: self.Loading = False self.FilePath = self.LoadedFile.FilePath if (self.FilePath == None): self.PathLabel.configure(text="") else: self.PathLabel.configure(text=self.FilePath) if (os.path.exists(self.FilePath)): self.SetClean(self) else: self.SetDirty(self) self.OnLinkedFilesFound() def NewBindCallback(self, result, bind, moving=None): self.Editor = None if (result): insertIndex = None replaceItem = None newKey = bind.Key newChord = bind.Chord if (self.view.Items == None): self.view.Items = [] #find place in list index = -1 itemsInList = [ (idx, str.upper(FormatKeyWithChord(bind.Key, bind.Chord))) for idx, bind in [(idx, item.Item.Get()) for idx, item in enumerate(self.view.Items)] ] newKeyWithChord = str.upper(FormatKeyWithChord(newKey, newChord)) chords = [''] for chord, altname, desc in CHORD_KEYS: dummy = altname dummy = desc chords.append(chord) for key, altname, desc in KEY_NAMES: dummy = altname dummy = desc for chord in chords: keyWithChord = str.upper(FormatKeyWithChord(key, chord)) match = [(idx, listedKeyWithChord) for idx, listedKeyWithChord in itemsInList if listedKeyWithChord == keyWithChord] if (len(match) > 0): #this key is in binds index = match[0][0] #we are overwriting it matchKeyWithChord = match[0][1] if (matchKeyWithChord == newKeyWithChord): replaceItem = self.view.Items[index] insertIndex = index break if (keyWithChord == newKeyWithChord): #this is our spot insertIndex = index + 1 break if (insertIndex != None): break if (replaceItem != None): response = messagebox.askokcancel( "Existing Bind", "Overwrite the existing bind for %s\n\n%s\n\nwith the new bind\n\n%s?" % (newKeyWithChord, replaceItem.Item.Get(), bind)) if (response): self.view.Remove(replaceItem) else: if (moving == None): title = 'New Bind' self.Editor = EditBindWindow(self, self.NewBindCallback, bind, title=title, dirty=True) else: title = moving.Item.Get().GetKeyWithChord() moving.Item.Button.Color(FOREGROUND, BACKGROUND) moving.Item.Editor = EditBindWindow( moving.Item, moving.Item.EditorCallback, bind, title=title, dirty=True) return if (moving != None): #remapping rather than inserting new movingIndex = self.view.GetIndex(moving) if (movingIndex >= 0): self.view.Remove(moving) if (movingIndex < insertIndex): insertIndex = insertIndex - 1 self.view.Insert( insertIndex, FrameListViewItem(self.view, BindListItem, bind, True)) if (bind.IsLoadFileBind()): self.OnLinkedFilesFound(binds=[bind]) def OnNewBind(self, *args): if (self.Editor == None): self.Editor = EditBindWindow(self, self.NewBindCallback) def Get(self) -> BindFile: binds = None if (self.view.Items != None): binds = [ bind for bind in [item.Item.Get() for item in self.view.Items] if bind.Commands != None ] return BindFile(binds=binds, filePath=self.FilePath) def OnSave(self, *args): if ((self.FilePath == None) or (self.FilePath == '')): filePath = self.PromptForFilePath() if (filePath == ''): return else: filePath = self.FilePath model = self.Get() self.DoWork(target=self._write, args=( model, filePath, )) self.FilePath = filePath self.SetClean(self) if (self.OnSaveCallback != None): self.OnSaveCallback(self) def OnCancel(self, *args): self.Load(self.LoadedFile) def _read(self, filePath): self._readFile = ReadBindsFromFile(filePath) def _write(self, model, filePath): model.WriteBindsToFile(filePath) def OnLinkedFilesFound(self, binds=None, *args): if (binds == None): binds = self.Get().GetLoadFileBinds() for bind in binds: for command in bind.GetLoadFileCommands(): targetPath = command.GetTargetFile() TriggerOpenLinkedFileCallback(targetPath, bind, source=self) def Open(self, fileName=None): if (fileName == None): options = {} if (self.LoadedFile != None): filePath = self.LoadedFile.FilePath else: filePath = None 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 fileName = filedialog.askopenfilename(**options) if (fileName != ''): self.DoWork(target=self._read, args=(fileName, )) self.Load(self._readFile) self._readFile = None def New(self, defaults: bool = False): file = NewBindFile(defaults) self.Load(file) self.SetDirty(self) def PromptForFilePath(self) -> str: if (self.LoadedFile == None): return '' options = {} options['initialfile'] = "keybinds.txt" options['title'] = "Save Keybind File As" options['filetypes'] = (("Text Files", "*.txt"), ("All Files", "*.*")) options['defaultextension'] = "txt" filePath = filedialog.asksaveasfilename(**options) return filePath def Save(self, promptForPath: bool = False): if (promptForPath): filePath = self.PromptForFilePath() if (filePath == ''): return self.OnSave() def OnOkSelect(self, *args): close = True if (self.OnSelectCallback != None): selected = [b.Get() for b in self.view.GetSelected()] if (len(selected) > 0): close = self.OnSelectCallback(selected) if (close): self.SetSelectMode(False) def OnCancelSelect(self, *args): self.SetSelectMode(False) def AddUploadBind(self, *args): if (self.FilePath == None): return path = os.path.abspath(self.FilePath) bind = None dirty = False #find current biind loadBinds = [ bind for bind in [item.Item.Get() for item in self.view.Items] if bind.IsLoadFileBind() ] for loadBind in loadBinds: loadCommands = loadBind.GetLoadFileCommands() for command in loadCommands: boundPath = command.GetTargetFile() if (boundPath == path): bind = loadBind break if (bind != None): break if (bind == None): bind = Bind(repr=DEFAULT_LOAD_BIND % path) dirty = True if (self.Editor == None): self.Editor = EditBindWindow(self, self.NewBindCallback, bind=bind, dirty=dirty) def SetSelectMode(self, set=False): if (set != self.SelectMode): self.SelectMode = set self.view.SelectMode.set(set) if (self.view.Items != None): for item in [item.Item for item in self.view.Items]: item.ShowEditButton(not set) if (set): self.NewBindButton.grid_forget() self.OkSelectButton.grid(row=0, column=1, sticky='nse') self.CancelSelectButton.grid(row=0, column=2, sticky='nse') else: self.NewBindButton.grid(row=0, column=3, sticky='nse') self.OkSelectButton.grid_forget() self.CancelSelectButton.grid_forget() def __init__(self, parent, bindFile: BindFile = None, list=False, showUploadBindButton=False, onSaveCallback=None, onSelectCallback=None): KeystoneEditFrame.__init__(self, parent) self.OnSetDirty.append(self.ShowSaveButtons) self.OnSetClean.append(self.HideSaveButtons) self.SaveButton = None self.CancelButton = None self.SelectMode = False self.OnSelectCallback = onSelectCallback self.columnconfigure(0, weight=1) self.columnconfigure(1, weight=0) self.columnconfigure(2, weight=0) self.columnconfigure(3, weight=0) self.columnconfigure(4, weight=0) self.columnconfigure(5, weight=0) self.rowconfigure(0, weight=0) self.rowconfigure(1, weight=1) self.PathLabel = KeystoneLabel(self) self.PathLabel.grid(row=0, column=0, sticky='nsew') self.SaveButton = KeystoneButton(self, text="Save", command=self.OnSave) self.SaveButton.Color("green", "black") self.CancelButton = KeystoneButton(self, text="Cancel", command=self.OnCancel) self.CancelButton.Color("red", "black") self.NewBindButton = KeystoneButton(self, text="New Bind", command=self.OnNewBind) self.NewBindButton.Color("yellow", "black") self.NewBindButton.grid(row=0, column=3, sticky='nse') self.OkSelectButton = KeystoneButton(self, text="Select", command=self.OnOkSelect) self.OkSelectButton.Color("green", "black") self.CancelSelectButton = KeystoneButton(self, text="Cancel", command=self.OnCancelSelect) self.CancelSelectButton.Color("red", "black") if (showUploadBindButton): self.UploadBindButton = KeystoneButton(self, text="Add Upload Bind", command=self.AddUploadBind) self.UploadBindButton.Color("orange", "black") self.UploadBindButton.grid(row=0, column=4, sticky='nse') scrollingFrame = ScrollingFrame(self) scrollingFrame.grid(row=1, column=0, columnspan=5, sticky='nsew') self.view = FrameListView(scrollingFrame.scrollwindow, showControlsOnFocus=(list)) self.view.pack(fill=tk.BOTH, expand=1) self.view.OnSetDirty.append(self.SetDirty) self.List = tk.BooleanVar() self.List.set(list) self.Editor = None self.OnSaveCallback = onSaveCallback self.FilePath = None self.LoadedFile = None if (bindFile != None): self.Load(bindFile)
def __init__(self, parent, bindFile: BindFile = None, list=False, showUploadBindButton=False, onSaveCallback=None, onSelectCallback=None): KeystoneEditFrame.__init__(self, parent) self.OnSetDirty.append(self.ShowSaveButtons) self.OnSetClean.append(self.HideSaveButtons) self.SaveButton = None self.CancelButton = None self.SelectMode = False self.OnSelectCallback = onSelectCallback self.columnconfigure(0, weight=1) self.columnconfigure(1, weight=0) self.columnconfigure(2, weight=0) self.columnconfigure(3, weight=0) self.columnconfigure(4, weight=0) self.columnconfigure(5, weight=0) self.rowconfigure(0, weight=0) self.rowconfigure(1, weight=1) self.PathLabel = KeystoneLabel(self) self.PathLabel.grid(row=0, column=0, sticky='nsew') self.SaveButton = KeystoneButton(self, text="Save", command=self.OnSave) self.SaveButton.Color("green", "black") self.CancelButton = KeystoneButton(self, text="Cancel", command=self.OnCancel) self.CancelButton.Color("red", "black") self.NewBindButton = KeystoneButton(self, text="New Bind", command=self.OnNewBind) self.NewBindButton.Color("yellow", "black") self.NewBindButton.grid(row=0, column=3, sticky='nse') self.OkSelectButton = KeystoneButton(self, text="Select", command=self.OnOkSelect) self.OkSelectButton.Color("green", "black") self.CancelSelectButton = KeystoneButton(self, text="Cancel", command=self.OnCancelSelect) self.CancelSelectButton.Color("red", "black") if (showUploadBindButton): self.UploadBindButton = KeystoneButton(self, text="Add Upload Bind", command=self.AddUploadBind) self.UploadBindButton.Color("orange", "black") self.UploadBindButton.grid(row=0, column=4, sticky='nse') scrollingFrame = ScrollingFrame(self) scrollingFrame.grid(row=1, column=0, columnspan=5, sticky='nsew') self.view = FrameListView(scrollingFrame.scrollwindow, showControlsOnFocus=(list)) self.view.pack(fill=tk.BOTH, expand=1) self.view.OnSetDirty.append(self.SetDirty) self.List = tk.BooleanVar() self.List.set(list) self.Editor = None self.OnSaveCallback = onSaveCallback self.FilePath = None self.LoadedFile = None if (bindFile != None): self.Load(bindFile)
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)
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)