From 01190f5a9a2831cb45af51a56bdbc026bb9f48a9 Mon Sep 17 00:00:00 2001 From: g0nzo83 <83645983+g0nzo83@users.noreply.github.com> Date: Sun, 11 Feb 2024 07:47:20 +0100 Subject: [PATCH] Initial commit --- Icon-Suspend.ico | Bin 0 -> 51478 bytes Icon.ico | Bin 0 -> 135155 bytes Lib/DefaultJSON.ahk | 73 ++++ Lib/LiveThumb.ahk | 330 +++++++++++++++++ Lib/json.ahk | 158 ++++++++ Main.ahk | 153 ++++++++ README.MD | 154 ++++++++ src/Main_Class.ahk | 730 ++++++++++++++++++++++++++++++++++++ src/Propertys.ahk | 600 ++++++++++++++++++++++++++++++ src/Settings_Gui.ahk | 862 +++++++++++++++++++++++++++++++++++++++++++ src/ThumbWindow.ahk | 410 ++++++++++++++++++++ src/TrayMenu.ahk | 93 +++++ 12 files changed, 3563 insertions(+) create mode 100644 Icon-Suspend.ico create mode 100644 Icon.ico create mode 100644 Lib/DefaultJSON.ahk create mode 100644 Lib/LiveThumb.ahk create mode 100644 Lib/json.ahk create mode 100644 Main.ahk create mode 100644 README.MD create mode 100644 src/Main_Class.ahk create mode 100644 src/Propertys.ahk create mode 100644 src/Settings_Gui.ahk create mode 100644 src/ThumbWindow.ahk create mode 100644 src/TrayMenu.ahk diff --git a/Icon-Suspend.ico b/Icon-Suspend.ico new file mode 100644 index 0000000000000000000000000000000000000000..bfddcb3416f95d7bcc9e176bd957893ddfb775d8 GIT binary patch literal 51478 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 literal 0 HcmV?d00001 diff --git a/Icon.ico b/Icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..52ab1b8ff9f250df09ff25f7386cc881a4fc0a0e GIT binary patch literal 135155 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 literal 0 HcmV?d00001 diff --git a/Lib/DefaultJSON.ahk b/Lib/DefaultJSON.ahk new file mode 100644 index 0000000..c89f465 --- /dev/null +++ b/Lib/DefaultJSON.ahk @@ -0,0 +1,73 @@ +default_JSON := " +( +{ + "global_Settings": { + "Suspend_Hotkeys_Hotkey": "", + "Global_Hotkeys": 1, + "LastUsedProfile": "Default", + "Minimize_Delay": 100, + "ThumbnailStartLocation": { + "x": 20, + "y": 20, + "width": 250, + "height": 140 + }, + "ThumbnailBackgroundColor":"#57504E", + "ThumbnailSnap": true, + "ThumbnailSnap_Distance": 20, + "ThumbnailMinimumSize": { + "width": 50, + "height": 50 + } + }, + "_Profiles": { + "Default": { + "Client Settings": { + "MinimizeInactiveClients": false, + "AlwaysMaximize": false, + "TrackClientPossitions": false, + "Dont_Minimize_Clients": [ + "Example Name1", + "Example Name2", + "Example Name3" + ] + }, + "Thumbnail Settings": { + "ShowThumbnailTextOverlay": true, + "ThumbnailTextColor":"#FAC57A", + "ThumbnailTextSize": 12, + "ThumbnailTextFont": "Gill Sans MT", + "ThumbnailTextMargins": { + "x": 15, + "y": 5 + }, + "ShowClientHighlightBorder": true, + "ClientHighligtColor": "#E36A0D", + "ClientHighligtBorderthickness": 4, + "HideThumbnailsOnLostFocus": false, + "ThumbnailOpacity": 80, + "ShowThumbnailsAlwaysOnTop": true, + "ShowAllColoredBorders":0 + }, + "Hotkeys":[ + {"Example Name1":"1"}, + {"Example Name2":"ctrl & 1"}, + {"Example Name3":"Xbutton1 & 1"}, + {"Example Name4":"^XButton1 & 1"} + ], + "Thumbnail Positions": {}, + "Client Possitions": {}, + "Thumbnail Visibility":{}, + "Hotkey Groups":{}, + "Custom Colors":{ + "cColorActive": "0", + "cColors": { + "CharNames": ["Example Char"], + "TextColor": ["FFFFFF"], + "Bordercolor":["FFFFFF"] + } + } + } + } +} +)" diff --git a/Lib/LiveThumb.ahk b/Lib/LiveThumb.ahk new file mode 100644 index 0000000..0efb011 --- /dev/null +++ b/Lib/LiveThumb.ahk @@ -0,0 +1,330 @@ +; ---------------------------------------------------------------------------------------------------------------------- +; Name .........: LiveThumb class library +; Description ..: Windows live thumbnails implementation (requires AERO to be enabled). +; AHK Version ..: AHK v2 2.0.3 +; Author .......: cyruz - http://ciroprincipe.info +; v2 Convertion : Gonz0 +; Forum .......: Ahk V1: https://www.autohotkey.com/boards/viewtopic.php?t=66585 +; Thanks .......: maul-esel - https://github.com/maul-esel/AeroThumbnail +; License ......: WTFPL - http://www.wtfpl.net/txt/copying/ +; Changelog ....: Feb. 21, 2019 - v0.1.0 - First version. +; ..............: Mar. 04, 2019 - v0.1.1 - Added active properties management and propertes getters. +; ..............: Jul. 28, 2019 - v0.1.2 - Added "Discard" method. Fixed LoadLibrary return type and a wrong behavior +; ..............: when returning false from the constructor (thanks Helgef). +; ..............: Sep. 21, 2019 - v0.1.3 - Fixed potential issue with HRESULT return code. Used internal memory +; ..............: management instead of LocalAlloc. +; ..............: Sep. 21, 2019 - v0.1.4 - Fixed Object.SetCapacity not zero-filling allocated memory. +; ..............: Nov. 15, 2022 - v0.1.5 - Fixed DWM_THUMB_PROPERTIES structure offsets (thanks swagfag). +; ..............: Jun. 26, 2023 - v0.1.5 - Conerverted to Autohotkey version 2 +; Remarks ......: The class registers a thumbnail and waits for properties update. When all the desired properties have +; ..............: been updated, the "Update()" method should be called to submit the properties. Getting a property +; ..............: when an update has not been performed before, will result in the string "NOT UPDATED" to be returned. +; ..............: Due to some internal unknown reason, the instantiated object must be in the global namespace to work. +; Info .........: Implements the following functions and structures from Win32 API. +; ..............: "DwmRegisterThumbnail" Win32 function: +; ..............: https://docs.microsoft.com/en-us/windows/desktop/api/dwmapi/nf-dwmapi-dwmregisterthumbnail +; ..............: "SIZE" Win32 structure: +; ..............: https://docs.microsoft.com/en-us/previous-versions//dd145106(v=vs.85) +; ..............: "DwmQueryThumbnailSourceSize" Win32 function: +; ..............: https://docs.microsoft.com/en-us/windows/desktop/api/dwmapi/nf-dwmapi-dwmquerythumbnailsourcesize +; ..............: "DWM_THUMB_PROPERTIES" Win32 structure: +; ..............: https://docs.microsoft.com/en-us/windows/desktop/api/dwmapi/ns-dwmapi-_dwm_thumbnail_properties +; ..............: "DWM_TNP" Constants for the dwFlags field: +; ..............: https://docs.microsoft.com/en-us/windows/desktop/dwm/dwm-tnp-constants +; ..............: "DwmUpdateThumbnailProperties" Win32 function: +; ..............: https://docs.microsoft.com/en-us/windows/desktop/api/dwmapi/nf-dwmapi-dwmupdatethumbnailproperties +; ..............: "DwmUnregisterThumbnail" Win32 function: +; ..............: https://docs.microsoft.com/en-us/windows/desktop/api/dwmapi/nf-dwmapi-dwmunregisterthumbnail +; ---------------------------------------------------------------------------------------------------------------------- + + + +; * How to use: +; ------------- + +; Instantiate the object: + +; thumb := LiveThumb(HWND Source Window, HWND Destination Window) + +; Modify its properties: + +; thumb.Source := [x, y, w, h] ;Size of the Source Window Thumbnail. Should be the same Size of the Source Window or it shows free space +; thumb.Destination := [x, y, w, h] ;Size of the Destination Window Thumbnail. Shrinks or streches the Thumbnail to the given size. To show the full area its should be the same size like the Destination Window +; thumb.Visible := True ;True or False Set the Thumbnail Visible +; hLT.SourceClientAreaOnly := True ;Optional: True or False Set Show Client Area Only. +; hLT.Opacity := 255 ;Optional: value between 0 and 255 + +; Update the properties: + +; thumb.Update() ;Updates the given Propertys. This should be called everytime if some value is changed. + +; Get a property: + +; aProp := thumb.Visible ; Shows 1 or 0 + + +; * Example: +; ---------- + +; #SingleInstance Force +; #Include + +; Run("notepad", , , &PID := 0) +; WinWait("ahk_pid " PID) +; hwndNotepad := WinExist("ahk_pid " PID) + +; WinGetPos( &X, &Y, &W, &H, "ahk_pid " PID) + +; Mygui := Gui() + +; hLT := LiveThumb(hwndNotepad, Mygui.Hwnd) +; hLT.Source := [0, 0, W, H] +; hLT.Destination := [0, 0, W, H] +; hLT.SourceClientAreaOnly := False +; hLT.Visible := True +; hLT.Opacity := 255 +; hLT.Update() + +; Mygui.Show("w" W "h" H) + + +; Name .........: LiveThumb - PUBLIC CLASS +; Description ..: Manages thumbnails creation and destruction. +Class LiveThumb +{ + Static Dll_Module := 0, + OBJ_COUNTER := 0, + DTP_SIZE := 48, + DTP_DWFLAGS := { Destination: 0x0001, + Source: 0x0002, + Opacity: 0x0004, + Visible: 0x0008, + SourceClientAreaOnly: 0x0010 }, + DTP_OFFSETS := { dwFlags: 0, + Destination: 4, + Source: 20, + Opacity: 36, + Visible: 37, + SourceClientAreaOnly: 41 } + + + ; Name .........: __New - PRIVATE CONSTRUCTOR + ; Description ..: Initialize the object, registering a new thumbnail and allocating the memory. + ; Parameters ...: hSource = Handle to the window to be previewed. + ; ..............: hDest = Handle to the window containing the live preview. + ; Return .......: LiveThumb object on success - False on error. + __New( hSource, hDest ) + { + ; Load the library on first run. + If ( !LiveThumb.DLL_MODULE ) + LiveThumb.DLL_MODULE := DllCall("LoadLibrary", "Str","dwmapi.dll", "Ptr") + + LiveThumb.OBJ_COUNTER += 1 + + ; Register a thumbnail to get an ID. + If ( DllCall( "dwmapi.dll\DwmRegisterThumbnail" + , "Ptr", hDest + , "Ptr", hSource + , "Ptr*", &phThumb := 0 + , "UPtr" ) ) + Return False + + this.THUMB_ID := phThumb + this.THUMB_UPDATED := False + this.THUMB_PENDING_UPDATE := True + + ; We define 2 portions of memory used for properties update and active properties tracking. + this.THUMB_UPD_PROP_PTR := Buffer(LiveThumb.DTP_SIZE,0) + this.THUMB_ACT_PROP_PTR := Buffer(LiveThumb.DTP_SIZE,0) + + ; Object.SetCapacity doesn't zero-fill the allocated memory so we call the Discard method. + this.Discard( ) + Return this + } + + ; Name .........: __Delete - PRIVATE DESTRUCTOR + ; Description ..: Unregister the thumbnail and deallocate memory. + __Delete( ) + { + ; Unregister thumbnail ID. + If ( this.THUMB_ID ) + DllCall( "dwmapi.dll\DwmUnregisterThumbnail" + , "Ptr", this.THUMB_ID ) + + ; If it's last instantiated object, free the library. + If ( LiveThumb.DLL_MODULE && !(LiveThumb.OBJ_COUNTER -= 1) ) + { + DllCall("FreeLibrary", "Ptr",LiveThumb.DLL_MODULE) + LiveThumb.DLL_MODULE := 0 + } + } + + __Get(aName, Params) { + If ( LiveThumb.HasOwnProp(aName)) + return LiveThumb.%aName% + + } + ; Name .........: QuerySourceSize - PUBLIC METHOD + ; Description ..: Return the size (width/height) of the source thumbnail. + ; Return .......: Array with width and height values - False on error. + QuerySourceSize( ) + { + SIZE := Buffer(8,0) + If ( DllCall( "dwmapi.dll\DwmQueryThumbnailSourceSize" + , "Ptr", this.THUMB_ID + , "Ptr", SIZE + , "UPtr" ) ) { + SIZE := Buffer(0) + Return False + } + + SourceSize := [NumGet(SIZE, 0, "Int"), NumGet(SIZE, 4, "Int")] + SIZE := Buffer(0) + + Return SourceSize + } + + ; Name .........: Update - PUBLIC METHOD + ; Description ..: Update thumbnail properties and zero fill the dwFlags memory to be ready for next update. + ; Return .......: True on success - False on error. + Update( ) + { + ; If no update is pending, return false. + ; If ( !this.THUMB_PENDING_UPDATE ) + ; Return False + + ; Update properties. + If ( DllCall( "dwmapi.dll\DwmUpdateThumbnailProperties" + , "Ptr", this.THUMB_ID + , "Ptr", this.THUMB_UPD_PROP_PTR + , "UPtr" ) ) + Return False + + ; Flag as updated and copy memory so that we can use this portion to track active properties with getters. + this.THUMB_UPDATED := True + DllCall( "NtDll.dll\RtlCopyMemory" + , "Ptr", this.THUMB_ACT_PROP_PTR + , "Ptr", this.THUMB_UPD_PROP_PTR + , "UInt", LiveThumb.DTP_SIZE ) + + ; Use the "Discard" method to reset dwFlags and return. + this.Discard( ) + Return True + } + + ; Name .........: Discard - PUBLIC METHOD + ; Description ..: Discard set properties, resetting dwFlags memory. + Discard( ) + { + ; Zero-fill dwFlags memory in the properties update memory portion. + NumPut("UInt", 0, this.THUMB_UPD_PROP_PTR, LiveThumb.DTP_OFFSETS.dwFlags) + this.THUMB_PENDING_UPDATE := False + } + + ; Name .........: Destination - PUBLIC PROPERTY + ; Description ..: The area in the destination window where the thumbnail will be rendered. + ; Value ........: Array with 4 client related coordinates [ left, top, right, bottom ]. + ; Remarks ......: "Destination" property is of "RECT" type (16 bytes structure) and starts from offset 4. + Destination { + Get { + If (!this.THUMB_UPDATED) + Return "NOT UPDATED" + + arrRet := [] + Loop 4 + arrRet.Push(NumGet(this.THUMB_ACT_PROP_PTR, LiveThumb.DTP_OFFSETS.Destination * A_Index, "Int")) + Return arrRet + } + Set { + This.SetDwFlags("Destination") + Loop 4 + NumPut("Int", value[A_Index], this.THUMB_UPD_PROP_PTR, LiveThumb.DTP_OFFSETS.Destination * A_Index) + } + } + + ; Name .........: Source - PUBLIC PROPERTY + ; Description ..: The region of the source window to use as the thumbnail. Default is the entire window. + ; Value ........: Array with 4 client related coordinates [ left, top, right, bottom ]. + ; Remarks ......: "Source" property is of "RECT" type (16 bytes structure) and starts from offset 20. + Source { + Get { + If (!this.THUMB_UPDATED) + Return "NOT UPDATED" + + arrRet := [] + Loop 4 + arrRet.Push(NumGet(this.THUMB_ACT_PROP_PTR, LiveThumb.DTP_OFFSETS.Source + 4*(A_Index-1), "Int")) + Return arrRet + } + Set { + This.SetDwFlags("Source") + Loop 4 + NumPut("Int", value[A_Index], this.THUMB_UPD_PROP_PTR, LiveThumb.DTP_OFFSETS.Source + 4*(A_Index-1)) + } + } + + ; Name .........: Opacity - PUBLIC PROPERTY + ; Description ..: The opacity with which to render the thumbnail. 0: transparent - 255: opaque. Default is 255. + ; Value ........: Integer value from 0 to 255. + ; Remarks ......: "Opacity" property is of "BYTE" type (1 byte + 3 padding) and starts from offset 36. + Opacity { + Get { + If (!this.THUMB_UPDATED) + Return "NOT UPDATED" + + Return NumGet(this.THUMB_ACT_PROP_PTR, LiveThumb.DTP_OFFSETS.Opacity, "UChar") + } + Set { + This.SetDwFlags("Opacity") + NumPut("UChar", value, this.THUMB_UPD_PROP_PTR, LiveThumb.DTP_OFFSETS.Opacity) + } + } + + ; Name .........: Visible - PUBLIC PROPERTY + ; Description ..: True to make the thumbnail visible, otherwise False. Default is False. + ; Value ........: Boolean True/False or integer 1/0 value. + ; Remarks ......: "Visible" property is of "BOOL" type (4 bytes) and starts from offset 40. + Visible { + Get { + If (!this.THUMB_UPDATED) + Return "NOT UPDATED" + + Return NumGet(this.THUMB_ACT_PROP_PTR, LiveThumb.DTP_OFFSETS.Visible, "Int") + } + Set { + This.SetDwFlags("Visible") + NumPut("Int", value, this.THUMB_UPD_PROP_PTR, LiveThumb.DTP_OFFSETS.Visible) + } + } + + ; Name .........: SourceClientAreaOnly - PUBLIC PROPERTY + ; Description ..: True to use only the thumbnail source's client area, otherwise False. Default is False. + ; Value ........: Boolean True/False or integer 1/0 value. + ; Remarks ......: "SourceClientAreaOnly" property is of "BOOL" type (4 bytes) and starts from offset 44. + SourceClientAreaOnly { + Get { + If (!this.THUMB_UPDATED) + Return "NOT UPDATED" + + Return NumGet(this.THUMB_ACT_PROP_PTR, LiveThumb.DTP_OFFSETS.SourceClientAreaOnly, "Int") + } + Set { + This.SetDwFlags("SourceClientAreaOnly") + NumPut("Uint", value, this.THUMB_UPD_PROP_PTR, LiveThumb.DTP_OFFSETS.SourceClientAreaOnly) + } + } + + ;Writes the DWFlags from the given Property into Memory. + SetDwFlags(aName) + { + If (LiveThumb.DTP_DWFLAGS.HasOwnProp(aName)) { + NumPut( "UInt", NumGet( this.THUMB_UPD_PROP_PTR, + LiveThumb.DTP_OFFSETS.dwFlags, "UInt" ) | LiveThumb.DTP_DWFLAGS.%aName%, + this.THUMB_UPD_PROP_PTR, + LiveThumb.DTP_OFFSETS.dwFlags) + + this.THUMB_PENDING_UPDATE := true + } + } +} + diff --git a/Lib/json.ahk b/Lib/json.ahk new file mode 100644 index 0000000..39e315c --- /dev/null +++ b/Lib/json.ahk @@ -0,0 +1,158 @@ +/************************************************************************ + * @Mdodified by G0nzo + * @description: JSON格式字符串序列化和反序列化, 修改自[HotKeyIt/Yaml](https://github.com/HotKeyIt/Yaml) + * 增加了对true/false/null类型的支持, 保留了数值的类型 + * @author thqby, HotKeyIt + * @date 2023/05/12 + * @version 1.0.5 + ***********************************************************************/ + +class JSON { + static null := ComValue(1, 0), true := ComValue(0xB, 1), false := ComValue(0xB, 0) + + /** + * Converts a AutoHotkey Object Notation JSON string into an object. + * @param text A valid JSON string. + * @param keepbooltype convert true/false/null to JSON.true / JSON.false / JSON.null where it's true, otherwise 1 / 0 / '' + * @param as_map object literals are converted to map, otherwise to object + */ + static Load(text, keepbooltype := false, as_map := true) { + keepbooltype ? (_true := JSON.true, _false := JSON.false, _null := JSON.null) : (_true := true, _false := false, _null := "") + as_map ? (map_set := (maptype := Map).Prototype.Set) : (map_set := (obj, key, val) => obj.%key% := val, maptype := Object) + NQ := "", LF := "", LP := 0, P := "", R := "" + D := [C := (A := InStr(text := LTrim(text, " `t`r`n"), "[") = 1) ? [] : maptype()], text := LTrim(SubStr(text, 2), " `t`r`n"), L := 1, N := 0, V := K := "", J := C, !(Q := InStr(text, '"') != 1) ? text := LTrim(text, '"') : "" + Loop Parse text, '"' { + Q := NQ ? 1 : !Q + NQ := Q && (SubStr(A_LoopField, -3) = "\\\" || (SubStr(A_LoopField, -1) = "\" && SubStr(A_LoopField, -2) != "\\")) + if !Q { + if (t := Trim(A_LoopField, " `t`r`n")) = "," || (t = ":" && V := 1) + continue + else if t && (InStr("{[]},:", SubStr(t, 1, 1)) || RegExMatch(t, "^-?\d*(\.\d*)?\s*[,\]\}]")) { + Loop Parse t { + if N && N-- + continue + if InStr("`n`r `t", A_LoopField) + continue + else if InStr("{[", A_LoopField) { + if !A && !V + throw Error("Malformed JSON - missing key.", 0, t) + C := A_LoopField = "[" ? [] : maptype(), A ? D[L].Push(C) : map_set(D[L], K, C), D.Has(++L) ? D[L] := C : D.Push(C), V := "", A := Type(C) = "Array" + continue + } else if InStr("]}", A_LoopField) { + if !A && V + throw Error("Malformed JSON - missing value.", 0, t) + else if L = 0 + throw Error("Malformed JSON - to many closing brackets.", 0, t) + else C := --L = 0 ? "" : D[L], A := Type(C) = "Array" + } else if !(InStr(" `t`r,", A_LoopField) || (A_LoopField = ":" && V := 1)) { + if RegExMatch(SubStr(t, A_Index), "m)^(null|false|true|-?\d+\.?\d*)\s*[,}\]\r\n]", &R) && (N := R.Len(0) - 2, R := R.1, 1) { + if A + C.Push(R = "null" ? _null : R = "true" ? _true : R = "false" ? _false : IsNumber(R) ? R + 0 : R) + else if V + map_set(C, K, R = "null" ? _null : R = "true" ? _true : R = "false" ? _false : IsNumber(R) ? R + 0 : R), K := V := "" + else throw Error("Malformed JSON - missing key.", 0, t) + } else { + ; Added support for comments without '"' + if A_LoopField == '/' { + nt := SubStr(t, A_Index + 1, 1), N := 0 + if nt == '/' { + if nt := InStr(t, '`n', , A_Index + 2) + N := nt - A_Index - 1 + } else if nt == '*' { + if nt := InStr(t, '*/', , A_Index + 2) + N := nt + 1 - A_Index + } else nt := 0 + if N + continue + } + throw Error("Malformed JSON - unrecognized character-", 0, A_LoopField " in " t) + } + } + } + } else if InStr(t, ':') > 1 + throw Error("Malformed JSON - unrecognized character-", 0, SubStr(t, 1, 1) " in " t) + } else if NQ && (P .= A_LoopField '"', 1) + continue + else if A + LF := P A_LoopField, C.Push(InStr(LF, "\") ? UC(LF) : LF), P := "" + else if V + LF := P A_LoopField, map_set(C, K, InStr(LF, "\") ? UC(LF) : LF), K := V := P := "" + else + LF := P A_LoopField, K := InStr(LF, "\") ? UC(LF) : LF, P := "" + } + return J + UC(S, e := 1) { + static m := Map(Ord('"'), '"', Ord("a"), "`a", Ord("b"), "`b", Ord("t"), "`t", Ord("n"), "`n", Ord("v"), "`v", Ord("f"), "`f", Ord("r"), "`r") + local v := "" + Loop Parse S, "\" + if !((e := !e) && A_LoopField = "" ? v .= "\" : !e ? (v .= A_LoopField, 1) : 0) + v .= (t := InStr("ux", SubStr(A_LoopField, 1, 1)) ? SubStr(A_LoopField, 1, RegExMatch(A_LoopField, "i)^[ux]?([\dA-F]{4})?([\dA-F]{2})?\K") - 1) : "") && RegexMatch(t, "i)^[ux][\da-f]+$") ? Chr(Abs("0x" SubStr(t, 2))) SubStr(A_LoopField, RegExMatch(A_LoopField, "i)^[ux]?([\dA-F]{4})?([\dA-F]{2})?\K")) : m.has(Ord(A_LoopField)) ? m[Ord(A_LoopField)] SubStr(A_LoopField, 2) : "\" A_LoopField, e := A_LoopField = "" ? e : !e + return v + } + } + + /** + * Converts a AutoHotkey Array/Map/Object to a Object Notation JSON string. + * @param obj A AutoHotkey value, usually an object or array or map, to be converted. + * @param expandlevel The level of JSON string need to expand, by default expand all. + * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read. + */ + static Dump(obj, expandlevel := unset, space := " ") { + expandlevel := IsSet(expandlevel) ? Abs(expandlevel) : 10000000 + return Trim(CO(obj, expandlevel)) + CO(O, J := 0, R := 0, Q := 0) { + static M1 := "{", M2 := "}", S1 := "[", S2 := "]", N := "`n", C := ",", S := "- ", E := "", K := ":" + if (OT := Type(O)) = "Array" { + D := !R ? S1 : "" + for key, value in O { + F := (VT := Type(value)) = "Array" ? "S" : InStr("Map,Object", VT) ? "M" : E + Z := VT = "Array" && value.Length = 0 ? "[]" : ((VT = "Map" && value.count = 0) || (VT = "Object" && ObjOwnPropCount(value) = 0)) ? "{}" : "" + D .= (J > R ? "`n" CL(R + 2) : "") (F ? (%F%1 (Z ? "" : CO(value, J, R + 1, F)) %F%2) : ES(value)) (OT = "Array" && O.Length = A_Index ? E : C) + } + } else { + D := !R ? M1 : "" + for key, value in (OT := Type(O)) = "Map" ? (Y := 1, O) : (Y := 0, O.OwnProps()) { + F := (VT := Type(value)) = "Array" ? "S" : InStr("Map,Object", VT) ? "M" : E + Z := VT = "Array" && value.Length = 0 ? "[]" : ((VT = "Map" && value.count = 0) || (VT = "Object" && ObjOwnPropCount(value) = 0)) ? "{}" : "" + D .= (J > R ? "`n" CL(R + 2) : "") (Q = "S" && A_Index = 1 ? M1 : E) ES(key) K (F ? (%F%1 (Z ? "" : CO(value, J, R + 1, F)) %F%2) : ES(value)) (Q = "S" && A_Index = (Y ? O.count : ObjOwnPropCount(O)) ? M2 : E) (J != 0 || R ? (A_Index = (Y ? O.count : ObjOwnPropCount(O)) ? E : C) : E) + if J = 0 && !R + D .= (A_Index < (Y ? O.count : ObjOwnPropCount(O)) ? C : E) + } + } + if J > R + D .= "`n" CL(R + 1) + if R = 0 + D := RegExReplace(D, "^\R+") (OT = "Array" ? S2 : M2) + return D + } + ES(S) { + switch Type(S) { + case "Float": + if (v := '', d := InStr(S, 'e')) + v := SubStr(S, d), S := SubStr(S, 1, d - 1) + if ((StrLen(S) > 17) && (d := RegExMatch(S, "(99999+|00000+)\d{0,3}$"))) + S := Round(S, Max(1, d - InStr(S, ".") - 1)) + return S v + case "Integer": + return S + case "String": + S := StrReplace(S, "\", "\\") + S := StrReplace(S, "`t", "\t") + S := StrReplace(S, "`r", "\r") + S := StrReplace(S, "`n", "\n") + S := StrReplace(S, "`b", "\b") + S := StrReplace(S, "`f", "\f") + S := StrReplace(S, "`v", "\v") + S := StrReplace(S, '"', '\"') + return '"' S '"' + default: + return S == JSON.true ? "true" : S == JSON.false ? "false" : "null" + } + } + CL(i) { + Loop (s := "", space ? i - 1 : 0) + s .= space + return s + } + } +} \ No newline at end of file diff --git a/Main.ahk b/Main.ahk new file mode 100644 index 0000000..38844e2 --- /dev/null +++ b/Main.ahk @@ -0,0 +1,153 @@ +#Requires AutoHotkey v2.0 + +#Include ; The Default Settings Values +#Include +#Include +#Include <../src/Main_Class> +#Include <../src/ThumbWindow> +#Include <../src/TrayMenu> +#Include <../src/Propertys> +#Include <../src/Settings_Gui> + +#SingleInstance Force +Persistent +ListLines False +KeyHistory 0 + +CoordMode "Mouse", "Screen" ; to track Window Mouse possition while DragMoving the thumbnails +SetWinDelay -1 +FileEncoding("UTF-8") ; Encoding for JSSON file + +SetTitleMatchMode 3 + +A_MaxHotKeysPerInterval := 10000 + +/* +TODO ######################### + +*/ + +;@Ahk2Exe-Let U_version = 1.0.0. +;@Ahk2Exe-SetVersion %U_version% +;@Ahk2Exe-SetFileVersion %U_version% +;@Ahk2Exe-SetCopyright gonzo83 +;@Ahk2Exe-SetDescription EVE-X-Preview +;@Ahk2Exe-SetProductName EVE-X-Preview +;@Ahk2Exe-ExeName EVE-X-Preview + +;@Ahk2Exe-AddResource icon.ico, 160 ; Replaces 'H on blue' +;@Ahk2Exe-AddResource icon-suspend.ico, 206 ; Replaces 'S on green' +;@Ahk2Exe-AddResource icon.ico, 207 ; Replaces 'H on red' +;@Ahk2Exe-AddResource icon-suspend.ico, 208 ; Replaces 'S on red' + +;@Ahk2Exe-SetMainIcon icon.ico + +if !(A_IsCompiled) + TraySetIcon("icon.ico",,true) + +OnError(Error_Handler) +Call := Main_Class() + + + +Load_JSON() { + DJSON := JSON.Load(default_JSON) + if !(FileExist("EVE-X-Preview.json")) { + FileAppend(JSON.Dump(DJSON,," " ), "EVE-X-Preview.json") + _JSON := JSON.Load(FileRead("EVE-X-Preview.json")) + return _JSON + } + else { + Try { + if (FileExist("EVE-X-Preview.json")) { + ;if needed because of Backward combativity from the alpha versions + MergeJson() + } + _JSON := JsonMergeNoOverwrite( + DJSON, + JSON.Load(FileRead("EVE-X-Preview.json")) + ) + FileDelete("EVE-X-Preview.json") + FileAppend(JSON.Dump(_JSON,," " ), "EVE-X-Preview.json") + } + catch as e { + value := MsgBox("The settings file is corrupted. Do you want to create a new one?",,"OKCancel") + if (value = "Cancel") + ExitApp() + + FileDelete("EVE-X-Preview.json") + FileAppend(JSON.Dump(DJSON,, " "), "EVE-X-Preview.json") + _JSON := JSON.Load(FileRead("EVE-X-Preview.json")) + } + } + return _JSON +} + +;Compare the User json wit the default Json to check if any key changed for possible future updates. +JsonMergeNoOverwrite(obj1, obj2) { + for key, value in obj1 { + if (obj2.Has(key)) { + if (IsObject(value) && IsObject(obj2[key])) + obj2[key] := JsonMergeNoOverwrite(value, obj2[key]) + } else { + obj2[key] := value + } + } + return obj2 +} + + +;THis function is only used to merge the Json from old versions into the new one +MergeJson(Settingsfile := "EVE-X-Preview.json", dJson := JSON.Load(default_JSON)) { + ;Load the content from the existing Json File + fileObj := FileOpen(Settingsfile,"r", "Utf-8") + JsonRaw := fileObj.Read(), fileObj.Close() + OldJson := JSON.Load(JsonRaw) + savetofile := 0 + + + for Profiles, settings in OldJson["_Profiles"] { + if (Profiles = "Default") { + continue + } + dJson["_Profiles"][Profiles] := Map() + for k, v in settings { + if (OldJson["_Profiles"][Profiles].Has("ClientPossitions")) { + savetofile := 1 + if (k = "ClientPossitions") + dJson["_Profiles"][Profiles]["Client Possitions"] := v + else if (k = "ClientSettings") + dJson["_Profiles"][Profiles]["Client Settings"] := v + else if (k = "ThumbnailSettings") + dJson["_Profiles"][Profiles]["Thumbnail Settings"] := v + else if (k = "ThumbnailPositions") + dJson["_Profiles"][Profiles]["Thumbnail Positions"] := v + else if (k = "Thumbnail_visibility") + dJson["_Profiles"][Profiles]["Thumbnail Visibility"] := v + else if (k = "Custom_Colors") + dJson["_Profiles"][Profiles]["Custom Colors"] := dJson["_Profiles"]["Default"]["Custom Colors"] + else if (k = "Hotkey_Groups") + dJson["_Profiles"][Profiles]["Hotkey Groups"] := v + else if (k = "Hotkeys") { + if (Type(v) = "Map") { + Arr := [] + for char, hotkey in v + Arr.Push(Map(char, hotkey)) + dJson["_Profiles"][Profiles]["Hotkeys"] := Arr + } + } + } + } + } + if savetofile { + dJson["global_Settings"] := OldJson["global_Settings"] + + fileObj := FileOpen(Settingsfile,"w", "Utf-8") + fileObj.Write(JSON.Dump(dJson,, " ")), fileObj.Close() + } +} + +; Hanles unmanaged Errors +Error_Handler(Thrown, Mode) { + return -1 +} \ No newline at end of file diff --git a/README.MD b/README.MD new file mode 100644 index 0000000..ec4b9a3 --- /dev/null +++ b/README.MD @@ -0,0 +1,154 @@ +## EVE-X-Preview + +EVE-X-Preview is a tool for Windows that makes it easy to manage and use multiple EVE clients. +It allows displaying thumbnails of the running EVE clients and bringing EVE clients to the foreground with a click on the thumbnail or with a set hotkey. Mouse and keyboard buttons are supported. + +It is possible to create multiple profiles to quickly change the hotkey assignments, thumbnail position, and color adjustments + + +**In summary, this tool offers the following features:** + +* Display thumbnails of active EVE clients. +* Bring an EVE client to the foreground with a hotkey, including full keyboard and mouse support. +* Create multiple profiles. +* Customize text color, size, borders, font, and position. +* Display thumbnails of varying sizes. +* Create hotkey groups. +* Save EVE client positions and restore them. +* Graphical user interface to configure all settings + + +**The following is not supported** +* The simultaneous sending of keyboard or mouse inputs to multiple EVE clients, also known as input broadcasting. +* Sending individual keyboard or mouse inputs. +* Displaying excerpts from the client as thumbnails. +* Manipulating EVE clients. + +#### EVE-X-Preview does not interact directly with the game clients in any way. It only allows changing the foreground window with the help of hotkeys and thumbnails.
No features will be added now or in the future that violate the EULA and Terms of Service of EVE Online. + + + +## How To Use + +1. Download the EXE file from here https://github.com/g0nzo83/EVE-X-Preview/releases +2. Create a new Folder on Dektop or in Documents or where you like with the exception of the Programs folders. And move EVE-X-Preview.exe to the created folder. +3. Start EVE-X-Preview.exe. It should create a json file. This file must always be in the same folder as EVE-X-Preview.exe. It contains all your settings +4. A tray icon should then appear at the bottom right of the taskbar. Right-click on it to access the settings. +5. Right Click on the Tryicon and klick "Open" or double klick it and klick on "Profile Settings" create a new Profile. +6. From here on you can adjust as you like + +`Important Note:`
`some settings require a restart of the tool. The settings window must be closed so that the settings made there are applied` + +## Run from Source + +1. Download and install [Autohotkey v2](https://www.autohotkey.com/) +2. Download the Zip file from https://github.com/g0nzo83/EVE-X-Preview/releases +3. Unpack the Zip file and Run the file `Main.ahk` + +## Will I get banned if I use it? +As I understand the EVE Online EULA and Terms of Service, this tool does not break any rules.
+Since EVE-X-Preview uses the same methods as [EVE-O Preview](https://github.com/EveOPlus/eve-o-preview), another tool which offers similar functions and is permitted, I assume that this also applies to EVE-X-Preview.
+Nevertheless I want to point out that the use of EVE-X-Preview or any other Thrid-Party tool is at your own risk.
+**I assume no liability whatsoever** + +## Application Options + +### **Tray Menu - Settings** + +| Option | Description | +| --- | --- | +| Open | Opens the settings window | +| Suspend Hotkeys | Deactivates the hotkeys | +| Close all EVE clients | Closes all open EVE windows | +| Restore Client Positions | Toggles On/ Off
Restores the previously saved client positions automatically if activated | +| Save Client Positions | Saves the current position of all EVE clients so that they can be restored with Restore Client Positions
Positions are not saved automatically. If the position has been changed, it must be saved again | +| Save Thumbnail Positions | Saves the current position of the thumbnails. Thumbnail positions are not saved automatically. If the position has been changed, it must be saved again | +| Reload | If problems occur with the tool, it can simply be restarted with this option | +| Exit | Exits the program | + + + + + +### **Global Settings** +| Option | Description | +| --- | --- | +| Suspend Hotkeys - Hotkey |Allows you to set a hotkey to su all active hotkeys. The tray icon changes when the pause is activated and a short message is displayed next to the cursor | +| Hotkey activation Scope | **Global: ->** Allows you to activate an EVE client with a hotkey regardless of which window you are in.

**If an EVE window is Active: ->** Activates the hotkeys only when any EVE Window is in the foreground| +| Thumbnail Background Color | Setting the background color of the thumbnail. This is only visible if the content of the thumbnail is not visible, such as when the EVE window is minimized and the thumbnail was created afterwards
**HEX: ->** 0xFFFFFF or #FFFFFF or FFFFFF
**RGB: ->** RGB(225,255,255) or (225,255,255) or 225,255,255| +| Thumbnail Default Location | Setting the dafault thumbnail position such as the thumbnail of the character selection screen | +| Thumbnail Minimum Size | Allows you to set a minimum size of the thumbnail to prevent it from becoming too small to edit | +| Thumbnail Snap | Allows you to switch the automatic alignment of the thumbnails to each other to On or Off | +| Thumbnail Snap Distance | Defines the range up to which the thumbnails automatically align with each other.
This only has an effect when Thumbnail Snap is activated | +| Minimize EVE Window Delay | Sets the delay before an inactive client is minimized after another one has been activated. This option is only used if "Minimize Inactive Client" has been activated | + +### **Profile Settings - Client Settings** +| Option | Description | +| --- | --- | +| Minimize Inactive Clients | If this option is activated, all inactive clients are minimized if they are not entered in the "Dont Minimize Clients" list | +| Always Maximize Clients | Thumbnails width. Can be set to any value from **100** to **640** points | +| Thumbnail Height | This is an important option. This means that the client is always maximized. This largely prevents the overview of the EVE client from shifting when the PC is on heavily load | +| Dont Minimize CLients| All EVE character names entered here are exempt from minimization. This is useful if you always need a current preview image of the client. Since a preview image of a minimized client can only be shown frozen | + +### **Profile Settings - Custom Colors** +| Allows you to set custom colors for the font and borders| +| --- | +| The supported syntax is:
HEX: -> 0xFFFFFF or #FFFFFF or FFFFFF
RGB: -> RGB(225,255,255) or (225,255,255) or 225,255,255| + + + +### **Profile Settings - Hotkey Groups** +| Option | Description | +| --- | --- | +| Select Group | Enables the creation and deletion of hotkey groups. Each group must have a unique name | +| Hotkey Groups Text field| The character names that belong to the group are entered here. The names must be entered one below the other. The activation sequence is from top to bottom | +| Forwards Hotkey
Backwards Hotkey | *Explanation of the hotkeys, see below* | + +### **Profile Settings - Hotkeys** +|**The character names must be entered one below the other and the corresponding hotkey on the opposite side
The same hotkey may only be assigned to one character!**
*Explanation of the hotkeys, see below*| +|---| + +### **Hotkeys - Explanation** +There are several ways to specify hotkeys
For a detailed description you can have a look at the following pages
[Hotkey Modifier Symbols](https://www.autohotkey.com/docs/v2/Hotkeys.htm#Symbols) and [List Of Keys](https://www.autohotkey.com/docs/v2/KeyList.htm) + +| Hotkey | Description | +| ---| --- | +| 1
2
Tab
~
Lbutton
Rbutton
Xbutton1
Xbutton2
Ctrl
Shift | These are simple hotkeys. They are defined by the letter itself or the name of the key. virtual key codes are also supported

It is not recommended to use the left or right mouse button as a simple hotkey. This would prevent you from being able to use the buttons.
These hotkeys can only be triggered when they are pressed alone. If another button is pressed that is not part of the hotkey, the hotkey is not triggered | +| ........Modifierkeys:..........
^1 = Ctrl & 1
+1 = Shift & 1
#1 = Win & 1
!1 = Alt & 1 | Both Hotkey combos are valid here.
the difference is that a hotkey defined with a prefix allows any number of prefixes, for example:
`+^1` means Shift+Control+1
while the assignment of 2 buttons as a hotkey is limited to 2 for example:
`Shift & Ctrl & 1` is not permitted
while these symbols are translated into Modifierkeys like `Ctrl`and `Shift` if used as a prefix but they do not mean it if they stand alone like: `+` alone means means the actual plus key | +| Special Prefix:
*1 | The `*` prefix allows the hotkey to be triggered even if it is pressed together with another button
This is a very useful prefix as you are not forced to press the additional key again like:
`*1` + +### **Profile Settings - Thumbnail Settings** +| Option | Description | +| --- | --- | +| Show Thumbnail Text Overlay | Shows or removes the character name on the thumbnail | +| Thumbnail Text Colour | Sets the color of the text of the character name on the thumbnail
The supported syntax is:
HEX: -> 0xFFFFFF or #FFFFFF or FFFFFF
RGB: -> RGB(225,255,255) or (225,255,255) or 225,255,255 | +|Thumbnail Text Size | Changes the size of the text of the character name. | +| Thumbnail Text Font | Changes the font of the text on the Thubnail. The font must be available in the Windows system. | +| Thumbnail Text Margins | Changes the distance of the thumbnail text to the edges of the thumbnail | +| Client Highlight Color | Changes the color of the color frame displayed on the thumbnail of the active client.
The supported syntax is:
HEX: -> 0xFFFFFF or #FFFFFF or FFFFFF
RGB: -> RGB(225,255,255) or (225,255,255) or 225,255,255| +|Client Highlight Border thickness | Changes the thickness of color frame displayed on the thumbnail of the active client | +| Show Client Highlight Border | Activates or deactivates the display of the color frame displayed on the thumbnail of the active client | +| Hide Thumbnails on Lost Focus | If activated, the thumbnails are not displayed if no EVE client is in the foreground and active. | +| Thumbnail Opacity | Sets the transparency of the thumbnail. The values are in percent from 0-100 | +| Show Thumbnails AlwaysOnTop | If activated, the thumbnails are always displayed above all windows. | + +### **Profile Settings - Thumbnail Visibility** +|The thumbnails of the selected characters are not displayed | +|---| + +### Mouse Gestures and Actions + +Mouse gestures are applied to the thumbnail window currently being hovered over. + +| Action | Gesture | +| --- | --- | +| Activate the EVE Online client and bring it to front | Left click the thumbnail | +| Minimize the EVE Online client | Hold Control key and click the thumbnail | +| Move thumbnail to a new position | Press right mouse button and move the mouse | +| Move all thumbnails | Hold Control and right Mousebutton and move the mouse | +| Adjust all thumbnails height and width | Press both left and right mouse buttons and move the mouse up or down | +|Adjust a single thumbnails height and width | Hold Control and the right+left mouse button and move the mouse| + + +## About +EVE-X-Preview is Created and Maintained by [g0nzo83](https://github.com/g0nzo83) also known as "*John Xer*" in EVE Online diff --git a/src/Main_Class.ahk b/src/Main_Class.ahk new file mode 100644 index 0000000..2c35710 --- /dev/null +++ b/src/Main_Class.ahk @@ -0,0 +1,730 @@ + + +Class Main_Class extends ThumbWindow { + Static WM_DESTROY := 0x02, + WM_SIZE := 0x05, + WM_NCCALCSIZE := 0x83, + WM_NCHITTEST := 0x84, + WM_NCLBUTTONDOWN := 0xA1, + WM_SYSKEYDOWN := 0x104, + WM_SYSKEYUP := 0x105, + WM_MOUSEMOVE := 0x200, + WM_LBUTTONDOWN := 0x201, + WM_LBUTTONUP := 0x0202, + WM_RBUTTONDOWN := 0x0204, + WM_RBUTTONUP := 0x0205, + WM_KEYDOWN := 0x0100, + WM_MOVE := 0x03, + WM_MOUSELEAVE := 0x02A2 + + ;! This key is for the internal Hotkey to bring the Window in forgeround + ;! it is possible this key needs to be changed if Windows updates and changes the unused virtual keys + static virtualKey := "vk0xE8" + + LISTENERS := [ + Main_Class.WM_LBUTTONDOWN, + Main_Class.WM_RBUTTONDOWN + ;Main_Class.WM_SIZE, + ;Main_Class.WM_MOVE + ] + + + EVEExe := "Ahk_Exe exefile.exe" + + ; Values for WM_NCHITTEST + ; Size from the invisible edge for resizing + border_size := 4 + HT_VALUES := [[13, 12, 14], [10, 1, 11], [16, 15, 17]] + + ;### Predifining Arrays and Maps ######### + EventHooks := Map() + ThumbWindows := {} + ThumbHwnd_EvEHwnd := Map() + + __New() { + + This._JSON := Load_JSON() + This.default_JSON := JSON.Load(default_JSON) + + This.TrayMenu() + This.MinimizeDelay := This.Minimizeclients_Delay + + ;Hotkey to trigger by the script to get permissions t bring a Window in foreground + ;Register all posible modifire combinations + prefixArr := ["","^","!", "#", "+", "+^", "+#", "+!", "^#", "^!","#!", "^+!", "^+#", "^#!", "+!#","^+#!"] + for index, prefix in prefixArr + Hotkey( prefix . Main_Class.virtualKey, ObjBindMethod(This, "ActivateForgroundWindow"), "P1") + + ; Register Hotkey for Puase Hotkeys if the user has is Set + if (This.Suspend_Hotkeys_Hotkey != "") { + HotIf (*) => WinExist(This.EVEExe) + try { + Hotkey This.Suspend_Hotkeys_Hotkey, ( * ) => This.Suspend_Hotkeys(), "S1" + } + catch ValueError as e { + MsgBox(e.Message ": --> " e.Extra " <-- in: Global Settings -> Suspend Hotkeys-Hotkey" ) + } + } + + ; The Timer property for Asycn Minimizing. + this.timer := ObjBindMethod(this, "EVEMinimize") + + ;margins for DwmExtendFrameIntoClientArea. higher values extends the shadow + This.margins := Buffer(16, 0) + NumPut("Int", 0, This.margins) + + ;Register all messages wich are inside LISTENERS + for i, message in this.LISTENERS + OnMessage(message, ObjBindMethod(This, "_OnMessage")) + + ;Property for the delay to hide Thumbnails if not client is in foreground and user has set Hide on lost Focus + This.CheckforActiveWindow := ObjBindMethod(This, "HideOnLostFocusTimer") + + ;The Main Timer who checks for new EVE Windows or closes Windows + SetTimer(ObjBindMethod(This, "HandleMainTimer"), 50) + This.Save_Settings_Delay_Timer := ObjBindMethod(This, "SaveJsonToFile") + ;Timer property to remove Thumbnails for closed EVE windows + This.DestroyThumbnails := ObjBindMethod(This, "EvEWindowDestroy") + This.DestroyThumbnailsToggle := 1 + + ;Register the Hotkeys for cycle groups + This.Register_Hotkey_Groups() + This.BorderActive := 0 + + return This + } + + HandleMainTimer() { + static HideShowToggle := 0, WinList := {} + try + WinList := WinGetList(This.EVEExe) + Catch + return + ; If any EVE Window exist + if (WinList.Length) { + try { + ;Check if a window exist without Thumbnail and if the user is in Character selection screen or not + for index, hwnd in WinList { + WinList.%hwnd% := { Title: This.CleanTitle(WinGetTitle(hwnd)) } + if !This.ThumbWindows.HasProp(hwnd) { + This.EVE_WIN_Created(hwnd, WinList.%hwnd%.title) + if (!This.HideThumbnailsOnLostFocus) + This.ShowThumb(hwnd, "Show") + HideShowToggle := 1 + } + ;if in Character selection screen + else if (This.ThumbWindows.HasProp(hwnd)) { + if (This.ThumbWindows.%hwnd%["Window"].Title != WinList.%hwnd%.Title) { + This.EVENameChange(hwnd, WinList.%hwnd%.Title) + } + } + } + } + catch + return + + try { + ;if HideThumbnailsOnLostFocus is selectet check if a eve window is still in foreground, runs a timer once with a delay to prevent stuck thumbnails + ActiveProcessName := WinGetProcessName("A") + + if ((DllCall("IsIconic","UInt", WinActive("ahk_exe exefile.exe")) || ActiveProcessName != "exefile.exe") && !HideShowToggle && This.HideThumbnailsOnLostFocus) { + SetTimer(This.CheckforActiveWindow, -500) + HideShowToggle := 1 + } + else if ( ActiveProcessName = "exefile.exe" && !DllCall("IsIconic","UInt", WinActive("ahk_exe exefile.exe"))) { + Ahwnd := WinExist("A") + if HideShowToggle { + for EVEHWND in This.ThumbWindows.OwnProps() { + This.ShowThumb(EVEHWND, "Show") + } + HideShowToggle := 0 + This.BorderActive := 0 + } + ; sets the Border to the active window thumbnail + else if (Ahwnd != This.BorderActive) { + ;Shows the Thumbnail on top of other thumbnails + WinSetAlwaysOnTop(1,This.ThumbWindows.%Ahwnd%["Window"].Hwnd ) + + This.ShowActiveBorder(Ahwnd) + This.UpdateThumb_AfterActivation(, Ahwnd) + This.BorderActive := Ahwnd + + } + } + } + } + ; Check if a Thumbnail exist without EVE Window. if so destroy the Thumbnail and free memory + if ( This.DestroyThumbnailsToggle ) { + for k, v in This.ThumbWindows.Clone().OwnProps() { + if !Winlist.HasProp(k) { + SetTimer(This.DestroyThumbnails, -500) + This.DestroyThumbnailsToggle := 0 + } + } + } + } + + ; The function for the timer which gets started if no EVE window is in focus + HideOnLostFocusTimer() { + Try { + ForegroundPName := WinGetProcessName("A") + if (ForegroundPName = "exefile.exe") { + if (DllCall("IsIconic", "UInt", WinActive("ahk_exe exefile.exe"))) { + for EVEHWND in This.ThumbWindows.OwnProps() { + This.ShowThumb(EVEHWND, "Hide") + } + } + } + else if (ForegroundPName != "exefile.exe") { + for EVEHWND in This.ThumbWindows.OwnProps() { + This.ShowThumb(EVEHWND, "Hide") + } + } + } + } + + ;Register set Hotkeys by the user in settings + RegisterHotkeys(title, EvE_hwnd) { + static registerGroups := 0 + ;if the user has set Hotkeys in Options + if (This._Hotkeys[title]) { + ;if the user has selected Global Hotkey. This means the Hotkey will alsways trigger as long at least 1 EVE Window exist. + ;if a Window does not Exist which was assigned to the hotkey the hotkey will be dissabled until the Window exist again + if(This.Global_Hotkeys) { + HotIf (*) => WinExist(This.EVEExe) && WinExist("EVE - " title ) && !WinActive("EVE-X-Preview - Settings") + try { + Hotkey This._Hotkeys[title], (*) => This.ActivateEVEWindow(,,title), "P1" + } + catch ValueError as e { + MsgBox(e.Message ": --> " e.Extra " <-- in Profile Settings - " This.LastUsedProfile " Hotkeys" ) + } + } + ;if the user has selected (Win Active) the hotkeys will only trigger if at least 1 EVE Window is Active and in Focus + ;This makes it possible to still use all keys outside from EVE + else { + HotIf (*) => WinExist("EVE - " title ) && WinActive(This.EVEExe) + try { + Hotkey This._Hotkeys[title], (*) => This.ActivateEVEWindow(,,title),"P1" + } + catch ValueError as e { + MsgBox(e.Message ": --> " e.Extra " <-- in Profile Settings - " This.LastUsedProfile " Hotkeys" ) + } + } + } + } + + ;Register the Hotkeys for cycle Groups if any set + Register_Hotkey_Groups() { + static Fkey := "", BKey := "", Arr := [] + if (IsObject(This.Hotkey_Groups) && This.Hotkey_Groups.Count != 0) { + for k, v in This.Hotkey_Groups { + ;If any EVE Window Exist and at least 1 character matches the the list from the group windows + if(This.Global_Hotkeys) { + if( v["ForwardsHotkey"] != "" ) { + Fkey := v["ForwardsHotkey"], Arr := v["Characters"] + HotIf (*) => This.OneWinExist(Arr) && !WinActive("EVE-X-Preview - Settings") + try { + Hotkey( v["ForwardsHotkey"], ObjBindMethod(This, "Cycle_Hotkey_Groups",Arr,"ForwardsHotkey"), "P1") + } + catch ValueError as e { + MsgBox(e.Message ": --> " e.Extra " <-- in Profile Settings - " This.LastUsedProfile " - Hotkey Groups - " k " - Forwards Hotkey" ) + } + } + if( v["BackwardsHotkey"] != "" ) { + Fkey := v["BackwardsHotkey"], Arr := v["Characters"] + HotIf (*) => This.OneWinExist(Arr) && !WinActive("EVE-X-Preview - Settings") + try { + Hotkey( v["BackwardsHotkey"], ObjBindMethod(This, "Cycle_Hotkey_Groups",Arr,"BackwardsHotkey"), "P1") + } + catch ValueError as e { + MsgBox(e.Message ": --> " e.Extra " <-- in Profile Settings - " This.LastUsedProfile " Hotkey Groups - " k " - Backwards Hotkey" ) + } + } + } + ;If any EVE Window is Active + else { + if( v["ForwardsHotkey"] != "" ) { + Fkey := v["ForwardsHotkey"], Arr := v["Characters"] + HotIf (*) => This.OneWinExist(Arr) && WinActive("Ahk_exe exefile.exe") + try { + Hotkey( v["ForwardsHotkey"], ObjBindMethod(This, "Cycle_Hotkey_Groups",Arr,"ForwardsHotkey"), "P1") + } + catch ValueError as e { + MsgBox(e.Message ": --> " e.Extra " <-- in Profile Settings - " This.LastUsedProfile " - Hotkey Groups - " k " - Forwards Hotkey" ) + } + } + if( v["BackwardsHotkey"] != "" ) { + Fkey := v["BackwardsHotkey"], Arr := v["Characters"] + HotIf (*) => This.OneWinExist(Arr) && WinActive("Ahk_exe exefile.exe") + try { + Hotkey( v["BackwardsHotkey"], ObjBindMethod(This, "Cycle_Hotkey_Groups",Arr,"BackwardsHotkey"), "P1") + } + catch ValueError as e { + MsgBox(e.Message ": --> " e.Extra " <-- in Profile Settings - " This.LastUsedProfile " Hotkey Groups - " k " - Backwards Hotkey" ) + } + } + } + } + } + } + + ; The method to make it possible to cycle throw the EVE Windows. Used with the Hotkey Groups + Cycle_Hotkey_Groups(Arr, direction,*) { + static Index := 0 + length := Arr.Length + + if (direction == "ForwardsHotkey") { + Try + Index := (n := IsActiveWinInGroup(This.CleanTitle(WinGetTitle("A")), Arr)) ? n+1 : 1 + + if (Index > length) + Index := 1 + + if (This.OneWinExist(Arr)) { + Try { + if !(WinExist("EVE - " This.CleanTitle(Arr[Index]))) { + while (!(WinExist("EVE - " This.CleanTitle(Arr[Index])))) { + index += 1 + if (Index > length) + Index := 1 + } + } + This.ActivateEVEWindow(,,This.CleanTitle(Arr[Index])) + } + } + } + + else if (direction == "BackwardsHotkey") { + Try + Index := (n := IsActiveWinInGroup(This.CleanTitle(WinGetTitle("A")), Arr)) ? n-1 : length + if (Index <= 0) + Index := length + + if (This.OneWinExist(Arr)) { + if !(WinExist("EVE - " This.CleanTitle(Arr[Index]))) { + while (!(WinExist("EVE - " This.CleanTitle(Arr[Index])))) { + Index -= 1 + if (Index <= 0) + Index := length + } + } + This.ActivateEVEWindow(,,This.CleanTitle(Arr[Index])) + } + } + + IsActiveWinInGroup(Title, Arr) { + for index, names in Arr { + if names = Title + return index + } + return false + } + } + + ; To Check if atleast One Win stil Exist in the Array for the cycle groups hotkeys + OneWinExist(Arr, *) { + for index, Name in Arr { + If WinExist("EVE - " Name " Ahk_Exe exefile.exe") + return true + } + return false + + } + + ;## Updates the Thumbnail in the GUI after Activation + ;## Do not Update thumbnails from minimized windows or this will leed in no picture for the Thumbnail + UpdateThumb_AfterActivation(event?, hwnd?) { + MinMax := -1 + try MinMax := WinGetMinMax("ahk_id " hwnd) + + if (This.ThumbWindows.HasProp(hwnd)) { + if !(MinMax == -1) { + This.Update_Thumb(false, This.ThumbWindows.%hwnd%["Window"].Hwnd) + } + } + } + + ;This function updates the Thumbnails and hotkeys if the user switches Charakters in the character selection screen + EVENameChange(hwnd, title) { + if (This.ThumbWindows.HasProp(hwnd)) { + This.SetThumbnailText[hwnd] := title + ; moves the Window to the saved positions if any stored, a bit of sleep is usfull to give the window time to move before creating the thumbnail + This.RestoreClientPossitions(hwnd, title) + + if (title = "") { + This.EvEWindowDestroy(hwnd, title) + This.EVE_WIN_Created(hwnd,title) + } + + else If (This.ThumbnailPositions.Has(title)) { + This.EvEWindowDestroy(hwnd, title) + This.EVE_WIN_Created(hwnd,title) + rect := This.ThumbnailPositions[title] + This.ShowThumb(hwnd, "Hide") + This.ThumbMove( rect["x"], + rect["y"], + rect["width"], + rect["height"], + This.ThumbWindows.%hwnd% ) + + This.BorderSize(This.ThumbWindows.%hwnd%["Window"].Hwnd, This.ThumbWindows.%hwnd%["Border"].Hwnd) + This.Update_Thumb(true) + If ( This.HideThumbnailsOnLostFocus && WinActive(This.EVEExe) || !This.HideThumbnailsOnLostFocus && !WinActive(This.EVEExe) || !This.HideThumbnailsOnLostFocus && WinActive(This.EVEExe)) { + for k, v in This.ThumbWindows.OwnProps() + This.ShowThumb(k, "Show") + } + } + This.BorderActive := 0 + This.RegisterHotkeys(title, hwnd) + } + } + + ;#### Gets Called after receiveing a mesage from the Listeners + ;#### Handels Window Border, Resize, Activation + _OnMessage(wparam, lparam, msg, hwnd) { + If (This.ThumbHwnd_EvEHwnd.Has(hwnd) ) { + + ; Move the Window with right mouse button + If (msg == Main_Class.WM_RBUTTONDOWN) { + while (GetKeyState("RButton")) { + + if !(GetKeyState("LButton")) { + ;sleep 1 + This.Mouse_DragMove(wparam, lparam, msg, hwnd) + This.Window_Snap(hwnd, This.ThumbWindows) + } + else + This.Mouse_ResizeThumb(wparam, lparam, msg, hwnd) + } + return 0 + } + + ; Wparam - 9 Ctrl+Lclick + ; 5 Shift+Lclick + ; 13 Shift+ctrl+click + Else If (msg == Main_Class.WM_LBUTTONDOWN) { + ;Activates the EVE Window by clicking on the Thumbnail + if (wparam = 1) { + if !(WinActive(This.ThumbHwnd_EvEHwnd[hwnd])) + This.ActivateEVEWindow(hwnd) + } + ; Ctrl+Lbutton, Minimizes the Window on whose thumbnail the user clicks + else if (wparam = 9) { + ; Minimize + if (!GetKeyState("RButton")) + PostMessage 0x0112, 0xF020, , , This.ThumbHwnd_EvEHwnd[hwnd] + } + return 0 + } + } + } + + ; Creates a new thumbnail if a new window got created + EVE_WIN_Created(Win_Hwnd, Win_Title) { + ; Moves the Window to the saved possition if any are stored + This.RestoreClientPossitions(Win_Hwnd, Win_Title) + + ;Creates the Thumbnail and stores the EVE Hwnd in the array + If !(This.ThumbWindows.HasProp(Win_Hwnd)) { + This.ThumbWindows.%Win_Hwnd% := This.Create_Thumbnail(Win_Hwnd, Win_Title) + This.ThumbHwnd_EvEHwnd[This.ThumbWindows.%Win_Hwnd%["Window"].Hwnd] := Win_Hwnd + + ;if the User is in character selection screen show the window always + if (This.ThumbWindows.%Win_Hwnd%["Window"].Title = "") { + This.SetThumbnailText[Win_Hwnd] := Win_Title + ;if the Title is just "EVE" that means it is in the Charakter selection screen + ;in this case show always the Thumbnail + This.ShowThumb(Win_Hwnd, "Show") + return + } + + ;if the user loged in into a Character then move the Thumbnail to the right possition + else If (This.ThumbnailPositions.Has(Win_Title)) { + This.SetThumbnailText[Win_Hwnd] := Win_Title + rect := This.ThumbnailPositions[Win_Title] + This.ThumbMove( rect["x"], + rect["y"], + rect["width"], + rect["height"], + This.ThumbWindows.%Win_Hwnd% ) + + This.BorderSize(This.ThumbWindows.%Win_Hwnd%["Window"].Hwnd, This.ThumbWindows.%Win_Hwnd%["Border"].Hwnd) + This.Update_Thumb(true) + If ( This.HideThumbnailsOnLostFocus && WinActive(This.EVEExe) || !This.HideThumbnailsOnLostFocus && !WinActive(This.EVEExe) || !This.HideThumbnailsOnLostFocus && WinActive(This.EVEExe)) { + for k, v in This.ThumbWindows.OwnProps() + This.ShowThumb(k, "Show") + } + } + This.RegisterHotkeys(Win_Title, Win_Hwnd) + } + } + + ;if a EVE Window got closed this destroyes the Thumbnail and frees the memory. + EvEWindowDestroy(hwnd?, WinTitle?) { + if (IsSet(hwnd) && This.ThumbWindows.HasProp(hwnd)) { + for k, v in This.ThumbWindows.Clone().%hwnd% { + if (K = "Thumbnail") + continue + v.Destroy() + ;This.ThumbWindows.%Win_Hwnd%.Delete() + } + This.ThumbWindows.DeleteProp(hwnd) + Return + } + ;If a EVE Windows get destroyed + for Win_Hwnd,v in This.ThumbWindows.Clone().OwnProps() { + if (!WinExist("Ahk_Id " Win_Hwnd)) { + for k,v in This.ThumbWindows.Clone().%Win_Hwnd% { + if (K = "Thumbnail") + continue + v.Destroy() + } + This.ThumbWindows.DeleteProp(Win_Hwnd) + } + } + This.DestroyThumbnailsToggle := 1 + } + + ActivateEVEWindow(hwnd?,ThisHotkey?, title?) { + ; If the user clicks the Thumbnail then hwnd stores the Thumbnail Hwnd. Here the Hwnd gets changed to the contiguous EVE window hwnd + if (IsSet(hwnd) && This.ThumbHwnd_EvEHwnd.Has(hwnd)) { + hwnd := WinExist(This.ThumbHwnd_EvEHwnd[hwnd]) + title := This.CleanTitle(WinGetTitle("Ahk_id " Hwnd)) + } + ;if the user presses the Hotkey + Else if (IsSet(title)) { + title := "EVE - " title + hwnd := WinExist(title " Ahk_exe exefile.exe") + } + ;return when the user tries to bring a window to foreground which is already in foreground + if (WinActive("Ahk_id " hwnd)) + Return + + If (DllCall("IsIconic", "UInt", hwnd)) { + if (This.AlwaysMaximize) || ( This.TrackClientPossitions && This.ClientPossitions[This.CleanTitle(title)]["IsMaximized"] ) { + ; ; Maximize + This.ShowWindowAsync(hwnd, 3) + } + else { + ; Restore + This.ShowWindowAsync(hwnd) + } + } + Else { + ; Use the virtual key to trigger the internal Hotkey. + This.ActivateHwnd := hwnd + SendEvent("{Blind}{" Main_Class.virtualKey "}") + } + + ;Sets the timer to minimize client if the user enable this. + if (This.MinimizeInactiveClients) { + This.wHwnd := hwnd + SetTimer(This.timer, -This.MinimizeDelay) + } + } + ;The function for the Internal Hotkey to bring a not minimized window in foreground + ActivateForgroundWindow(*) { + ; 2 attempts for brining the window in foreground + try { + if !(DllCall("SetForegroundWindow", "UInt", This.ActivateHwnd)) { + DllCall("SetForegroundWindow", "UInt", This.ActivateHwnd) + } + + ;If the user has selected to always maximize. this prevents wrong sized windows on heavy load. + if (This.AlwaysMaximize && WinGetMinMax("ahk_id " This.ActivateHwnd) = 0) || ( This.TrackClientPossitions && This.ClientPossitions[This.CleanTitle(WinGetTitle("Ahk_id " This.ActivateHwnd))]["IsMaximized"] && WinGetMinMax("ahk_id " This.ActivateHwnd) = 0 ) + This.ShowWindowAsync(This.ActivateHwnd, 3) + } + Return + } + + + + + ; Minimize All windows after Activting one with the exception of Titels in the DontMinimize Wintitels + ; gets called by the timer to run async + EVEMinimize() { + for EveHwnd, GuiObj in This.ThumbWindows.OwnProps() { + ThumbHwnd := GuiObj["Window"].Hwnd + try + WinTitle := WinGetTitle("Ahk_Id " EveHwnd) + catch + continue + + if (EveHwnd = This.wHwnd || Dont_Minimze_Enum(EveHwnd, WinTitle) || WinTitle == "EVE" || WinTitle = "") + continue + else { + ; Just to make sure its not minimizeing the active Window + if !(EveHwnd = WinExist("A")) { + This.ShowWindowAsync(EveHwnd, 11) + } + } + } + ;to check which names are in the list that should not be minimized + Dont_Minimze_Enum(hwnd, EVEwinTitle) { + WinTitle := This.CleanTitle(EVEwinTitle) + if !(WinTitle = "") { + for k in This.Dont_Minimize_Clients { + value := This.CleanTitle(k) + if value == WinTitle + return 1 + } + return 0 + } + } + } + + ; Function t move the Thumbnails into the saved positions from the user + ThumbMove(x := "", y := "", Width := "", Height := "", GuiObj := "") { + for Names, Obj in GuiObj { + if (Names = "Thumbnail") + continue + WinMove(x, y, Width, Height, Obj.Hwnd) + } + } + + ;Saves the possitions of all Windows and stores + Client_Possitions() { + IDs := WinGetList("Ahk_Exe " This.EVEExe) + for k, v in IDs { + Title := This.CleanTitle(WinGetTitle("Ahk_id " v)) + if !(Title = "") { + ;If Minimzed then restore before saving the coords + if (DllCall("IsIconic", "UInt", v)) { + This.ShowWindowAsync(v) + ;wait for getting Active for maximum of 2 seconds + if (WinWaitActive("Ahk_Id " v, , 2)) { + Sleep(200) + WinGetPos(&X, &Y, &Width, &Height, "Ahk_Id " v) + ;If the Window is Maximized + if (DllCall("IsZoomed", "UInt", v)) { + This.ClientPossitions[Title] := [X, Y, Width, Height, 1] + } + else { + This.ClientPossitions[Title] := [X, Y, Width, Height, 0] + } + + } + } + ;If the Window is not Minimized + else { + WinGetPos(&X, &Y, &Width, &Height, "Ahk_Id " v) + ;is the window Maximized? + if (DllCall("IsZoomed", "UInt", v)) { + This.ClientPossitions[Title] := [X, Y, Width, Height, 1] + } + else + This.ClientPossitions[Title] := [X, Y, Width, Height, 0] + } + } + } + SetTimer(This.Save_Settings_Delay_Timer, -200) + } + + ;Restore the clients to the saved positions + RestoreClientPossitions(hwnd, title) { + if (This.TrackClientPossitions) { + if ( This.TrackClientPossitions && This.ClientPossitions[title] ) { + if (DllCall("IsIconic", "UInt", hwnd) && This.ClientPossitions[title]["IsMaximized"] || DllCall("IsZoomed", "UInt", hwnd) && This.ClientPossitions[title]["IsMaximized"]) { + This.SetWindowPlacement(hwnd,This.ClientPossitions[title]["x"], This.ClientPossitions[title]["y"], + This.ClientPossitions[title]["width"], This.ClientPossitions[title]["height"], 9 ) + This.ShowWindowAsync(hwnd, 3) + Return + } + else if (DllCall("IsIconic", "UInt", hwnd) && !This.ClientPossitions[title]["IsMaximized"] || DllCall("IsZoomed", "UInt", hwnd) && !This.ClientPossitions[title]["IsMaximized"]) { + This.SetWindowPlacement(hwnd,This.ClientPossitions[title]["x"], This.ClientPossitions[title]["y"], + This.ClientPossitions[title]["width"], This.ClientPossitions[title]["height"], 9 ) + This.ShowWindowAsync(hwnd, 4) + Return + } + else if ( This.ClientPossitions[title]["IsMaximized"]) { + This.SetWindowPlacement(hwnd,This.ClientPossitions[title]["x"], This.ClientPossitions[title]["y"], + This.ClientPossitions[title]["width"], This.ClientPossitions[title]["height"] ) + This.ShowWindowAsync(hwnd, 3) + Return + } + else if ( !This.ClientPossitions[title]["IsMaximized"]) { + This.SetWindowPlacement(hwnd,This.ClientPossitions[title]["x"], This.ClientPossitions[title]["y"], + This.ClientPossitions[title]["width"], This.ClientPossitions[title]["height"], 4 ) + This.ShowWindowAsync(hwnd, 4) + Return + } + } + } + } + + + + ;*WinApi Functions + ;Gets the normal possition from the Windows. Not to use for Maximized Windows + GetWindowPlacement(hwnd) { + DllCall("User32.dll\GetWindowPlacement", "Ptr", hwnd, "Ptr", WP := Buffer(44)) + Lo := NumGet(WP, 28, "Int") ; X coordinate of the upper-left corner of the window in its original restored state + To := NumGet(WP, 32, "Int") ; Y coordinate of the upper-left corner of the window in its original restored state + Wo := NumGet(WP, 36, "Int") - Lo ; Width of the window in its original restored state + Ho := NumGet(WP, 40, "Int") - To ; Height of the window in its original restored state + + CMD := NumGet(WP, 8, "Int") ; ShowCMD + flags := NumGet(WP, 4, "Int") ; flags + MinX := NumGet(WP, 12, "Int") + MinY := NumGet(WP, 16, "Int") + MaxX := NumGet(WP, 20, "Int") + MaxY := NumGet(WP, 24, "Int") + WP := "" + + return { X: Lo, Y: to, W: Wo, H: Ho , cmd: CMD, flags: flags, MinX: MinX, MinY: MinY, MaxX: MaxX, MaxY: MaxY } + } + + ;Moves the window to the given possition immediately + SetWindowPlacement(hwnd:="", X:="", Y:="", W:="", H:="", action := 9) { + ;hwnd := hwnd = "" ? WinExist("A") : hwnd + DllCall("User32.dll\GetWindowPlacement", "Ptr", hwnd, "Ptr", WP := Buffer(44)) + Lo := NumGet(WP, 28, "Int") ; X coordinate of the upper-left corner of the window in its original restored state + To := NumGet(WP, 32, "Int") ; Y coordinate of the upper-left corner of the window in its original restored state + Wo := NumGet(WP, 36, "Int") - Lo ; Width of the window in its original restored state + Ho := NumGet(WP, 40, "Int") - To ; Height of the window in its original restored state + L := X = "" ? Lo : X ; X coordinate of the upper-left corner of the window in its new restored state + T := Y = "" ? To : Y ; Y coordinate of the upper-left corner of the window in its new restored state + R := L + (W = "" ? Wo : W) ; X coordinate of the bottom-right corner of the window in its new restored state + B := T + (H = "" ? Ho : H) ; Y coordinate of the bottom-right corner of the window in its new restored state + + NumPut("UInt",action,WP,8) + NumPut("UInt",L,WP,28) + NumPut("UInt",T,WP,32) + NumPut("UInt",R,WP,36) + NumPut("UInt",B,WP,40) + + Return DllCall("User32.dll\SetWindowPlacement", "Ptr", hwnd, "Ptr", WP) + } + + + ShowWindowAsync(hWnd, nCmdShow := 9) { + DllCall("ShowWindowAsync", "UInt", hWnd, "UInt", nCmdShow) + } + GetActiveWindow() { + Return DllCall("GetActiveWindow", "Ptr") + } + SetActiveWindow(hWnd) { + Return DllCall("SetActiveWindow", "Ptr", hWnd) + } + SetFocus(hWnd) { + Return DllCall("SetFocus", "Ptr", hWnd) + } + SetWindowPos(hWnd, x, y, w, h, hWndInsertAfter := 0, uFlags := 0x0020) { + ; SWP_FRAMECHANGED 0x0020 + ; SWP_SHOWWINDOW 0x40 + Return DllCall("SetWindowPos", "Ptr", hWnd, "Ptr", hWndInsertAfter, "Int", x, "Int", y, "Int", w, "Int", h, "UInt", uFlags) + } + + ;removes "EVE" from the Titel and leaves only the Character names + CleanTitle(title) { + Return RegExReplace(title, "^(?i)eve(?:\s*-\s*)?\b", "") + ;RegExReplace(title, "(?i)eve\s*-\s*", "") + + } + + SaveJsonToFile() { + FileDelete("EVE-X-Preview.json") + FileAppend(JSON.Dump(This._JSON, , " "), "EVE-X-Preview.json") + } +} + diff --git a/src/Propertys.ahk b/src/Propertys.ahk new file mode 100644 index 0000000..aa072f8 --- /dev/null +++ b/src/Propertys.ahk @@ -0,0 +1,600 @@ + + +class Propertys extends TrayMenu { + + + ;###################### + ;## Script Propertys + + SetThumbnailText[hwnd, *] { + set { + if (This.ThumbWindows.HasProp(hwnd)) { + ;RegExReplace(Value, "(EVE)(?: - )?", "") + newtext := Value + + for k, v in This.ThumbWindows.%hwnd% { + if (k = "Thumbnail" || k = "Border") + continue + if (k = "TextOverlay") { + for chwnd, cobj in v { + cobj.Value := newtext + ;ControlSetText "New Text Here", cobj + } + } + if (k = "Window") + v.Title := newtext + } + } + } + } + + Profiles => This._JSON["_Profiles"] + + + ;###################### + ;## global Settings + ThumbnailStartLocation[key] { + get => This._JSON["global_Settings"]["ThumbnailStartLocation"][key] + set => This._JSON["global_Settings"]["ThumbnailStartLocation"][key] := value + + + } + + Minimizeclients_Delay { + get => This._JSON["global_Settings"]["Minimize_Delay"] + set => This._JSON["global_Settings"]["Minimize_Delay"] := (value < 50 ? "50" : value) + } + + Suspend_Hotkeys_Hotkey { + get => This._JSON["global_Settings"]["Suspend_Hotkeys_Hotkey"] + set => This._JSON["global_Settings"]["Suspend_Hotkeys_Hotkey"] := value + } + + ThumbnailBackgroundColor { + get => convertToHex(This._JSON["global_Settings"]["ThumbnailBackgroundColor"]) + set => This._JSON["global_Settings"]["ThumbnailBackgroundColor"] := convertToHex(value) + } + + ThumbnailSnap[*] { + get => This._JSON["global_Settings"]["ThumbnailSnap"] + set => This._JSON["global_Settings"]["ThumbnailSnap"] := Value + } + + Global_Hotkeys { + get => This._JSON["global_Settings"]["Global_Hotkeys"] + set => This._JSON["global_Settings"]["Global_Hotkeys"] := value + } + + ThumbnailSnap_Distance { + get => This._JSON["global_Settings"]["ThumbnailSnap_Distance"] + set => This._JSON["global_Settings"]["ThumbnailSnap_Distance"] := (value ? value : "20") + } + + + ThumbnailMinimumSize[key] { + get => This._JSON["global_Settings"]["ThumbnailMinimumSize"][key] + set => This._JSON["global_Settings"]["ThumbnailMinimumSize"][key] := value + } + + + ;######################## + ;## Profile ThumbnailSettings + + ShowAllColoredBorders { + get => This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Settings"]["ShowAllColoredBorders"] + set => This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Settings"]["ShowAllColoredBorders"] := value + } + + LastUsedProfile { + get => This._JSON["global_Settings"]["LastUsedProfile"] + set => This._JSON["global_Settings"]["LastUsedProfile"] := value + } + + _ProfileProps { + get { + Arr := [] + for k in This._JSON["_Profiles"][This.LastUsedProfile] { + If (k = "Thumbnail Positions" || k = "Client Possitions") + continue + Arr.Push(k) + } + return Arr + } + } + + Thumbnail_visibility[key?] { + get { + return This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Visibility"] + + ; if IsSet(Key) { + ; Arr := Array() + ; for k, v in This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail_visibility"] + ; Arr.Push(k) + ; return Arr + ; } + ; else + ; return This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail_visibility"] + } + set { + if (IsObject(value)) { + This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Visibility"] := value + ; for k, v in Value { + ; This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail_visibility"][k] := v + ; } + } + This.Save_Settings() + + } + } + + + HideThumbnailsOnLostFocus { + get => This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Settings"]["HideThumbnailsOnLostFocus"] + set => This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Settings"]["HideThumbnailsOnLostFocus"] := value + } + ShowThumbnailsAlwaysOnTop { + get => This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Settings"]["ShowThumbnailsAlwaysOnTop"] + set => This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Settings"]["ShowThumbnailsAlwaysOnTop"] := value + } + + ThumbnailOpacity { + get { + percentage := This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Settings"]["ThumbnailOpacity"] + return Round((percentage < 0 ? 0 : percentage > 100 ? 100 : percentage) * 2.55) + } + set { + This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Settings"]["ThumbnailOpacity"] := Value + } + } + + ClientHighligtBorderthickness { + get => This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Settings"]["ClientHighligtBorderthickness"] + set => This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Settings"]["ClientHighligtBorderthickness"] := Trim(value, "`n ") + } + + ClientHighligtColor { + get => convertToHex(This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Settings"]["ClientHighligtColor"]) + set => This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Settings"]["ClientHighligtColor"] := convertToHex(Trim(value, "`n ")) + } + ShowClientHighlightBorder { + get => This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Settings"]["ShowClientHighlightBorder"] + set => This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Settings"]["ShowClientHighlightBorder"] := value + } + ThumbnailTextFont { + get => This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Settings"]["ThumbnailTextFont"] + set => This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Settings"]["ThumbnailTextFont"] := Trim(value, "`n ") + } + ThumbnailTextSize { + get => This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Settings"]["ThumbnailTextSize"] + set => This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Settings"]["ThumbnailTextSize"] := Trim(value, "`n ") + } + + ThumbnailTextColor { + get => convertToHex(This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Settings"]["ThumbnailTextColor"]) + set => This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Settings"]["ThumbnailTextColor"] := convertToHex(Trim(value, "`n ")) + } + ShowThumbnailTextOverlay { + get => This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Settings"]["ShowThumbnailTextOverlay"] + set => This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Settings"]["ShowThumbnailTextOverlay"] := value + } + ThumbnailTextMargins[var] { + get => This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Settings"]["ThumbnailTextMargins"][var] + set => This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Settings"]["ThumbnailTextMargins"][var] := Trim(value, "`n ") + + + } + + ;######################## + ;## Profile ClientSettings + + + CustomColorsGet[CName?] { + get { + name := "", nameIndex := 0, ctext := "", cBorder := "" + for index, names in This._JSON["_Profiles"][This.LastUsedProfile]["Custom Colors"]["cColors"]["CharNames"] { + if (names = CName) { + nameIndex := index + name := names + break + } + else + nameIndex := index + + } + if (nameIndex) { + if (This._JSON["_Profiles"][This.LastUsedProfile]["Custom Colors"]["cColors"]["Bordercolor"].Length >= nameIndex) { + cBorder := This._JSON["_Profiles"][This.LastUsedProfile]["Custom Colors"]["cColors"]["Bordercolor"][nameIndex] + } + if (This._JSON["_Profiles"][This.LastUsedProfile]["Custom Colors"]["cColors"]["TextColor"].Length >= nameIndex) + ctext := This._JSON["_Profiles"][This.LastUsedProfile]["Custom Colors"]["cColors"]["TextColor"][nameIndex] + } + return Map("Char", name, "Border", cBorder, "Text", ctext) + } + } + + + IndexcChars => This._JSON["_Profiles"][This.LastUsedProfile]["Custom Colors"]["cColors"]["CharNames"].Length + IndexcBorder => This._JSON["_Profiles"][This.LastUsedProfile]["Custom Colors"]["cColors"]["Bordercolor"].Length + IndexcText => This._JSON["_Profiles"][This.LastUsedProfile]["Custom Colors"]["cColors"]["TextColor"].Length + + CustomColors_AllCharNames { + get { + names := "" + for k, v in This._JSON["_Profiles"][This.LastUsedProfile]["Custom Colors"]["cColors"]["CharNames"] { + if (A_Index < This._JSON["_Profiles"][This.LastUsedProfile]["Custom Colors"]["cColors"]["CharNames"].Length) + names .= k ": " v "`n" + else + names .= k ": " v + } + return names + } + set { + tempvar := [] + ListChars := StrSplit(value, "`n") + for k, v in ListChars { + chars := RegExReplace(This.CleanTitle(Trim(v, "`n ")), ".*:\s*", "") + tempvar.Push(chars) + } + This._JSON["_Profiles"][This.LastUsedProfile]["Custom Colors"]["cColors"]["CharNames"] := tempvar + } + } + CustomColors_AllBColors { + get { + names := "" + for k, v in This._JSON["_Profiles"][This.LastUsedProfile]["Custom Colors"]["cColors"]["Bordercolor"] { + if (A_Index < This._JSON["_Profiles"][This.LastUsedProfile]["Custom Colors"]["cColors"]["Bordercolor"].Length) + names .= k ": " v "`n" + else + names .= k ": " v + } + return names + } + set { + tempvar := [] + ListChars := StrSplit(value, "`n") + for k, v in ListChars { + chars := RegExReplace(convertToHex(Trim(v, "`n ")), ".*:\s*", "") + tempvar.Push(chars) + } + This._JSON["_Profiles"][This.LastUsedProfile]["Custom Colors"]["cColors"]["Bordercolor"] := tempvar + } + } + CustomColors_AllTColors { + get { + names := "" + for k, v in This._JSON["_Profiles"][This.LastUsedProfile]["Custom Colors"]["cColors"]["TextColor"] { + if (A_Index < This._JSON["_Profiles"][This.LastUsedProfile]["Custom Colors"]["cColors"]["TextColor"].Length) + names .= k ": " v "`n" + else + names .= k ": " v + } + return names + } + set { + tempvar := [] + ListChars := StrSplit(value, "`n") + for k, v in ListChars { + chars := RegExReplace(convertToHex(Trim(v, "`n ")), ".*:\s*", "") + tempvar.Push(chars) + } + This._JSON["_Profiles"][This.LastUsedProfile]["Custom Colors"]["cColors"]["TextColor"] := tempvar + } + } + + + CustomColorsActive { + get => This._JSON["_Profiles"][This.LastUsedProfile]["Custom Colors"]["cColorActive"] + set => This._JSON["_Profiles"][This.LastUsedProfile]["Custom Colors"]["cColorActive"] := Value + } + + + MinimizeInactiveClients { + get => This._JSON["_Profiles"][This.LastUsedProfile]["Client Settings"]["MinimizeInactiveClients"] + set => This._JSON["_Profiles"][This.LastUsedProfile]["Client Settings"]["MinimizeInactiveClients"] := value + } + AlwaysMaximize { + get => This._JSON["_Profiles"][This.LastUsedProfile]["Client Settings"]["AlwaysMaximize"] + set => This._JSON["_Profiles"][This.LastUsedProfile]["Client Settings"]["AlwaysMaximize"] := value + } + TrackClientPossitions { + get => This._JSON["_Profiles"][This.LastUsedProfile]["Client Settings"]["TrackClientPossitions"] + set => This._JSON["_Profiles"][This.LastUsedProfile]["Client Settings"]["TrackClientPossitions"] := value + } + Dont_Minimize_Clients { + get => This._JSON["_Profiles"][This.LastUsedProfile]["Client Settings"]["Dont_Minimize_Clients"] + set { + This._JSON["_Profiles"][This.LastUsedProfile]["Client Settings"]["Dont_Minimize_Clients"] := [] + + For index, Client in StrSplit(Value, ["`n", ","]) { + if (Client = "") + continue + This._JSON["_Profiles"][This.LastUsedProfile]["Client Settings"]["Dont_Minimize_Clients"].Push(Trim(Client, "`n ")) + } + } + } + + ThumbnailPositions[wTitle?] { + get { + if (IsSet(wTitle)) + return This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Positions"][wTitle] + return This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Positions"] + } + set { + form := ["x", "y", "width", "height"] + + if !(This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Positions"].Has(wTitle)) + This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Positions"][wTitle] := Map() + + for v in form { + This._JSON["_Profiles"][This.LastUsedProfile]["Thumbnail Positions"][wTitle][v] := value[A_Index] + } + SetTimer(This.Save_Settings_Delay_Timer, -200) + } + + } + + ClientPossitions[wTitle] { + get { + if (This._JSON["_Profiles"][This.LastUsedProfile]["Client Possitions"].Has(wTitle)) + return This._JSON["_Profiles"][This.LastUsedProfile]["Client Possitions"][wTitle] + else + return 0 + } + set { + form := ["x", "y", "width", "height", "IsMaximized"] + if !(This._JSON["_Profiles"][This.LastUsedProfile]["Client Possitions"].Has(wTitle)) + This._JSON["_Profiles"][This.LastUsedProfile]["Client Possitions"][wTitle] := Map() + for v in form { + This._JSON["_Profiles"][This.LastUsedProfile]["Client Possitions"][wTitle][v] := value[A_Index] + } + + } + } + + ;######################## + ;## Profile Hotkeys + Hotkey_Groups[key?] { + get { + if (IsSet(key)) { + return This._JSON["_Profiles"][This.LastUsedProfile]["Hotkey Groups"][key] + } + else + return This._JSON["_Profiles"][This.LastUsedProfile]["Hotkey Groups"] + } + set { + This._JSON["_Profiles"][This.LastUsedProfile]["Hotkey Groups"][Key] := Map("Characters", value, "ForwardsHotkey", "", "BackwardsHotkey", "") + } + } + ; Hotkey_Groups_Hotkeys[Name?, Hotkey?] { + ; get { + + ; } + ; set { + ; This._JSON["_Profiles"][This.LastUsedProfile]["Hotkey_Groups"][Name][Hotkey] := Value + ; } + ; } + + + _Hotkeys[key?] { + get { + if (IsSet(Key)) { + loop This._JSON["_Profiles"][This.LastUsedProfile]["Hotkeys"].Length { + if (This._JSON["_Profiles"][This.LastUsedProfile]["Hotkeys"][A_Index].Has(key)) { + return This._JSON["_Profiles"][This.LastUsedProfile]["Hotkeys"][A_Index][key] + } + } + return 0 + } + if !(IsSet(Key)) + return This._JSON["_Profiles"][This.LastUsedProfile]["Hotkeys"] + } + set => This._JSON["_Profiles"][This.LastUsedProfile]["Hotkeys"] := Value + } + + _Hotkey_Delete(*) { + if (This.LV_Item) { + try { + HKey_Char_Name := This.LV.GetText(This.LV_Item) + if (This._Hotkeys.Has(HKey_Char_Name)) { + This._Hotkeys.Delete(HKey_Char_Name) + This.LV.Delete(This.LV_Item) + + ;This.Save_Settings() + } + } + } + } + + _Hotkey_Add(*) { + Obj := InputBox("Enter the Char Name", "Add New Char", "w200 h90") + if (Obj.Result = "OK") { + This._Hotkeys[Trim(Obj.Value, " ")] := "" + This.LV.Add(, Trim(Obj.Value, " ")) + + ;This.Save_Settings() + } + } + + _Hotkey_Edit(*) { + if (This.LV_Item) { + HKey_Char_Key := This.LV.GetText(This.LV_Item, 2), HKey_Char_Name := This.LV.GetText(This.LV_Item) + if (This._Hotkeys.Has(HKey_Char_Name)) { + Obj := InputBox(HKey_Char_Key, "Edit Hotkey for -> " HKey_Char_Name, "w250 h100") + if (Obj.Result = "OK") { + This._Hotkeys[HKey_Char_Name] := Trim(Obj.Value, " ") + This.LV.Modify(This.LV_Item, , , Trim(Obj.Value, " ")) + This.LV.Modify(This.LV_Item, "+Focus +Select") + + ;This.Save_Settings() + } + } + } + } + + + _Tv_LVSelectedRow(GuiCtrlObj, Item, Checked) { + Obj := Map() + if (GuiCtrlObj == This.Tv_LV) { + loop { + RowNumber := This.Tv_LV.GetNext(A_Index - 1, "Checked") + if not RowNumber ; The above returned zero, so there are no more selected rows. + break + + Obj[This.Tv_LV.GetText(RowNumber)] := 1 + This.Thumbnail_visibility[This.Tv_LV.GetText(RowNumber)] := 1 + ;MsgBox(GuiCtrlObj.value) + } + This.Thumbnail_visibility := Obj + SetTimer(This.Save_Settings_Delay_Timer, -200) + ;This.LV_Item := Item + ; ddd := GuiCtrlObj.GetText(Item) + ; ToolTip(Item ", " ddd " -, " Checked) + } + } + + + _LVSelectedRow(GuiCtrlObj, Item, Selected) { + if (GuiCtrlObj == This.LV && Selected) { + This.LV_Item := Item + ddd := GuiCtrlObj.GetText(Item) + ;ToolTip(Item ", " ddd " -, " Selected) + } + } + + + ;###################### + ;## Methods + + + Suspend_Hotkeys(*) { + static state := 0 + ToolTip() + state := !state + state ? ToolTip("Hotkeys disabled") : ToolTip("Hotkeys enabled") + Suspend(-1) + + SetTimer((*) => ToolTip(), -1500) + } + + Delete_Profile(*) { + if (This.SelectProfile_DDL.Text = "Default") { + MsgBox("You cannot delete the default settings") + Return + } + + if (This.SelectProfile_DDL.Text = This.LastUsedProfile) { + This.LastUsedProfile := "Default" + } + + This._JSON["_Profiles"].Delete(This.SelectProfile_DDL.Text) + + if (This.LastUsedProfile = "" || !This.Profiles.Has(This.LastUsedProfile)) + This.LastUsedProfile := "Default" + + ; FileDelete("EVE-X-Preview.json") + ; FileAppend(JSON.Dump(This._JSON, , " "), "EVE-X-Preview.json") + SetTimer(This.Save_Settings_Delay_Timer, -200) + + ;Index := This.SelectProfile_DDL.Value + This.SelectProfile_DDL.Delete(This.SelectProfile_DDL.Value) + This.SelectProfile_DDL.Redraw() + + for k, v in This.S_Gui.Controls.Profile_Settings.PsDDL { + for _, ob in v { + ob.Enabled := 0 + } + } + + ;This.S_Gui.Show("AutoSize") + } + + + Create_Profile(*) { + Obj := InputBox("Enter a Profile Name", "Create New Profile", "w200 h90") + if (Obj.Result != "OK" || Obj.Result = "") + return + if (This.Profiles.Has(Obj.value)) { + MsgBox("A profile with this name already exists") + return + } + if !(This.LastUsedProfile = "Default") { + Result := MsgBox("Do you want to use the current settings for the new profile?", , "YesNo") + } + else + Result := "No" + + if Result = "Yes" + This._JSON["_Profiles"][Obj.value] := JSON.Load(FileRead("EVE-X-Preview.json"))["_Profiles"][This.LastUsedProfile] + else if Result = "No" + This._JSON["_Profiles"][Obj.value] := This.default_JSON["_Profiles"]["Default"] + else + Return 0 + + FileDelete("EVE-X-Preview.json") + FileAppend(JSON.Dump(This._JSON, , " "), "EVE-X-Preview.json") + This.SelectProfile_DDL.Delete() + This.SelectProfile_DDL.Add(This.Profiles_to_Array()) + This.LastUsedProfile := "Default" + Return + } + Save_ThumbnailPossitions() { + for EvEHwnd, GuiObj in This.ThumbWindows.OwnProps() { + for Names, Obj in GuiObj { + if (Names = "Window" && Obj.Title = "" || Obj.Title = "EVE") + continue + Else if (Names = "Window") { + WinGetPos(&wX, &wY, &wWidth, &wHeight, Obj.Hwnd) + This.ThumbnailPositions[Obj.Title] := [wX, wY, wWidth, wHeight] + } + } + } + } + + ;### Stores the Thumbnail Size and Possitions in the Json file + Save_Settings() { + if !(This.Tray_Profile_scwitch) { + for EvEHwnd, GuiObj in This.ThumbWindows.OwnProps() { + for Names, Obj in GuiObj { + if (Names = "Window" && Obj.Title = "" || Obj.Title = "EVE") + continue + Else if (Names = "Window") { + WinGetPos(&wX, &wY, &wWidth, &wHeight, Obj.Hwnd) + This.ThumbnailPositions[Obj.Title] := [wX, wY, wWidth, wHeight] + } + } + } + } + SetTimer(This.Save_Settings_Delay_Timer, -200) + ; var := Json.Dump(This._JSON, , " ") + ; FileDelete("EVE-X-Preview.json") + ; FileAppend(var, "EVE-X-Preview.json") + } +} + + +;######################## +;## Functions + +Add_New_Profile() { + return +} + +convertToHex(rgbString) { + ; Check if the string corresponds to the decimal value format (e.g. "255, 255, 255" or "rgb(255, 255, 255)") + if (RegExMatch(rgbString, "^\s*(rgb\s*\(?)?\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)?\s*$", &matches)) { + red := matches[2], green := matches[3], blue := matches[4] + + ; covert decimal to hex + hexValue := Format("{:02X}{:02X}{:02X}", red, green, blue) + return hexValue + } + + ; Check whether the string corresponds to the hexadecimal value format (e.g "#FFFFFF" or "0xFFFFFF") + if (RegExMatch(rgbString, "^\s*(#|0x)?([0-9A-Fa-f]{6})\s*$", &matches)) { + hexValue := matches[2] + hexValue := StrLower(hexValue) + return hexValue + } + ; If no match was found or the string is already in hexadecimal value format, return directly + return rgbString +} diff --git a/src/Settings_Gui.ahk b/src/Settings_Gui.ahk new file mode 100644 index 0000000..a912431 --- /dev/null +++ b/src/Settings_Gui.ahk @@ -0,0 +1,862 @@ +Class Settings_Gui { + MainGui() { + ;if settings got chnaged which require a restart to apply + This.NeedRestart := 0 + + + ;MsgBox(This.CustomColorsGet["Example Char"]["Char"]) + + SetControlDelay(-1) + This.S_Gui := Gui("+OwnDialogs +MinimizeBox -Resize -MaximizeBox -DPIScale SysMenu +MinSize500x250") + This.S_Gui.Title := "EVE-X-Preview - Settings" + + ;Font options for the Buttons + This.S_Gui.SetFont("s10 w700") + + ;Sets Margins for the following Buttons + This.S_Gui.MarginX := 80, This.S_Gui.MarginY := 20 + This.S_Gui.Add("Button", " x140 y20 w120 h40 vGlobal_Settings", "Global Settings").OnEvent("Click", (obj, *) => Button_Handler(obj)) + This.S_Gui.Add("Button", "x+40 y+-40 wp hp vProfile_Settings", "Profile Settings").OnEvent("Click", (obj, *) => Button_Handler(obj)) + + This.S_Gui.Show("hide") + + ;Create the Arrays which hold the GUI objects for the controls + This.S_Gui.Controls := [], This.S_Gui.ClientSettings := [] + + ;Sets Margins for the following controls + This.S_Gui.MarginX := 25 + + ;Default Font options for the controls + This.S_Gui.SetFont("s9 w400") + ;Creates the Controls + This.Global_Settings(), This.Profile_Settings(), This.ClientSettings_Ctrl(), This.Custom_ColorsCtrl() + This.Hotkey_GroupsCtrl(), This.HotkeysCtrl(), This.ThumbnailSettings_Ctrl(), This.Thumbnail_visibilityCtrl() + + This.S_Gui.Show("AutoSize Center") + This._Button_Load() + + This.Seetings_DDL.OnEvent("Change", (Obj, *) => SettingsDDL_Handler(Obj)) + + This.S_Gui.OnEvent("Close", (*) => GuiDestroy()) + + GuiDestroy(*) { + This.S_Gui.Destroy() + if (This.NeedRestart) + Reload() + } + + SettingsDDL_Handler(Obj) { + for k, v in This.S_Gui.Controls.Profile_Settings.PsDDL { + if k = Obj.Text { + for _, ob in v + ob.Visible := 1 + } + else { + for _, ob in v + ob.Visible := 0 + } + } + This.S_Gui.Show("AutoSize") + } + + Button_Handler(obj) { + if (obj.Name = "Global_Settings") { + for ButtonName, Controls in This.S_Gui.Controls.OwnProps() { + if ButtonName = obj.Name { + for _, Ctrl in Controls { + Ctrl.Visible := 1 + } + } + else { + for _, Ctrl in Controls { + Ctrl.Visible := 0 + } + for _, Ctrl in This.S_Gui.Controls.Profile_Settings.PsDDL { + for k, v in Ctrl + v.Visible := 0 + } + + } + } + } + else if (obj.Name = "Profile_Settings") { + for ButtonName, Controls in This.S_Gui.Controls.OwnProps() { + if ButtonName = obj.Name { + for _, Ctrl in Controls { + Ctrl.Visible := 1 + } + for _, Ctrl in This.S_Gui.Controls.Profile_Settings.PsDDL { + if (This.Seetings_DDL.Text = _) { + for k, v in Ctrl { + v.Visible := 1 + } + } + } + } + else { + for _, Ctrl in Controls { + Ctrl.Visible := 0 + } + } + } + if (This.Profiles.Count = 1 && This.SelectProfile_DDL.Text = "Default") + MsgBox("you must first create a profile to change the settings") + } + + This.S_Gui.Show("AutoSize") + + + } + } + + ;This Function creates all Settings controls for the Global Settings Button + Global_Settings(visible?) { + This.S_Gui.Controls.Global_Settings := [] + This.S_Gui.SetFont("s10 w400") + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("GroupBox", "x20 y80 h280 w500") + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("Text", "xp+15 yp+20 Section", "Suspend Hotkeys - Hotkey:") + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("Text", "xs y+15", "Hotkey activation Scope:") + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("Text", "xs y+15", "Thumbnail Background Color:") + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("Text", "xs y+15", "Thumbnail Default Location:") + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("Text", "xs y+15", "Thumbnail Minimum Size:") + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("Text", "xs y+15", "Thumbnail Snap:") + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("Text", "xs y+15", "Thumbnail Snap Distance:") + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("Text", "xs y+15", "Minimize EVE Window Delay:") + + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("Edit", "xs+230 ys-3 w150 Section vSuspend_Hotkeys_Hotkey", This.Suspend_Hotkeys_Hotkey) + This.S_Gui["Suspend_Hotkeys_Hotkey"].OnEvent("Change", (obj, *) => gSettings_EventHandler(obj)) + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("DDL", "xp y+5 w180 vTTT vHotkey_Scoope Choose" (This.Global_Hotkeys ? 1 : 2), ["Global", "If an EVE window is Active"]) + This.S_Gui["Hotkey_Scoope"].OnEvent("Change", (obj, *) => gSettings_EventHandler(obj)) + + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("Edit", "xp y+5 w120 section vThumbnailBackgroundColor", This.ThumbnailBackgroundColor) + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("Text", "xp+130 yp+4", "Hex or RGB") + This.S_Gui["ThumbnailBackgroundColor"].OnEvent("Change", (obj, *) => gSettings_EventHandler(obj)) + + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("Text", "xs+2 y+17 section", "x:") + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("Edit", "x+5 y+-18 w40 vThumbnailStartLocationx", This.ThumbnailStartLocation["x"]) + This.S_Gui["ThumbnailStartLocationx"].OnEvent("Change", (obj, *) => gSettings_EventHandler(obj)) + + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("Text", "x+8 ys ", "y:") + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("Edit", "x+5 y+-18 w40 vThumbnailStartLocationy", This.ThumbnailStartLocation["y"]) + This.S_Gui["ThumbnailStartLocationy"].OnEvent("Change", (obj, *) => gSettings_EventHandler(obj)) + + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("Text", "x+8 ys ", "w:") + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("Edit", "x+5 y+-18 w40 vThumbnailStartLocationwidth", This.ThumbnailStartLocation["width"]) + This.S_Gui["ThumbnailStartLocationwidth"].OnEvent("Change", (obj, *) => gSettings_EventHandler(obj)) + + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("Text", "x+8 ys ", "h:") + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("Edit", "x+5 y+-18 w40 vThumbnailStartLocationheight", This.ThumbnailStartLocation["height"]) + This.S_Gui["ThumbnailStartLocationheight"].OnEvent("Change", (obj, *) => gSettings_EventHandler(obj)) + + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("Text", "xs y+10 section ", "width:") + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("Edit", "x+5 y+-18 w40 vThumbnailMinimumSizewidth", This.ThumbnailMinimumSize["width"]) + This.S_Gui["ThumbnailMinimumSizewidth"].OnEvent("Change", (obj, *) => gSettings_EventHandler(obj)) + + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("Text", "x+8 ys ", "height:") + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("Edit", "x+5 y+-18 w40 vThumbnailMinimumSizeheight", This.ThumbnailMinimumSize["height"]) + This.S_Gui["ThumbnailMinimumSizeheight"].OnEvent("Change", (obj, *) => gSettings_EventHandler(obj)) + + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("Radio", "xs y+10 w37 vThumbnailSnapOn Checked" This.ThumbnailSnap, "On") + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("Radio", " xp+50 yp w37 vThumbnailSnapOff Checked" (This.ThumbnailSnap ? 0 : 1), "Off") + This.S_Gui["ThumbnailSnapOn"].OnEvent("Click", (obj, *) => gSettings_EventHandler(obj)) + This.S_Gui["ThumbnailSnapOff"].OnEvent("Click", (obj, *) => gSettings_EventHandler(obj)) + + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("Text", "xs y+15 ", "pixel:") + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("Edit", "x+5 y+-18 w40 vThumbnailSnap_Distance", This.ThumbnailSnap_Distance) + This.S_Gui["ThumbnailSnap_Distance"].OnEvent("Change", (obj, *) => gSettings_EventHandler(obj)) + + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("Text", "xs y+9 ", "Milliseconds:") + This.S_Gui.Controls.Global_Settings.Push This.S_Gui.Add("Edit", "xp+80 yp-3 w40 vMinimizeclients_Delay", This.Minimizeclients_Delay) + This.S_Gui["Minimizeclients_Delay"].OnEvent("Change", (obj, *) => gSettings_EventHandler(obj)) + + gSettings_EventHandler(obj) { + if (obj.name = "Suspend_Hotkeys_Hotkey") { + This.Suspend_Hotkeys_Hotkey := Trim(obj.value, "`n ") + This.NeedRestart := 1 + } + else if (obj.name = "Hotkey_Scoope") { + This.Global_Hotkeys := (obj.value = 1 ? 1 : 0) + This.NeedRestart := 1 + } + else if (obj.name = "ThumbnailBackgroundColor") { + This.ThumbnailBackgroundColor := obj.value + This.NeedRestart := 1 + } + else if (obj.name = "ThumbnailStartLocationx") { + This.ThumbnailStartLocation["x"] := obj.value + } + else if (obj.name = "ThumbnailStartLocationy") { + This.ThumbnailStartLocation["y"] := obj.value + } + else if (obj.name = "ThumbnailStartLocationwidth") { + This.ThumbnailStartLocation["width"] := obj.value + } + else if (obj.name = "ThumbnailStartLocationheight") { + This.ThumbnailStartLocation["height"] := obj.value + } + else if (obj.name = "ThumbnailMinimumSizewidth") { + This.ThumbnailMinimumSize["width"] := obj.value + } + else if (obj.name = "ThumbnailMinimumSizeheight") { + This.ThumbnailMinimumSize["height"] := obj.value + } + else if (obj.name = "ThumbnailSnapOn") { + This.ThumbnailSnap := 1 + } + else if (obj.name = "ThumbnailSnapOff") { + This.ThumbnailSnap := 0 + } + else if (obj.name = "ThumbnailSnap_Distance") { + This.ThumbnailSnap_Distance := obj.value + } + else if (obj.name = "Minimizeclients_Delay") { + This.Minimizeclients_Delay := obj.value + This.NeedRestart := 1 + } + SetTimer(This.Save_Settings_Delay_Timer, -200) + } + } + + ;This Function creates all Settings controls for the Profile Settings Button + Profile_Settings(visible?) { + This.S_Gui.Controls.Profile_Settings := [], This.S_Gui.Controls.Profile_Settings.PsDDL := Map() + + ;This.S_Gui.Controls.Profile_Settings.Push This.S_Gui.Add("GroupBox", "x20 y80 h200 w500 vPSGroupBox", "") + This.S_Gui.Controls.Profile_Settings.Push This.S_Gui.Add("Text", "x58 y95", "Select Profile:") + + This.SelectProfile_DDL := This.S_Gui.Add("DDL", "w200 xp-30 yp+18 Section vSelectedProfile", This.Profiles_to_Array()) + This.S_Gui.Controls.Profile_Settings.Push This.SelectProfile_DDL + This.SelectProfile_DDL.Choose(This.LastUsedProfile) + This.SelectProfile_DDL.OnEvent("Change", (obj,*) => This._Button_Load(Obj)) + + Button_Delete := This.S_Gui.Add("Button", "w60 xs+360 yp-2 ", "Delete") + This.S_Gui.Controls.Profile_Settings.Push Button_Delete + Button_Delete.OnEvent("Click", ObjBindMethod(This, "Delete_Profile")) + + Button_New := This.S_Gui.Add("Button", "wp x+5 yp ", "New") + This.S_Gui.Controls.Profile_Settings.Push Button_New + Button_New.OnEvent("Click", ObjBindMethod(This, "Create_Profile")) + + ;*Seperator line + This.Seperator_text := This.S_Gui.Add("Text", "xs+15 y+5 w460 h2 +0x10") + This.S_Gui.Controls.Profile_Settings.Push This.Seperator_text + + This.S_Gui.Controls.Profile_Settings.Push This.S_Gui.Add("Text", "xp+190 y+5", "Profile Settings:") + + This.Seetings_DDL := This.S_Gui.Add("DDL", "w180 xp-40 y+5 vSeetings_Props", This._ProfileProps) + This.Seetings_DDL.Choose(1) + ;This.Seetings_DDL.OnEvent("Change", ObjBindMethod(This, "ProfileSettings_DDL")) + This.S_Gui.Controls.Profile_Settings.Push This.Seetings_DDL + + ;*Seperator line + This.S_Gui.Controls.Profile_Settings.Push This.S_Gui.Add("Text", "x150 yp+30 w260 h2 Section +0x10") + + ;Sets all controls invisible at beginning + for k, v in This.S_Gui.Controls.Profile_Settings + v.Visible := 0 + + } + + ClientSettings_Ctrl(visible?) { + This.S_Gui.Controls.Profile_Settings.PsDDL["Client Settings"] := [], ClientSettings := [] + + ClientSettings.Push This.S_Gui.Add("GroupBox", "x20 y80 h400 w500 Section", "") + ClientSettings.Push This.S_Gui.Add("Text", " xp+15 yp+140 Section ", "Minimize Inactive Clients:") + ClientSettings.Push This.S_Gui.Add("Text", "xs y+15 ", "Always Maximize Clients:") + ClientSettings.Push This.S_Gui.Add("Text", "xs y+15 ", "Dont Minimize Clients:") + + ClientSettings.Push This.S_Gui.Add("CheckBox", "xs+230 ys Section vMinimizeInactiveClients Checked" This.MinimizeInactiveClients, "On/Off") + This.S_Gui["MinimizeInactiveClients"].OnEvent("Click", (obj, *) => cSettings_EventHandler(obj)) + + ClientSettings.Push This.S_Gui.Add("CheckBox", "xs y+15 vAlwaysMaximize Checked" This.AlwaysMaximize, "On/Off") + This.S_Gui["AlwaysMaximize"].OnEvent("Click", (obj, *) => cSettings_EventHandler(obj)) + + ClientSettings.Push This.S_Gui.Add("Edit", "xs y+15 w220 h180 vDont_Minimize_Clients -Wrap", This.Dont_Minimize_List()) + This.S_Gui["Dont_Minimize_Clients"].OnEvent("Change", (obj, *) => cSettings_EventHandler(obj)) + + ;Pulls the GUI Object into the Map + This.S_Gui.Controls.Profile_Settings.PsDDL["Client Settings"] := ClientSettings + + for k, v in This.S_Gui.Controls.Profile_Settings.PsDDL["Client Settings"] + v.Visible := 0 + + cSettings_EventHandler(obj) { + if (obj.name = "MinimizeInactiveClients") { + This.MinimizeInactiveClients := obj.value + } + else if (obj.name = "AlwaysMaximize") { + This.AlwaysMaximize := obj.value + } + else if (obj.name = "TrackClientPossitions") { + This.TrackClientPossitions := obj.value + } + else if (obj.name = "Dont_Minimize_Clients") { + This.Dont_Minimize_Clients := obj.value + } + SetTimer(This.Save_Settings_Delay_Timer, -200) + } + } + + ;TODO Needs to be implemented - Add Propertys + ; User defined colurs per Client + Custom_ColorsCtrl() { + This.S_Gui.Controls.Profile_Settings.PsDDL["Custom Colors"] := [], CustomColors := [] + CustomColors.Push This.S_Gui.Add("GroupBox", "x20 y80 h480 w500 Section", "") + + CustomColors.Push This.S_Gui.Add("Text", " xp+25 yp+140 Section ", "Custom Colors Active On/Off") + CustomColors.Push This.S_Gui.Add("Text", " x70 yp+40 ", "Character name") + CustomColors.Push This.S_Gui.Add("Text", " xp+150 yp ", "Border Color") + CustomColors.Push This.S_Gui.Add("Text", " xp+130 yp ", "Text Color") + + CustomColors.Push This.S_Gui.Add("CheckBox", " xs+200 ys vCcoloractive Checked" This.CustomColorsActive, " ON / Off") + This.S_Gui["Ccoloractive"].OnEvent("Click", (obj, *) => Cclors_Eventhandler(obj)) + + CustomColors.Push This.S_Gui.Add("Edit", " x60 yp+60 w150 h250 -Wrap vCchars", This.CustomColors_AllCharNames) + This.S_Gui["Cchars"].OnEvent("Change", (obj, *) => Cclors_Eventhandler(obj)) + + CustomColors.Push This.S_Gui.Add("Edit", " x+10 yp w120 hp -Wrap vCBorderColor", This.CustomColors_AllBColors) + This.S_Gui["CBorderColor"].OnEvent("Change", (obj, *) => Cclors_Eventhandler(obj)) + + CustomColors.Push This.S_Gui.Add("Edit", " x+10 yp wp hp -Wrap vCTextColor", This.CustomColors_AllTColors) + This.S_Gui["CTextColor"].OnEvent("Change", (obj, *) => Cclors_Eventhandler(obj)) + + + This.S_Gui.Controls.Profile_Settings.PsDDL["Custom Colors"] := CustomColors + for k, v in This.S_Gui.Controls.Profile_Settings.PsDDL["Custom Colors"] + v.Visible := 0 + + Cclors_Eventhandler(obj) { + if (obj.Name = "Ccoloractive") { + This.CustomColorsActive := obj.value + } + else if (obj.Name = "Cchars") { + indexOld := This.IndexcChars + This.CustomColors_AllCharNames := obj.value + if (indexOld < This.IndexcChars) { + obj.value := This.CustomColors_AllCharNames + ControlSend("^{End}", obj.Hwnd) + } + This.NeedRestart := 1 + } + else if (obj.Name = "CBorderColor") { + indexOld := This.IndexcBorder + This.CustomColors_AllBColors := obj.value + if (indexOld < This.IndexcBorder) { + obj.value := This.CustomColors_AllBColors + ControlSend("^{End}", obj.Hwnd) + } + This.NeedRestart := 1 + } + else if (obj.Name = "CTextColor") { + indexOld := This.IndexcText + This.CustomColors_AllTColors := obj.value + if (indexOld < This.IndexcText) { + obj.value := This.CustomColors_AllTColors + ControlSend("^{End}", obj.Hwnd) + } + This.NeedRestart := 1 + } + SetTimer(This.Save_Settings_Delay_Timer, -200) + } + } + + + Hotkey_GroupsCtrl() { + This.S_Gui.Controls.Profile_Settings.PsDDL["Hotkey Groups"] := [], Hotkey_Groups := [] + + Hotkey_Groups.Push This.S_Gui.Add("GroupBox", "x20 y80 h440 w500 Section", "") + Hotkey_Groups.Push This.S_Gui.Add("Text", "x58 yp+130", "Select Group:") + ddl := This.S_Gui.Add("DropDownList", " xp-30 yp+18 w180 vHotkeyGroupDDL", This.GetGroupList()) + Hotkey_Groups.Push ddl + This.S_Gui["HotkeyGroupDDL"].OnEvent("Change", (*) => SetEditText(ddl, EditBox, HKForwards, HKBackwards)) + + DeleteButton := This.S_Gui.Add("Button", "xs+370 yp-1 w60", "Delete") + NewButton := This.S_Gui.Add("Button", "x+5 yp w60", "New") + DeleteButton.OnEvent("Click", (*) => Delete_Group(ddl, HKForwards, HKBackwards, EditBox)) + NewButton.OnEvent("Click", (*) => CreateNewGroup(ddl, HKForwards, HKBackwards, EditBox)) + + Hotkey_Groups.Push DeleteButton + Hotkey_Groups.Push NewButton + + EditBox := This.S_Gui.Add("Edit", "xs+8 y275 w250 h225 -Wrap +HScroll Disabled vHKCharlist") + Hotkey_Groups.Push EditBox + This.S_Gui["HKCharlist"].OnEvent("Change", (obj, *) => SaveHKGroupList(obj)) + + Hotkey_Groups.Push This.S_Gui.Add("Text", "xs300 yp20", "Forwards Hotkey:") + HKForwards := This.S_Gui.Add("Edit", "xp yp+20 w150 Disabled vForwardsKey") + Hotkey_Groups.Push HKForwards + This.S_Gui["ForwardsKey"].OnEvent("Change", (obj, *) => SaveHKGroupList(obj)) + + Hotkey_Groups.Push This.S_Gui.Add("Text", "xp yp50", "Backwards Hotkey:") + HKBackwards := This.S_Gui.Add("Edit", "xp yp+20 w150 Disabled vBackwardsdKey") + Hotkey_Groups.Push HKBackwards + This.S_Gui["BackwardsdKey"].OnEvent("Change", (obj, *) => SaveHKGroupList(obj)) + + This.S_Gui.Controls.Profile_Settings.PsDDL["Hotkey Groups"] := Hotkey_Groups + for k, v in This.S_Gui.Controls.Profile_Settings.PsDDL["Hotkey Groups"] + v.Visible := 0 + + + CreateNewGroup(ddlObj, ForwardHKObj, BackwardHKObj, EditObj) { + ArrayIndex := 0 + Obj := InputBox("Enter a Groupname", "Create New Group", "w200 h90") + if (Obj.Result != "OK") + return + This.Hotkey_Groups[Obj.value] := [] + ddlObj.Delete() + ddlObj.Add(This.GetGroupList()) + for k in This.Hotkey_Groups { + if k = Obj.value { + ArrayIndex := A_Index + break + } + } + EditObj.value := "", ForwardHKObj.value := "", BackwardHKObj.value := "" + ForwardHKObj.Enabled := 1, BackwardHKObj.Enabled := 1, EditObj.Enabled := 1 + ddlObj.Choose(ArrayIndex) + This.NeedRestart := 1 + SetTimer(This.Save_Settings_Delay_Timer, -200) + } + + Delete_Group(ddlObj, ForwardHKObj, BackwardHKObj, EditObj) { + if (ddlObj.Text != "" && This.Hotkey_Groups.Has(ddlObj.Text)) + This.Hotkey_Groups.Delete(ddlObj.Text) + + ddlObj.Delete() + ddlObj.Add(This.GetGroupList()) + ForwardHKObj.value := "", BackwardHKObj.value := "", EditObj.value := "" + ForwardHKObj.Enabled := 0, BackwardHKObj.Enabled := 0, EditObj.Enabled := 0 + This.NeedRestart := 1 + + SetTimer(This.Save_Settings_Delay_Timer, -200) + } + + SetEditText(ddlObj, EditObj, ForwardHKObj?, BackwardHKObj?) { + text := "" + if (ddlObj.Text != "" && This.Hotkey_Groups.Has(ddlObj.Text)) { + for index, Names in This.Hotkey_Groups[ddlObj.Text]["Characters"] { + text .= Names "`n" + } + EditObj.value := text, EditObj.Enabled := 1 + ForwardHKObj.value := This.Hotkey_Groups[ddlObj.Text]["ForwardsHotkey"], ForwardHKObj.Enabled := 1 + BackwardHKObj.value := This.Hotkey_Groups[ddlObj.Text]["BackwardsHotkey"], BackwardHKObj.Enabled := 1 + } + + + } + + SaveHKGroupList(obj) { + if (obj.Name = "HKCharlist" && ddl.Text != "") { + Arr := [] + for k, v in StrSplit(obj.value, "`n") { + Chars := Trim(v, "`n ") + if (Chars = "") + continue + Arr.Push(Chars) + } + This.Hotkey_Groups[ddl.Text]["Characters"] := Arr + } + else if (obj.Name = "ForwardsKey" && ddl.Text != "") { + This.Hotkey_Groups[ddl.Text]["ForwardsHotkey"] := Trim(obj.value, "`n ") + } + else if (obj.Name = "BackwardsdKey" && ddl.Text != "") { + This.Hotkey_Groups[ddl.Text]["BackwardsHotkey"] := Trim(obj.value, "`n ") + } + This.NeedRestart := 1 + SetTimer(This.Save_Settings_Delay_Timer, -200) + } + } + + + HotkeysCtrl() { + + This.S_Gui.Controls.Profile_Settings.PsDDL["Hotkeys"] := [], Hotkeys := [] + Hotkeys.Push This.S_Gui.Add("GroupBox", "x20 y80 h530 w500 Section", "") + + Charlist := "", Hklist := "" + for index, value in This._Hotkeys { + for name, hotkey in value { + Charlist .= name "`n" + Hklist .= hotkey "`n" + } + } + + Hotkeys.Push This.S_Gui.Add("Text", " x115 yp+130 section", "Charactername:") + HKCharList := This.S_Gui.Add("Edit", " xp-30 yp20 w180 h350 -Wrap vHotkeyCharList", Charlist) + Hotkeys.Push HKCharList + HKCharList.OnEvent("Change", (obj, *) => EventHandler(obj)) + + Hotkeys.Push This.S_Gui.Add("Text", " xs+210 ys", "Hotkeys:") + HKKeylist := This.S_Gui.Add("Edit", " xp-50 yp20 w180 h350 -Wrap vHotkeyList", Hklist) + Hotkeys.Push HKKeylist + HKKeylist.OnEvent("Change", (obj, *) => EventHandler(obj)) + + This.S_Gui.Controls.Profile_Settings.PsDDL["Hotkeys"] := Hotkeys + for k, v in This.S_Gui.Controls.Profile_Settings.PsDDL["Hotkeys"] + v.Visible := 0 + + ;Parse All hotkeys to a Array on value change + EventHandler(obj) { + tempvar := [] + ListChars := StrSplit(This.S_Gui["HotkeyCharList"].value, "`n"), ListHotkeys := StrSplit(This.S_Gui["HotkeyList"].value, "`n") + for k, v in ListChars { + chars := "", keys := "" + if (A_Index <= ListChars.Length) { + chars := Trim(ListChars[A_Index], "`n ") + } + if (A_Index <= ListHotkeys.Length) { + keys := Trim(ListHotkeys[A_Index], "`n ") + } + if (A_Index > ListHotkeys.Length) { + keys := "" + } + if (chars = "") + continue + tempvar.Push Map(chars, keys) + } + this._Hotkeys := tempvar + This.NeedRestart := 1 + SetTimer(This.Save_Settings_Delay_Timer, -200) + } + + } + + ThumbnailSettings_Ctrl() { + This.S_Gui.Controls.Profile_Settings.PsDDL["Thumbnail Settings"] := [], ThumbnailSettings := [] + + ThumbnailSettings.Push This.S_Gui.Add("GroupBox", "x20 y80 h530 w500 Section", "") + + ThumbnailSettings.Push This.S_Gui.Add("Text", "xp+15 yp+140 Section", "Show Thumbnail Text Overlay:") + ThumbnailSettings.Push This.S_Gui.Add("Text", " xs y+15 ", "Thumbnail Text Color:") + ThumbnailSettings.Push This.S_Gui.Add("Text", " xs y+15 ", "Thumbnail Text Size:") + ThumbnailSettings.Push This.S_Gui.Add("Text", " xs y+15 ", "Thumbnail Text Font:") + ThumbnailSettings.Push This.S_Gui.Add("Text", " xs y+15 ", "Thumbnail Text Margins:") + ThumbnailSettings.Push This.S_Gui.Add("Text", " xs y+15 ", "Client Highligt Color:") + ThumbnailSettings.Push This.S_Gui.Add("Text", " xs y+15 ", "Client Highligt Border thickness:") + ThumbnailSettings.Push This.S_Gui.Add("Text", " xs y+15 ", "Show Client Highlight Border:") + ThumbnailSettings.Push This.S_Gui.Add("Text", " xs y+15 ", "Hide Thumbnails On Lost Focus:") + ThumbnailSettings.Push This.S_Gui.Add("Text", " xs y+15 ", "Thumbnail Opacity:") + ThumbnailSettings.Push This.S_Gui.Add("Text", " xs y+15 ", "Show Thumbnails AlwaysOnTop:") + + ThumbnailSettings.Push This.S_Gui.Add("CheckBox", "xs+230 ys Section vShowThumbnailTextOverlay Checked" This.ShowThumbnailTextOverlay, "On/Off") + This.S_Gui["ShowThumbnailTextOverlay"].OnEvent("Click", (obj, *) => ThumbnailSettings_EventHandler(obj)) + + ThumbnailSettings.Push This.S_Gui.Add("Edit", "xs y+11 w120 vThumbnailTextColor -Wrap", This.ThumbnailTextColor) + ThumbnailSettings.Push This.S_Gui.Add("Text", " x+5 yp+3 ", "Hex or RGB") + This.S_Gui["ThumbnailTextColor"].OnEvent("Change", (obj, *) => ThumbnailSettings_EventHandler(obj)) + + ThumbnailSettings.Push This.S_Gui.Add("Edit", "xs y+10 w30 vThumbnailTextSize -Wrap", This.ThumbnailTextSize) + This.S_Gui["ThumbnailTextSize"].OnEvent("Change", (obj, *) => ThumbnailSettings_EventHandler(obj)) + + ThumbnailSettings.Push This.S_Gui.Add("Edit", "xs y+8 w120 vThumbnailTextFont -Wrap", This.ThumbnailTextFont) + This.S_Gui["ThumbnailTextFont"].OnEvent("Change", (obj, *) => ThumbnailSettings_EventHandler(obj)) + + ThumbnailSettings.Push This.S_Gui.Add("Text", " xs y+12", "width px:") + ThumbnailSettings.Push This.S_Gui.Add("Edit", "x+5 yp-4 w40 vThumbnailTextMarginsx -Wrap", This.ThumbnailTextMargins["x"]) + This.S_Gui["ThumbnailTextMarginsx"].OnEvent("Change", (obj, *) => ThumbnailSettings_EventHandler(obj)) + + ThumbnailSettings.Push This.S_Gui.Add("Text", " xs+100 yp+4 ", "height px:") + ThumbnailSettings.Push This.S_Gui.Add("Edit", "xp+60 yp-4 w40 vThumbnailTextMarginsy -Wrap", This.ThumbnailTextMargins["y"]) + This.S_Gui["ThumbnailTextMarginsy"].OnEvent("Change", (obj, *) => ThumbnailSettings_EventHandler(obj)) + + ThumbnailSettings.Push This.S_Gui.Add("Edit", "xs y+7 w120 vClientHighligtColor -Wrap", This.ClientHighligtColor) + ThumbnailSettings.Push This.S_Gui.Add("Text", " x+5 yp+3 ", "Hex or RGB") + This.S_Gui["ClientHighligtColor"].OnEvent("Change", (obj, *) => ThumbnailSettings_EventHandler(obj)) + + + ThumbnailSettings.Push This.S_Gui.Add("Text", " xs y+15 ", "px:") + ThumbnailSettings.Push This.S_Gui.Add("Edit", "x+5 yp-3 w30 vClientHighligtBorderthickness -Wrap", This.ClientHighligtBorderthickness) + This.S_Gui["ClientHighligtBorderthickness"].OnEvent("Change", (obj, *) => ThumbnailSettings_EventHandler(obj)) + + ThumbnailSettings.Push This.S_Gui.Add("CheckBox", "xs y+10 vShowClientHighlightBorder Checked" This.ShowClientHighlightBorder, "On/Off") + This.S_Gui["ShowClientHighlightBorder"].OnEvent("Click", (obj, *) => ThumbnailSettings_EventHandler(obj)) + + ThumbnailSettings.Push This.S_Gui.Add("CheckBox", "xs y+16 vHideThumbnailsOnLostFocus Checked" This.HideThumbnailsOnLostFocus, "On/Off") + This.S_Gui["HideThumbnailsOnLostFocus"].OnEvent("Click", (obj, *) => ThumbnailSettings_EventHandler(obj)) + + ThumbnailSettings.Push This.S_Gui.Add("Text", " xs y+15 ", "%") + ThumbnailSettings.Push This.S_Gui.Add("Edit", "x+4 yp-4 w40 vThumbnailOpacity -Wrap", IntegerToPercentage(This.ThumbnailOpacity)) + This.S_Gui["ThumbnailOpacity"].OnEvent("Change", (obj, *) => ThumbnailSettings_EventHandler(obj)) + + ThumbnailSettings.Push This.S_Gui.Add("CheckBox", "xs y+12 vShowThumbnailsAlwaysOnTop Checked" This.ShowThumbnailsAlwaysOnTop, "On/Off") + This.S_Gui["ShowThumbnailsAlwaysOnTop"].OnEvent("Click", (obj, *) => ThumbnailSettings_EventHandler(obj)) + + + This.S_Gui.Controls.Profile_Settings.PsDDL["Thumbnail Settings"] := ThumbnailSettings + for k, v in This.S_Gui.Controls.Profile_Settings.PsDDL["Thumbnail Settings"] { + v.Visible := 0 + } + + ;Parse All hotkeys to a Array on value change + ThumbnailSettings_EventHandler(obj) { + if (obj.name = "ShowThumbnailTextOverlay") { + This.ShowThumbnailTextOverlay := obj.value + This.NeedRestart := 1 + } + else if (obj.name = "ThumbnailTextColor") { + This.ThumbnailTextColor := obj.value + This.NeedRestart := 1 + } + else if (obj.name = "ThumbnailTextSize") { + This.ThumbnailTextSize := obj.value + This.NeedRestart := 1 + } + else if (obj.name = "ThumbnailTextFont") { + This.ThumbnailTextFont := obj.value + This.NeedRestart := 1 + } + else if (obj.name = "ThumbnailTextMarginsx") { + This.ThumbnailTextMargins["x"] := obj.value + This.NeedRestart := 1 + } + else if (obj.name = "ThumbnailTextMarginsy") { + This.ThumbnailTextMargins["y"] := obj.value + This.NeedRestart := 1 + } + else if (obj.name = "ClientHighligtColor") { + This.ClientHighligtColor := obj.value + This.NeedRestart := 1 + } + else if (obj.name = "ClientHighligtBorderthickness") { + This.ClientHighligtBorderthickness := obj.value + This.NeedRestart := 1 + } + else if (obj.name = "ShowClientHighlightBorder") { + This.ShowClientHighlightBorder := obj.value + } + else if (obj.name = "HideThumbnailsOnLostFocus") { + This.HideThumbnailsOnLostFocus := obj.value + } + else if (obj.name = "ThumbnailOpacity") { + This.ThumbnailOpacity := obj.value + This.NeedRestart := 1 + } + else if (obj.name = "ShowThumbnailsAlwaysOnTop") { + This.ShowThumbnailsAlwaysOnTop := obj.value + This.NeedRestart := 1 + } + + SetTimer(This.Save_Settings_Delay_Timer, -200) + } + } + + Thumbnail_visibilityCtrl() { + This.S_Gui.Controls.Profile_Settings.PsDDL["Thumbnail Visibility"] := [], Thumbnail_visibility := [] + + Thumbnail_visibility.Push This.S_Gui.Add("GroupBox", "x20 y80 h610 w500 Section", "") + Thumbnail_visibility.Push This.S_Gui.Add("Text", "xp+140 yp+130 w250", "Select any Client to hide the Thumbnail") + This.Tv_LV := This.S_Gui.Add("ListView", "xp+15 yp+30 w210 Checked -LV0x10 -Multi r20 -Sort vVisibility_List", ["Client Name "]) + Thumbnail_visibility.Push This.Tv_LV + + for k, v in This.compare_openclients_with_list() { + if (k != "EVE" || v != "") { + if This.Thumbnail_visibility.Has(v) + This.Tv_LV.Add("Check", v,) + else + This.Tv_LV.Add("", v,) + } + } + + + This.Tv_LV.ModifyCol(1, 150), This.Tv_LV.ModifyCol(2, 115) + This.Tv_LV.OnEvent("ItemCheck", ObjBindMethod(This, "_Tv_LVSelectedRow")) + + This.S_Gui.Controls.Profile_Settings.PsDDL["Thumbnail Visibility"] := Thumbnail_visibility + for k, v in This.S_Gui.Controls.Profile_Settings.PsDDL["Thumbnail Visibility"] + v.Visible := 0 + + + } + + On_WM_MOUSEMOVE(wParam, lParam, msg, Hwnd) { + static PrevHwnd := 0 + if (Hwnd != PrevHwnd) { + Text := "", ToolTip() ; Turn off any previous tooltip. + CurrControl := GuiCtrlFromHwnd(Hwnd) + if CurrControl { + if !CurrControl.HasProp("ToolTip") + return ; No tooltip for this control. + Text := CurrControl.ToolTip + SetTimer () => ToolTip(Text), -1000 + SetTimer () => ToolTip(), -4000 ; Remove the tooltip. + } + PrevHwnd := Hwnd + } + } + + Profiles_to_Array() { + ll := [] + for k, v in This.Profiles + ll.Push(k) + return ll + } + + Dont_Minimize_List() { + list := "" + for k in This.Dont_Minimize_Clients { + list .= k "`n" + } + return list + } + + _Button_Load(obj?,*) { + if (IsSet(obj)) + This.NeedRestart := 1 + + This.LastUsedProfile := This.S_Gui["SelectedProfile"].Text + This.Refresh_ControlValues() + + if (This.S_Gui["SelectedProfile"].Text = "Default") { + for k, v in This.S_Gui.Controls.Profile_Settings.PsDDL { + for _, ob in v { + ob.Enabled := 0 + } + } + } + SetTimer(This.Save_Settings_Delay_Timer, -200) + } + + Refresh_ControlValues() { + ; Global Settings + This.S_Gui["Suspend_Hotkeys_Hotkey"].value := This.Suspend_Hotkeys_Hotkey + This.S_Gui["Hotkey_Scoope"].value := (This.Global_Hotkeys ? 1 : 2) + This.S_Gui["ThumbnailBackgroundColor"].value := This.ThumbnailBackgroundColor + This.S_Gui["ThumbnailStartLocationx"].value := This.ThumbnailStartLocation["x"] + This.S_Gui["ThumbnailStartLocationy"].value := This.ThumbnailStartLocation["y"] + This.S_Gui["ThumbnailStartLocationwidth"].value := This.ThumbnailStartLocation["width"] + This.S_Gui["ThumbnailStartLocationheight"].value := This.ThumbnailStartLocation["height"] + This.S_Gui["ThumbnailMinimumSizewidth"].value := This.ThumbnailMinimumSize["width"] + This.S_Gui["ThumbnailMinimumSizeheight"].value := This.ThumbnailMinimumSize["height"] + This.S_Gui["ThumbnailSnapOn"].value := This.ThumbnailSnap + This.S_Gui["ThumbnailSnapOff"].value := (This.ThumbnailSnap ? 0 : 1) + This.S_Gui["ThumbnailSnap_Distance"].value := This.ThumbnailSnap_Distance + + ;Client Settings + This.S_Gui["MinimizeInactiveClients"].value := This.MinimizeInactiveClients + This.S_Gui["Minimizeclients_Delay"].value := This.Minimizeclients_Delay + This.S_Gui["AlwaysMaximize"].value := This.AlwaysMaximize + This.S_Gui["Dont_Minimize_Clients"].value := This.Dont_Minimize_List() + + ;Custom Colors + This.S_Gui["Ccoloractive"].value := This.CustomColorsActive + This.S_Gui["Cchars"].value := This.CustomColors_AllCharNames + This.S_Gui["CBorderColor"].value := This.CustomColors_AllBColors + This.S_Gui["CTextColor"].value := This.CustomColors_AllTColors + + + ;Hotkey Groups + This.S_Gui["HotkeyGroupDDL"].Delete() + This.S_Gui["HotkeyGroupDDL"].Add(This.GetGroupList()) + This.S_Gui["ForwardsKey"].value := "", This.S_Gui["ForwardsKey"].Enabled := 0 + This.S_Gui["BackwardsdKey"].value := "", This.S_Gui["BackwardsdKey"].Enabled := 0 + This.S_Gui["HKCharlist"].value := "", This.S_Gui["HKCharlist"].Enabled := 0 + + ;Hotkeys + Charlist := "", Hklist := "" + for index, value in This._Hotkeys { + for name, hotkey in value { + Charlist .= name "`n" + Hklist .= hotkey "`n" + } + } + This.S_Gui["HotkeyCharList"].value := Charlist + This.S_Gui["HotkeyList"].value := Hklist + + ;Thumbnail Settings + This.S_Gui["ShowThumbnailTextOverlay"].value := This.ShowThumbnailTextOverlay + This.S_Gui["ThumbnailTextColor"].value := This.ThumbnailTextColor + This.S_Gui["ThumbnailTextSize"].value := This.ThumbnailTextSize + This.S_Gui["ThumbnailTextFont"].value := This.ThumbnailTextFont + This.S_Gui["ThumbnailTextMarginsx"].value := This.ThumbnailTextMargins["x"] + This.S_Gui["ThumbnailTextMarginsy"].value := This.ThumbnailTextMargins["y"] + This.S_Gui["ClientHighligtColor"].value := This.ClientHighligtColor + This.S_Gui["ClientHighligtBorderthickness"].value := This.ClientHighligtBorderthickness + This.S_Gui["ShowClientHighlightBorder"].value := This.ShowClientHighlightBorder + This.S_Gui["HideThumbnailsOnLostFocus"].value := This.HideThumbnailsOnLostFocus + This.S_Gui["ThumbnailOpacity"].value := IntegerToPercentage(This.ThumbnailOpacity) + This.S_Gui["ShowThumbnailsAlwaysOnTop"].value := This.ShowThumbnailsAlwaysOnTop + + ;Thumbnail Visibility + This.S_Gui["Visibility_List"].Delete() + for k, v in This.compare_openclients_with_list() { + if (k != "EVE" || v != "") { + if This.Thumbnail_visibility.Has(v) + This.Tv_LV.Add("Check", v,) + else + This.Tv_LV.Add("", v,) + } + } + + for k, v in This.S_Gui.Controls.Profile_Settings.PsDDL { + for _, ob in v { + ob.Enabled := 1 + } + This.S_Gui["HKCharlist"].Enabled := 0 + This.S_Gui["ForwardsKey"].Enabled := 0 + This.S_Gui["BackwardsdKey"].Enabled := 0 + } + } + + + compare_openclients_with_list() { + EvENameList := [] + for EveHwnd in This.ThumbWindows.OwnProps() { + try { + if title := This.CleanTitle(WinGetTitle("Ahk_Id " EveHwnd) = "") { + continue + } + EvENameList.Push This.CleanTitle(WinGetTitle("Ahk_Id " EveHwnd)) + } + } + return EvENameList + } + + + GetGroupList() { + List := [] + if (IsObject(This.Hotkey_Groups)) { + for k in This.Hotkey_Groups { + List.Push(k) + } + return List + } + else + return [] + } + + +} +;Class End + + +IntegerToPercentage(integerValue) { + percentage := (integerValue < 0 ? 0 : integerValue > 255 ? 100 : Round(integerValue * 100 / 255)) + return percentage +} + + +CompareArrays(arr1, arr2) { + commonValues := {} + + for _, value in arr1 { + if (IsInArray(value, arr2)) + commonValues.%value% := 1 + else + commonValues.%value% := 0 + } + + for _, value in arr2 { + if (!IsInArray(value, arr1)) + commonValues.%value% := 0 + } + + return commonValues +} + +IsInArray(value, arr) { + for _, item in arr { + if (item = value) + return true + } + return false +} diff --git a/src/ThumbWindow.ahk b/src/ThumbWindow.ahk new file mode 100644 index 0000000..b68160a --- /dev/null +++ b/src/ThumbWindow.ahk @@ -0,0 +1,410 @@ + + + +Class ThumbWindow extends Propertys { + Create_Thumbnail(Win_Hwnd, Win_Title) { + ThumbObj := Map() + ; Remove the "EVE -" part from the Titel to show only the Name and if no Name is present yet show nothing + + ThumbObj["Window"] := Gui("+Owner +LastFound AlwaysOnTop -Caption +ToolWindow -DPIScale +E0x08000000", Win_Title) ;WS_EX_NOACTIVATE -> +E0x08000000 + ThumbObj["Window"].OnEvent("Close", GUI_Close_Button) + + ; The Backcolor which is visible when no thumbnail is displayed + Try + ThumbObj["Window"].BackColor := This.ThumbnailBackgroundColor + catch as e { + ThumbObj["Window"].BackColor := 0x57504e + This.ThumbnailBackgroundColor := 0x57504e + ThumbObj["Window"].BackColor := This.ThumbnailBackgroundColor + MsgBox( "Invalid Color: Global Settings -> Thumbnail Background Color`n`nUse the following syntax:`n HEX =>: #FFFFFF or 0xFFFFFF or FFFFFF`nRGB =>: 255, 255, 255 or rgb(255, 255, 255)`n`nColor is now set to default") + } + + ;Enable Shadow + DllCall("Dwmapi\DwmExtendFrameIntoClientArea", + "Ptr", ThumbObj["Window"].Hwnd, ; HWND hWnd + "Ptr", This.margins, ; MARGINS *pMarInset + ) + + + ;Set The Opacity who is set in the JSON File, its important to set this on the MainWindow and not on the Thumbnail itself + WinSetTransparent(This.ThumbnailOpacity) + + ;creates the GUI but Hides it + ThumbObj["Window"].Show("Hide") + WinMove( This.ThumbnailStartLocation["x"], + This.ThumbnailStartLocation["y"], + This.ThumbnailStartLocation["width"], + This.ThumbnailStartLocation["height"] + ) + + + ;#### Register Thumbnail + ; gets the EVE Window sizes + WinGetClientPos(, , &W, &H, "ahk_id " Win_Hwnd) + + ; These values for the Thumbnails should not be touched + ThumbObj["Thumbnail"] := LiveThumb(Win_Hwnd, ThumbObj["Window"].Hwnd) + ThumbObj["Thumbnail"].Source := [0, 0, W, H] + ThumbObj["Thumbnail"].Destination := [0, 0, This.ThumbnailStartLocation["width"], This.ThumbnailStartLocation["height"]] + ThumbObj["Thumbnail"].SourceClientAreaOnly := True + ThumbObj["Thumbnail"].Visible := True + ThumbObj["Thumbnail"].Opacity := 255 + ThumbObj["Thumbnail"].Update() + + + ;#### Create the Thumbnail TextOverlay + ;#### + ThumbObj["TextOverlay"] := Gui("AlwaysOnTop +LastFound -Caption +E0x20 +Owner" ThumbObj["Window"].Hwnd, Win_Title) ; WS_EX_CLICKTHROUGH -> +E0x20 + ThumbObj["TextOverlay"].MarginX := This.ThumbnailTextMargins["x"] + ThumbObj["TextOverlay"].MarginY := This.ThumbnailTextMargins["y"] + + CheckError := 0 + if (This.CustomColorsActive) { + if (This.CustomColorsGet[Win_Title]["Char"] != "" && This.CustomColorsGet[Win_Title]["Text"] != "") { + try { + ThumbObj["TextOverlay"].SetFont("s" This.ThumbnailTextSize " q6 w500 c" This.CustomColorsGet[Win_Title]["Text"] , This.ThumbnailTextFont) + } + catch as e { + CheckError := 1 + MsgBox("Error: Thumbnail Text Color is wrong´nin: Profile Settings - " This.LastUsedProfile " - Custom Colors -> " Win_Title "`nUse the following syntax:`n HEX =>: #FFFFFF or 0xFFFFFF or FFFFFF`nRGB =>: 255, 255, 255 or rgb(255, 255, 255)") + } + } + else + CheckError := 1 + } + + if (CheckError || !This.CustomColorsActive) { + try { + ThumbObj["TextOverlay"].SetFont("s" This.ThumbnailTextSize " q6 w500 c" This.ThumbnailTextColor, This.ThumbnailTextFont) + } + catch as e { + MsgBox("Error: Thumbnail Text Color Or Thumbnail Text Font are wrong´nin: Profile Settings - " This.LastUsedProfile " - Thumbnail Settings`nUse the following syntax:`n HEX =>: #FFFFFF or 0xFFFFFF or FFFFFF`nRGB =>: 255, 255, 255 or rgb(255, 255, 255)`nValues are now Set to Default") + This.ThumbnailTextSize := "12", This.ThumbnailTextColor := "0xfac57a", This.ThumbnailTextFont := "Gill Sans MT" + ThumbObj["TextOverlay"].SetFont("s" This.ThumbnailTextSize " q6 w500 c" This.ThumbnailTextColor, This.ThumbnailTextFont) + } + } + + ThumbTitle := ThumbObj["TextOverlay"].Add("Text", "vOverlayText w" This.ThumbnailStartLocation["width"], Win_Title) + ;Sets a Color for the Text Control to make it also invisible, same as background color + ThumbTitle.Opt("+Background040101") + + ThumbObj["TextOverlay"].BackColor := "040101" ;Sets a Color for the Text Control to make it also invisible, same as background color + WinSetTransColor("040101") + + ThumbObj["TextOverlay"].Show("Hide") + WinMove(This.ThumbnailStartLocation["x"], + This.ThumbnailStartLocation["y"], + This.ThumbnailStartLocation["width"], + This.ThumbnailStartLocation["height"] + ) + + + ;#### Create Borders + ;#### + border_thickness := This.ClientHighligtBorderthickness + border_color := This.ClientHighligtColor + + ThumbObj["Border"] := Gui("-Caption +E0x20 +Owner" ThumbObj["Window"].Hwnd) + + CheckError := 0 + if (This.CustomColorsActive) { + if (This.CustomColorsGet[Win_Title]["Char"] != "" && This.CustomColorsGet[Win_Title]["Border"] != "") { + try { + ThumbObj["Border"].BackColor := This.CustomColorsGet[Win_Title]["Border"] + } + catch as e { + CheckError := 1 + MsgBox("Error: Client Highligt Color are wrong´nin: Profile Settings - " This.LastUsedProfile " - Custom Colors - " Win_Title "`nUse the following syntax:`n HEX =>: #FFFFFF or 0xFFFFFF or FFFFFF`nRGB =>: 255, 255, 255 or rgb(255, 255, 255)") + } + } + else + CheckError := 1 + } + + + if (CheckError || !This.CustomColorsActive) { + try { + ThumbObj["Border"].BackColor := border_color + } + catch as e { + MsgBox("Error: Client Highligt Color are wrong´nin: Profile Settings - " This.LastUsedProfile " - Thumbnail Settings`nUse the following syntax:`n HEX =>: #FFFFFF or 0xFFFFFF or FFFFFF`nRGB =>: 255, 255, 255 or rgb(255, 255, 255)`nValues are now Set to Default") + This.ClientHighligtColor := "0xe36a0d" + ThumbObj["Border"].BackColor := This.ClientHighligtColor + } + } + + size := This.BorderSize(ThumbObj["Window"].Hwnd, ThumbObj["Border"].Hwnd) + + ThumbObj["Border"].Show("w" size.w " h" size.h " x" size.x " y" size.y "NoActivate Hide") + + return ThumbObj + + GUI_Close_Button(*) { + return + } + } + + BorderSize(DesinationHwnd, BorderHwnd) { + border_thickness := This.ClientHighligtBorderthickness + + WinGetPos(&dx, &dy, &dw, &dh, DesinationHwnd) + + offset := 0 + outerX := offset + outerY := offset + outerX2 := dw - offset + outerY2 := dh - offset + + innerX := border_thickness + offset + innerY := border_thickness + offset + innerX2 := dw - border_thickness - offset + innerY2 := dh - border_thickness - offset + + newX := dx + newY := dy + newW := dw + newH := dh + + WinSetRegion(outerX "-" outerY " " outerX2 "-" outerY " " outerX2 "-" outerY2 " " outerX "-" outerY2 " " outerX "-" outerY " " innerX "-" innerY " " innerX2 "-" innerY " " innerX2 "-" innerY2 " " innerX "-" innerY2 " " innerX "-" innerY, BorderHwnd) + + return { x: newX, y: newY, w: newW, h: newH } + + } + + ;## Moves the Window by holding down the Right Mousebutton + ;## By Holding CTRL and SHIFT it moves all Windows + Mouse_DragMove(wparam, lparam, msg, hwnd) { + This.Resize := 1 + dragging := 0 + ThumbMap := Map() + + MouseGetPos(&x0, &y0, &window_id) ;gets the current Mouse possition + if !(This.ThumbHwnd_EvEHwnd.Has(window_id)) + return + WinGetPos &wx, &wy, &wn, &wh, window_id ;gets the current window possition what the user clicks on + + ;Store the current size and position of all Thumbnails + for ThumbIDs in This.ThumbHwnd_EvEHwnd { + if (ThumbIDs == This.ThumbHwnd_EvEHwnd[hwnd]) + continue + if This.ThumbWindows.HasProp(This.ThumbHwnd_EvEHwnd[ThumbIDs]) { + for k, v in This.ThumbWindows.%This.ThumbHwnd_EvEHwnd[ThumbIDs]% { + WinGetPos(&Tempx, &Tempy, , , v.Hwnd) + ThumbMap[v.Hwnd] := { x: Tempx, y: Tempy } + } + } + } + + while (GetKeyState("RButton") && !GetKeyState("LButton")) { + + ;Moves a Single Window + MouseGetPos &x, &y + Nx := x - x0, NEUx := wx + Nx ;Nx -> stores the pixel diffrenz from Start to stop Moveing, NEUx -> Calculates the new Position + Ny := y - y0, NEUy := wy + Ny ;Ny -> stores the pixel diffrenz from Start to stop Moveing, NEUy -> Calculates the new Position + if This.ThumbWindows.HasProp(This.ThumbHwnd_EvEHwnd[hwnd]) { + for k, v in This.ThumbWindows.%This.ThumbHwnd_EvEHwnd[hwnd]% { + WinMove(NEUx, NEUy, , , v.Hwnd) + } + } + + ;Moves all windows + if (wparam = 10) { ; Ctrl+RButton + for k, v in This.ThumbWindows.OwnProps() { + for type, Obj in v { + if (hwnd == Obj.Hwnd) + continue + ;Calculates the new Position for all the other Windows + Ax := ThumbMap[Obj.Hwnd].x + Nx + Ay := ThumbMap[Obj.Hwnd].y + Ny + + WinMove(Ax, Ay, , , Obj.Hwnd) + } + } + } + } + } + + + ; wparam, lparam, msg, hwnd + Mouse_ResizeThumb(wparam, lparam, msg, hwnd) { + This.Resize := 0 + while (GetKeyState("LButton") && GetKeyState("RButton")) { + Sleep 10 + if !(This.Resize) { + WinGetPos(&Rx, &Ry, &Width, &Height, hwnd) + MouseGetPos(&Bx, &By) + This.Resize := 1 + } + MouseGetPos(&DragX, &DragY) + x := DragX - Bx, Wn := Width + x + y := DragY - BY, Wh := Height + y + + + ;ensures that the minimum size cannot be undershot + if (Wn < This.ThumbnailMinimumSize["width"]) { + Wn := This.ThumbnailMinimumSize["width"] + } + if (Wh < This.ThumbnailMinimumSize["height"]) { + Wh := This.ThumbnailMinimumSize["height"] + } + + for k, v in This.ThumbWindows.%This.ThumbHwnd_EvEHwnd[hwnd]% { + WinMove(, , Wn, Wh, v.hwnd) + } + This.Update_Thumb(false, hwnd) + This.BorderSize(This.ThumbWindows.%This.ThumbHwnd_EvEHwnd[hwnd]%["Window"].Hwnd, This.ThumbWindows.%This.ThumbHwnd_EvEHwnd[hwnd]%["Border"].Hwnd) + + if (!GetKeyState("LCtrl")) { + for ThumbIDs in This.ThumbHwnd_EvEHwnd { + if (ThumbIDs == This.ThumbHwnd_EvEHwnd[hwnd]) + continue + for k, v in This.ThumbWindows.%This.ThumbHwnd_EvEHwnd[ThumbIDs]% { + if k = "Window" + window := v.Hwnd + WinMove(, , Wn, Wh, v.Hwnd) + if (k = "Border") { + border := v.Hwnd + } + if (k = "TextOverlay") { + TextOverlay := v.Hwnd + ;WinMove(,,Wn,Wh, v.Hwnd ) + continue + } + + } + This.BorderSize(window, border) + } + This.Update_Thumb() + + } + } + + } + + ; Snaps the window to the nearest corner of another window if it is within SnapRange in pixels + Window_Snap(hwnd, GuiObject, SnapRange := 20) { + if (This.ThumbnailSnap) { + SnapRange := This.ThumbnailSnap_Distance + ;stores the coordinates of the corners from moving window + WinGetPos(&X, &Y, &Width, &Height, hwnd) + A_RECT := { TL: [X, Y], + TR: [X + Width, Y], + BL: [X, Y + Height], + BR: [X + Width, Y + Height] } + + destX := X, destY := Y, shouldMove := false + ;loops through all created GUIs and checks the distanz between the corners + for index, _Gui in GuiObject.OwnProps() { + if (hwnd = _Gui["Window"].Hwnd) { + continue + } + WinGetPos(&X, &Y, &Width, &Height, _Gui["Window"].Hwnd) + Gui_RECT := { TL: [X, Y], + TR: [X + Width, Y], + BL: [X, Y + Height], + BR: [X + Width, Y + Height] } + + for _, corner in A_RECT.OwnProps() { + for _, neighborCorner in Gui_RECT.OwnProps() { + dist := Distance(corner, neighborCorner) + if (dist <= SnapRange) { + shouldMove := true + destX := neighborCorner[1] - (corner = A_RECT.TR || corner = A_RECT.BR ? Width : 0) + destY := neighborCorner[2] - (corner = A_RECT.BL || corner = A_RECT.BR ? Height : 0) + } + } + } + } + ;If some window is in range then Snap the moving window into it + ; Snap the full GUI Obj stack + if (shouldMove) { + for k, v in This.ThumbWindows.%This.ThumbHwnd_EvEHwnd[hwnd]% + WinMove(destX, destY, , , v.Hwnd) + } + } + ;Nested Function for the Window Calculation + Distance(pt1, pt2) { + return Sqrt((pt1[1] - pt2[1]) ** 2 + (pt1[2] - pt2[2]) ** 2) + } + } + + ShowThumb(EVEWindowHwnd, HideOrShow) { + try + title := WinGetTitle("Ahk_Id " EVEWindowHwnd) + catch + title := 0 + if (!This.Thumbnail_visibility.Has(This.CleanTitle(title))) { + if (HideOrShow = "Show") { + for k, v in This.ThumbWindows.%EVEWindowHwnd% { + if (k = "Thumbnail") + continue + if (k = "Border" && !This.ShowAllColoredBorders) || (k = "TextOverlay" && !This.ShowThumbnailTextOverlay) + continue + + This.ThumbWindows.%EVEWindowHwnd%[k].Show("NoActivate") + This.ThumbWindows.%EVEWindowHwnd%["TextOverlay"].Show("NoActivate") + } + } + else { + if (This.ThumbWindows.%EVEWindowHwnd%["Window"].Title = "") { + This.ThumbWindows.%EVEWindowHwnd%["Border"].Show("Hide") + return + } + for k, v in This.ThumbWindows.%EVEWindowHwnd% { + if (k = "Thumbnail") + continue + This.ThumbWindows.%EVEWindowHwnd%[k].Show("Hide") + } + } + } + } + + + Update_Thumb(AllOrOne := true, ThumbHwnd?) { + If (AllOrOne && !IsSet(ThumbHwnd)) { + for EvEHwnd, ThumbObj in This.ThumbWindows.OwnProps() { + for Name, Obj in ThumbObj { + if (Name = "Window") { + WinGetPos(, , &TWidth, &THeight, Obj.Hwnd) + WinGetClientPos(, , &EWidth, &EHeight, "Ahk_Id" EvEHwnd) + ThumbObj["Thumbnail"].Source := [0, 0, EWidth, EHeight] + ThumbObj["Thumbnail"].Destination := [0, 0, TWidth, THeight] + ThumbObj["Thumbnail"].Update() + } + } + } + } + else { + If (IsSet(ThumbHwnd)) { + WinGetPos(, , &TWidth, &THeight, ThumbHwnd) + WinGetClientPos(, , &EWidth, &EHeight, This.ThumbHwnd_EvEHwnd[ThumbHwnd]) + ThumbObj := This.ThumbWindows.%This.ThumbHwnd_EvEHwnd[ThumbHwnd]% + ThumbObj["Thumbnail"].Source := [0, 0, EWidth, EHeight] + ThumbObj["Thumbnail"].Destination := [0, 0, TWidth, THeight] + ThumbObj["Thumbnail"].Update() + } + } + + } + + ShowActiveBorder(EVEHwnd?, ThumbHwnd?) { + if (IsSet(EVEHwnd) && This.ShowClientHighlightBorder) { + if (This.ThumbWindows.HasProp(EVEHwnd) && !This.ShowAllColoredBorders) { + for EW_Hwnd, Objs in This.ThumbWindows.OwnProps() { + for names, GuiObj in Objs { + if (names = "Border") { + GuiObj.Show("Hide") + } + } + } + } + + if !(This.Thumbnail_visibility.Has(This.CleanTitle(WinGetTitle("Ahk_Id " EVEHwnd)))) { + Show_Border := This.ThumbWindows.%EVEHwnd%["Border"] + Show_Border.Show("NoActivate") + } + } + } +} + + \ No newline at end of file diff --git a/src/TrayMenu.ahk b/src/TrayMenu.ahk new file mode 100644 index 0000000..d2b9fc1 --- /dev/null +++ b/src/TrayMenu.ahk @@ -0,0 +1,93 @@ + + +Class TrayMenu extends Settings_Gui { + TrayMenuObj := A_TrayMenu + Saved_overTray := 0 + Tray_Profile_scwitch := 0 + + TrayMenu() { + Profiles_Submenu := Menu() + + for k in This.Profiles { + If (k = This.LastUsedProfile) { + Profiles_Submenu.Add(This.LastUsedProfile, MenuHandler) + Profiles_Submenu.Check(This.LastUsedProfile) + } + Profiles_Submenu.Add(k, MenuHandler) + } + + ;Profiles_Submenu.Add() ;*Seperator line + + TrayMenu := This.TrayMenuObj + TrayMenu.Delete() ; Delete the Default TrayMenu Items + + TrayMenu.Add("Open", MenuHandler) + TrayMenu.Add() ; Seperator + TrayMenu.Add("Profiles", Profiles_Submenu) + TrayMenu.Add() ; Seperator + TrayMenu.Add("Suspend Hotkeys", MenuHandler) + TrayMenu.Add() + TrayMenu.Add() + TrayMenu.Add("Close all EVE Clients", (*) => This.CloseAllEVEWindows()) + TrayMenu.Add() + TrayMenu.Add() + TrayMenu.Add("Restore Client Positions", MenuHandler) + if (This.TrackClientPossitions) + TrayMenu.check("Restore Client Positions") + else + TrayMenu.Uncheck("Restore Client Positions") + + TrayMenu.Add("Save Client Positions", (*) => This.Client_Possitions()) + TrayMenu.Add() + TrayMenu.Add() + TrayMenu.Add("Save Thumbnail Positions", MenuHandler) ; Creates a separator line. + TrayMenu.Add("Reload", (*) => Reload()) + TrayMenu.Add() + TrayMenu.Add("Exit", (*) => ExitApp()) ; Creates a new menu item. + TrayMenu.Default := "Open" + + MenuHandler(ItemName, ItemPos, MyMenu) { + If (ItemName = "Exit") + ExitApp + Else if (ItemName = "Save Thumbnail Positions") { + ;* Saved Thumbnail Positions only if the Saved button is used on the Traymenu + This.Save_ThumbnailPossitions + } + Else if (ItemName = "Restore Client Positions") { + This.TrackClientPossitions := !This.TrackClientPossitions + TrayMenu.ToggleCheck("Restore Client Positions") + SetTimer(This.Save_Settings_Delay_Timer, -200) + } + Else if (This.Profiles.Has(ItemName)) { + This.Tray_Profile_scwitch := 1 + This.LastUsedProfile := ItemName + This.Save_Settings() + This.Tray_Profile_scwitch := 0 + Reload() + } + Else if (ItemName = "Open") { + if WinExist("EVE-X-Preview - Settings") { + WinActivate("EVE-X-Preview - Settings") + Return + } + This.MainGui() + } + Else If (ItemName = "Suspend Hotkeys") { + Suspend(-1) + TrayMenu.ToggleCheck("Suspend Hotkeys") + } + + } + } + + CloseAllEVEWindows(*) { + try { + list := WinGetList("Ahk_Exe exefile.exe") + GroupAdd("EVE", "Ahk_Exe exefile.exe") + for k in list { + PostMessage 0x0112, 0xF060, , , k + Sleep(50) + } + } + } +}