diff --git a/src/multi_clipboard.ahk b/src/multi_clipboard.ahk deleted file mode 100644 index c44e1c4..0000000 --- a/src/multi_clipboard.ahk +++ /dev/null @@ -1,186 +0,0 @@ -;=================================================================================================== -; Multi_Clipboard -; GroggyOtter - 20230502 -;=================================================================================================== -; Customizeable multi-clipboard script -; Allows number bar, numpad, or function keys to be used. -; Modifier keys are used to either copy, paste, or view a key's clipboard -; -; === Usage === -; Treats a numberset as multiple virtual clipboard that you can copy to, paste from, and display -; Example:input_mode is 1, copy_hotkey is ^, paste_hotkey is -class multi_clipboard { ; Make a class to bundle our properties (variables) and methods (functions) - #Requires AutoHotkey 2.0+ ; Always define ahk version - - ; User settings - static input_mode := 2 ; Set numberset to use: 0 = 0-9, 1 = Numpad0-Numpad9, 2 = F1-F12 - static quick_view := 0 ; Set to true to close clipview on key release - - static copy_hotkey := '^' ; Modifier key to make a key copy - static paste_hotkey := '!' ; Modifier key to make a key paste - static show_hotkey := '#' ; Modifier key to show key contents - static all_hotkey := '^NumpadEnter' ; Hotkey to show all keys - - static input_mode_str => !this.input_mode ? 'Function' - : this.input_mode = 1 ? 'Numpad' - : 'Number Bar' - static __New() { ; Run at script startup - this.clip_dat := Map() ; Create clip_dat map to store all clipboard data - this.gui := 0 ; Initialize gui - this.mod_map := Map('copy' ,this.copy_hotkey ; Make map for hotkey creation - ,'paste',this.paste_hotkey - ,'show' ,this.show_hotkey) - this.verify_mod_map() ; Warn user of any duplicate maps - - obm := ObjBindMethod(this, 'show', '') ; Create a show all boundfunc to fire on keypress - ,Hotkey('*' this.all_hotkey, obm) ; Create hotkey with obm - - times := this.input_mode = 2 ? 12 : 10 ; Set loop to 10 times or 12 if function mode - loop times { ; Loop once for each key number - num := A_Index - (this.input_mode = 2 ? 0 : 1) ; Minus 1 for non function keys so they start at 0 - ,prfx := !this.input_mode ? '' : (this.input_mode = 1) ? 'Numpad' : 'F' ; Set prefix > 0 = none, 1 = NumPad, 2 = F - ,this.make_hotkey(num, prfx) ; Create hotkey - } - } - - static make_hotkey(num, prfx) { - num_shift := Map(0,'Ins' ,1,'End' ,2,'Down' ,3,'PgDn' ,4,'Left' ; Used with numpad keys to create shift variants - ,5,'Clear' ,6,'Right' ,7,'Home' ,8,'Up' ,9,'PgUp') - - for method, hk_mod in this.mod_map { ; Loop through copy/paste/show methods and mods - obm := ObjBindMethod(this, method, num) ; Make BoundFunc to run when copy/paste/show pressed - ,Hotkey('*' hk_mod prfx num, obm) ; Creates copy/paste/show in both numpad and shift+numpad variants - ,this.clip_dat[num] := '' ; Initialize all clipboard slots as empty strings - ,(this.input_mode = 1) ? Hotkey('*' hk_mod prfx num_shift[num], obm) : 0 ; If numpad, make a shift variant hotkey - } - } - - static copy(index, *) { ; Method to call when copying data - bak := ClipboardAll() ; Backup current clipboard contents - ,A_Clipboard := '' ; Clear clipboard - ,SendInput('^c') ; Send copy - ,ClipWait(1, 1) ; Wait up to 1 sec for clipboard to contain something - ,this.clip_dat[index] := this.is_str(A_Clipboard) ? A_Clipboard : ClipboardAll() ; Save string/bin data to clip_dat - ,A_Clipboard := bak ; Finally, restore the original clipboard contents - } - - static paste(index, *) { ; Method to call when pasting saved data - bak := ClipboardAll() ; Backup current clipboard contents - ,A_Clipboard := this.clip_dat[index] ; Put saved data back onto clipboard - ,SendInput('^v') ; Paste - loop 10 ; Wait up to 1 second for clipboard to not be in use - Sleep(100) - Until !DllCall('GetOpenClipboardWindow') ; Break if clipboard not in use - A_Clipboard := bak ; Finally, restore the original clipboard contents - } - - static show(index:='', hk:='', *) { ; Method to show contents of clip_dat - str := '' ; String to display - - switch this.input_mode { ; Get key type using input_mode - case 0: typ := 'Number ' - case 1: typ := 'Numpad' - case 2: typ := 'F' - } - - if (index != '') ; If key not blank, clipboard was specified - str .= this.format_line(index, typ) ; Get that key's clipboard info - else ; Else if key was blank, get all clipboards - for index, dat in this.clip_dat ; Loop through clip_dat - str .= this.format_line(index, typ) '`n`n' ; Format each clipboard - - title := [] - this.make_gui(RTrim(str, '`n'), title) ; Trim text and make a gui to display it - - If this.quick_view ; If quick view is enabled - KeyWait(this.strip_mods(hk)) ; Halt code here until hotkey is released - ,this.destroy_gui() ; Destroy gui after key release - return - } - - static format_line(index, typ) { ; Formats clipboard text for display - dat := this.clip_dat[index] ; Get clipboard data - ,header := '[' typ index '] ========================================`n`n' ; Format header - ,str := (dat = '') ? txt := '' ; Mark empty clipboard slot - : this.is_str(dat) ? dat ; Else if string, show data - : '`n Size: ' dat.Size '`n Pointer: ' dat.Ptr ; Else show size and pointer of binary data - return header str - } - - static make_gui(str, title) { ; Create a gui to display text - if this.HasOwnProp('gui') ; Check if a gui already exists - this.destroy_gui() ; If yes, get rid of it - - ; Set default values - m := 10 ; Choose default margin size - ,edt := {h:A_ScreenHeight*0.7, w:A_ScreenWidth*0.3} ; Make popup 40%/70% for screen width/height - ,btn := {w:edt.w, h:30} ; Set btn width to edit box width and 30 px high - ; Make GUI - goo := Gui() ; Make main gui object - ,goo.title := this.input_mode_str ' Keys - ' A_ScriptName ; Set the title to show - ,goo.MarginX := goo.MarginY := m ; Set default margins > Useful for spacing - ,goo.BackColor := 0x101010 ; Make main gui dark - ,goo.OnEvent('Close', (*) => goo.Destroy()) ; On gui close, destroy it - ,goo.OnEvent('Escape', (*) => goo.Destroy()) ; On escape press, destroy it - ,goo.SetFont('s10', 'Consolas') ; Default font values - ; Edit box - opt := ' ReadOnly -Wrap +0x300000 -WantReturn -WantTab' ; Edit control options - ,goo.AddEdit('xm ym w' edt.w ' h' edt.h opt, str) ; Add edit control to gui - ,goo.close := goo.AddButton('xm y+' m ' w' btn.w ' h' btn.h, 'Close') ; Add an large close button - ,goo.close.OnEvent('Click', (*) => goo.Destroy()) ; When it's clicked, destroy gui - ,goo.close.Focus() ; Now close button the focused control - ; Finish up - obm := ObjBindMethod(this, "WM_MOUSEMOVE") ; Boundfunc to run with OnMessage - ,OnMessage(0x200, obm) ; When gui detects mouse movement (0x200), run boundfunc - ,this.gui := goo ; Save gui to class for later use - ,this.gui.Show() ; And show gui - } - - ; https://learn.microsoft.com/en-us/windows/win32/inputdev/wm-mousemove - ; Allows click+drag movement on non-elements - static WM_MOUSEMOVE(wparam, lparam, msg, hwnd) { ; Function that runs on gui mouse move - static WM_NCLBUTTONDOWN := 0xA1 ; Message for left clicking on a window's titlebar - if (wparam = 1) ; If Left Mouse is down - PostMessage(WM_NCLBUTTONDOWN, 2,,, "ahk_id " hwnd) ; Tell windows left click is down on the title bar - } - - static destroy_gui() { ; Destroys current gui - try this.gui.destroy() ; Try suppresses errors if gui doesn't exist - } - - static strip_mods(txt) { ; Used to remove modifiers from hotkey strings - loop parse '^!#+*<>~$' ; Go through each modifier - if SubStr(txt, -1) != A_LoopField ; Last char can't match or the symbol is the literal key - txt := StrReplace(txt, A_LoopField) ; Otherwise remove it - return txt ; Return neutered hotkey - } - - static verify_mod_map() { ; Warns user of duplicate key assignments - for meth1, mod1 in this.mod_map - for meth2, mod2 in this.mod_map - if StrCompare(mod1, mod2) && !StrCompare(meth1, meth2) - throw Error('Duplicate modifiers found in mod_map', A_ThisFunc - ,'`n' meth1 ':' mod1 '`n' meth2 ':' mod2) - } - - static is_str(value) { ; Function to determine if data can be stored as a string - return !IsSet(value) ? 0 : InStr('String,Number', Type(value)) ; If value type is string or number, return true - } -}