sounds good man, thanks for the feedback
i'm putting back in -duration, adding images, and converting to an options parameter now, i'll get a new version up shortly
- gwarble
edit:
HugoV:
got back to it, no images yet but try this for no corner rounding, option testing, color control, let me know what oyu think about the usage syntax for your script
;
; Notify() Version 0.2
; made by gwarble - sept 09
;
; for displaying multiple tray area notifications
;
; Notify([Message,Title,Duration,Action,FontColor,FontSize,GuiColor,StartGN,MaxGuiCount])
;
; thanks to Rhys and engunneer [Toaster Popups]
; test with [Ctrl-Shift-1] [^+1] if Notify.ahk is run
;
;=== To Fix:
;=== fill gaps from removed notifications if fit (might not be worth the wingetpos processing...?, and may not be desireable)
;=== or shift left a "column" width for more than monitor height allows
;=== or collapse open not's on new not or on close not (with delay)
;=== one last global to remove for label name... don't know if its possible
;=== flashing could be improved with options
;=== position could be controlable, could be moveable once open (stickies, reminders, etc)
;=== GN/maxcount need to be made parametric (for now it starts at 11: and allows 40)
;=== flash only works with odd number of flashing not's (easy to fix but may change functionality instead)
;=== have an Options parameter, for color/size/font stuff, position/size stuff, time action, click action, instead of so many parameters, parse internally...
;===
;====================================================================================
;====================================================================================
Notify_Demo1: ;=== in case Notify.ahk is run instead of #include-d
; Notify("Notify()","This is a sample notification.`nIt will last for 15 seconds unless clicked.`nNotify.ahk is meant to be #Include-d.`nDownload Notifier for a working example.`n`nCtrl-Shift-F12 for more...`n`nThanks for trying!",15)
Notify("f","f",13,"TC=Red GR=2 BT=2")
Notify("f","f",13,"TC=Red GR=4 BT=2")
Notify("f","f",13,"TC=Red GR=6 BT=2")
Notify("f","f",13,"TC=Red GR=9 BT=2 BC=Red")
Notify()
Notify()
Notify()
Hotkey, ^+F12, Notify_Demo2
Return
Notify_Demo2:
Notify()
Notify("Notification:","This one won't go away unless clicked",0)
Hotkey, ^+F12, Notify_Demo3
Return
Notify_Demo3:
; NotifyID := Notify("Test Notify","This notification will close in 2 seconds...", 2, "","Red", 8, "Black")
NotifyID := Notify()
Hotkey, ^+F12, Notify_Demo1
Return
;====================================================================================
;====================================================================================
Notify(Title="Notification!!!",Message="",Duration=15,Options="")
{
Static ;=== assume-static mode for arrays of options
Critical ;=== don't allow interruption
;Global Notify_Action := Action ;=== global Action label name, i don't know a way to keep actions but not have a global
static GF := 11 ;GF is Initial GN ;=== defaults if no options
static GL := 30 ;GM is Last GN ;=== options are saved between calls (ie only set once)
static GC := "FFFFAA" ;GC is Gui Color
static GR := 9 ;GR is Gui Radius
static TS := 8 ;TS is Title Font Size
static TW := 625 ;TW is Title Font Weight
static TC := "Black" ;TC is Title Font Color
static TF := "Arial" ;TF is Title Font
static MS := 8 ;MS is Message Font Size
static MW := 550 ;MW is Message Font Weight
static MC := "Black" ;MC is Message Font Color
static MF := "Arial" ;MF is Message Font
static BC := "Black" ;BC is Border Color
static BT := 2 ;BT is Border Thickness
static BF := 150 ;BF is Border Flash Speed
static AC := "" ;AC is Clicked Action (gosub label when clicked)
static AT := "" ;AT is Action Timeout (gosub label when timeout)
static AI := "" ;AI is Action In (not really useful, is it? an action upon creation)
static SC := 300 ;SC is Speed Clicked (AnimateWindow time)
static SI := 250 ;SI is Speed In (AnimateWindow time)
static ST := 100 ;SO is Speed TimeOut (AnimateWindow time)
If (Options) ;=== parse Options parameter
Loop,Parse,Options,%A_Space%
If (Option:= SubStr(A_LoopField,1,2))
%Option%:= SubStr(A_LoopField,4) ;=== two letter option and = (GF=1) means value starts at 4 (needs to strip quotes if used)
GN := GF
Loop ;=== max notifications, Notify() uses twice the max (for background) so 5 notifications use 10 gui numbers
IfNotInString, NotifyList, % "|" GN ;=== check if this notification exists
Break ;=== if not, make it
Else ;=== if so
If (++GN > GL) ;=== increment GN, check if under maxcount
GN := GF ;Return 0 ;=== If so, recheck, if not, return 0 ERROR (process by your script, if succedes returns guiID) (should save somehow and show when possible)
NotifyList .= "|" GN ;=== add GN to list of open guis, | delimeted
GN2 := GN + GL - GF + 1 ;=== gui number for background gui
Prev_DetectHiddenWindows := A_DetectHiddenWindows ;=== save current DetectHiddenWindows settings
Prev_TitleMatchMode := A_TitleMatchMode ;=== save current TitleMatchMode settings
DetectHiddenWindows On ;=== needed for winexist()
SetTitleMatchMode 1 ;=== needed for winexist()
If (WinExist("NotifyGui")) ;=== find all Notify() gui's from any scripts for placement
WinGetPos, OtherX, OtherY ;=== change this to a loop for all windows, not just first found by winexist()
DetectHiddenWindows %Prev_DetectHiddenWindows% ;=== restore script settings
SetTitleMatchMode %Prev_TitleMatchMode% ;=== restore script settings
Gui, %GN2%:Destroy ; - remove these once unnecessary
Gui, %GN%:Destroy ; - remove these once unnecessary
Gui, %GN%:-Caption +ToolWindow +AlwaysOnTop -Border ;=== notification gui creation
Gui, %GN%:Color, %GC%
Gui, %GN%:Font, w%TW% s%TS% c%TC%
If (Title)
Gui, %GN%:Add, Text, gNotify_Action, % Title
Gui, %GN%:Font, w%MW% s%MS% c%MC%
If ((Title) && (Message))
Gui, %GN%:Margin, , -5
If (Message)
Gui, %GN%:Add, Text, gNotify_Action, % Message
If ((Title) && (Message))
Gui, %GN%:Margin, , 8
Gui, %GN%:Show, Hide, NotifyGui
Gui %GN%:+LastFound
WinGetPos, GUIX, GUIY, GW, GH
Gui, %GN%:Add, Text, x0 y0 w%GW% h%GH% gNotify_Action BackgroundTrans ;=== for clicking anywhere on the notification instead of just the text
WinSet, Region, % "0-0 w" GW " h" GH " R" GR "-" GR ;=== round corners of notification, notification gui creation END
SysGet, Workspace, MonitorWorkArea ;=== initial placement
NewX := WorkSpaceRight-GW-5
If (OtherY)
NewY := OtherY-GH-5
Else
NewY := WorkspaceBottom-GH-5
If NewY < % WorkspaceTop
NewY := WorkspaceBottom-GH-5 ;=== initial placement END
Gui, %GN2%:-Caption +ToolWindow +AlwaysOnTop -Border +E0x20 ;=== background gui
Gui, %GN2%:Color, %BC%
Gui %GN2%:+LastFound
WinSet, Region, % "0-0 w" GW+(BT*2) " h" GH+(BT*2) " R" GR "-" GR
WinSet, Transparent, 105 ;=== background gui END
Gui, %GN2%:Show, % "Hide x" NewX-BT " y" NewY-BT " w" GW+3 " h" GH+3
Gui, %GN%:Show, % "Hide x" NewX " y" NewY, NotifyGui
Gui %GN%:+LastFound
NotifyGuiID := WinExist()
DllCall("AnimateWindow","UInt",NotifyGuiID,"Int",250,"UInt","0x00040008") ;=== slide up new notifications
Gui, %GN2%:Show, NA ;=== show background gui
WinSet, AlwaysOnTop, On
If Duration < 0
Notify_Exit%GN% = 1
If (Duration) ;=== set timeout for notification
SetTimer, NotifyKill%GN%, % - Abs(Duration) * 1000
Else
SetTimer, NotifyFlash%GN%, 150 ;=== flash border/icon for permanent notification (add option for flash/noflash)
Return NotifyGuiID ;=== change to return gui number
;====================================================================================
;====================================================================================
;=== when a notification is clicked:
Notify_Action:
SetTimer, NotifyKill%A_Gui%, Off
Gui, % A_Gui + 20 ":Destroy"
Gui %A_Gui%:+LastFound
NotifyGuiID := WinExist()
DllCall("AnimateWindow","UInt",NotifyGuiID,"Int",100,"UInt", "0x00050001") ;=== slide right FAST clicked notifications
Gui, %A_Gui%:Destroy
If IsLabel(Notify_Action)
Gosub, %Notify_Action%
StringReplace, NotifyList, NotifyList, % "|" GN, , All
SetTimer, % "NotifyFlash" A_Gui, Off
Return
;=== when a notification times out:
NotifyKill:
NotifyKill11:
NotifyKill12:
NotifyKill13:
NotifyKill14:
NotifyKill15:
NotifyKill16:
NotifyKill17:
NotifyKill18:
NotifyKill19: ;=== there's gotta be a better way to do this, bueller?, bueller?
NotifyKill20:
NotifyKill21:
NotifyKill22:
NotifyKill23:
NotifyKill24:
NotifyKill25:
NotifyKill26:
NotifyKill27:
NotifyKill28:
NotifyKill29:
NotifyKill30:
StringReplace, GN, A_ThisLabel, NotifyKill
SetTimer, NotifyFlash%GN%, Off
Gui, % GN + 20 ":Destroy"
Gui %GN%:+LastFound
NotifyGuiID := WinExist()
DllCall("AnimateWindow","UInt",NotifyGuiID,"Int",300,"UInt", "0x00050001") ;=== slide right SLOW timed-out notifications
Gui, %GN%:Destroy
StringReplace, NotifyList, NotifyList, % "|" GN
Return
;=== flashes a permanent notification [buggy]
NotifyFlash11:
NotifyFlash12:
NotifyFlash13:
NotifyFlash14:
NotifyFlash15:
NotifyFlash16:
NotifyFlash17:
NotifyFlash18:
NotifyFlash19:
NotifyFlash20: ;=== maybe instead use one timer and a FlashList like notifylist
NotifyFlash21: ;=== maybe they should just all flash
NotifyFlash22:
NotifyFlash23:
NotifyFlash24:
NotifyFlash25:
NotifyFlash26:
NotifyFlash27:
NotifyFlash28:
NotifyFlash29:
NotifyFlash30:
NotifyFlash:
StringReplace, FlashGN, A_ThisLabel, NotifyFlash
FlashGN2 := FlashGN + 20
If Flashed := !Flashed
Gui, %FlashGN2%:Color, Silver
Else
Gui, %FlashGN2%:Color, Black
Return
} ;=== end of Notify() ===
;=== use in OnExit (or elsewhere) to wait for notifications to close before doing something [buggy]
;=== fix: Reference GN instead of GuiID, use negative forcetime to kill all open notifications (not yet implemented)
Notify_Wait(ForceTime="", GN=11, MaxNotifications=20)
{
Loop % MaxNotifications
{
Gui %GN%:+LastFound
If NotifyGuiID := WinExist()
{
WinWaitClose, , , % ForceTime
If ErrorLevel
{
Gui, % GN + 20 ":Destroy"
DllCall("AnimateWindow","UInt",NotifyGuiID,"Int",200,"UInt", "0x00050001") ;=== slide right FAST clicked notifications
Gui, %GN%:Destroy
}
Break
}
GN++
}
Return 1
}
edit: oops, i guess yo uneed all those statics so they dont get reinitialized
edit: ok
version 0.3 is updated in first post