241 lines
6.2 KiB
Plaintext
241 lines
6.2 KiB
Plaintext
Module Notify
|
|
EnableExplicit
|
|
|
|
;- Toast constants
|
|
#Toast_W = 300
|
|
#Toast_H = 60
|
|
#Toast_Margin = 10
|
|
#Accent_W = 4
|
|
#Toast_Timer = 0
|
|
#MaxToasts = 5
|
|
|
|
;- Globals
|
|
Global _Font = LoadFont(#PB_Any, "sans-serif", 12)
|
|
|
|
; Toast state
|
|
Global Dim _Wins.i(#MaxToasts)
|
|
Global Dim _Canvases.i(#MaxToasts)
|
|
Global Dim _Types.i(#MaxToasts)
|
|
Global Dim _Messages.s(#MaxToasts)
|
|
Global _Count
|
|
|
|
; Confirm state
|
|
Global _ConfirmWin
|
|
Global _ConfirmOkBtn
|
|
Global _ConfirmCancelBtn
|
|
Global *_ConfirmCb
|
|
|
|
;- Private declarations
|
|
Declare _TypeColor(Type)
|
|
Declare _DrawToast(Slot)
|
|
Declare _Dismiss(Slot)
|
|
Declare _Reposition()
|
|
Declare _FindByWindow(Win)
|
|
Declare _FindByCanvas(Canvas)
|
|
Declare _CloseConfirm()
|
|
Declare _FireConfirm(Result)
|
|
Declare Handler_ToastTimer()
|
|
Declare Handler_ToastClick()
|
|
Declare Handler_ConfirmOK()
|
|
Declare Handler_ConfirmCancel()
|
|
Declare Handler_ConfirmClose()
|
|
|
|
;- Public procedures
|
|
|
|
; Show a toast in the bottom-right corner. Dismisses after Duration ms or on click.
|
|
Procedure Toast(Message.s, Type = #Info, Duration = 4000)
|
|
Protected Slot, DW, DH, X, Y, Win, Canvas
|
|
|
|
If _Count >= #MaxToasts : ProcedureReturn : EndIf
|
|
|
|
Slot = _Count
|
|
DW = DesktopWidth(0)
|
|
DH = DesktopHeight(0)
|
|
X = DW - #Toast_W - #Toast_Margin
|
|
Y = DH - (Slot + 1) * (#Toast_H + #Toast_Margin)
|
|
Win = OpenWindow(#PB_Any, X, Y, #Toast_W, #Toast_H, "", #PB_Window_BorderLess)
|
|
StickyWindow(Win, #True)
|
|
Canvas = CanvasGadget(#PB_Any, 0, 0, #Toast_W, #Toast_H)
|
|
|
|
_Wins(Slot) = Win
|
|
_Canvases(Slot) = Canvas
|
|
_Types(Slot) = Type
|
|
_Messages(Slot) = Message
|
|
_Count + 1
|
|
|
|
_DrawToast(Slot)
|
|
|
|
BindGadgetEvent(Canvas, @Handler_ToastClick())
|
|
AddWindowTimer(Win, #Toast_Timer, Duration)
|
|
BindEvent(#PB_Event_Timer, @Handler_ToastTimer(), Win)
|
|
EndProcedure
|
|
|
|
; Show a modal confirm dialog. *Callback(Result) is called with 1 for OK, 0 for Cancel.
|
|
; Only one confirm can be open at a time — subsequent calls are ignored.
|
|
Procedure Confirm(Title.s, Message.s, *Callback)
|
|
Protected W, H, DW, DH
|
|
|
|
If IsWindow(_ConfirmWin) : ProcedureReturn : EndIf
|
|
|
|
W = 340
|
|
H = 130
|
|
DW = DesktopWidth(0)
|
|
DH = DesktopHeight(0)
|
|
|
|
_ConfirmWin = OpenWindow(#PB_Any, (DW - W) / 2, (DH - H) / 2, W, H, Title, #PB_Window_TitleBar | #PB_Window_SystemMenu)
|
|
StickyWindow(_ConfirmWin, #True)
|
|
*_ConfirmCb = *Callback
|
|
|
|
TextGadget(#PB_Any, 20, 20, W - 40, 50, Message)
|
|
_ConfirmOkBtn = ButtonGadget(#PB_Any, W - 190, H - 45, 80, 30, "OK")
|
|
_ConfirmCancelBtn = ButtonGadget(#PB_Any, W - 100, H - 45, 80, 30, "Cancel")
|
|
|
|
BindGadgetEvent(_ConfirmOkBtn, @Handler_ConfirmOK())
|
|
BindGadgetEvent(_ConfirmCancelBtn, @Handler_ConfirmCancel())
|
|
BindEvent(#PB_Event_CloseWindow, @Handler_ConfirmClose(), _ConfirmWin)
|
|
EndProcedure
|
|
|
|
;- Private procedures
|
|
|
|
Procedure _TypeColor(Type)
|
|
Select Type
|
|
Case #Success : ProcedureReturn RGB( 60, 180, 100)
|
|
Case #Warning : ProcedureReturn RGB(220, 160, 40)
|
|
Case #Error : ProcedureReturn RGB(210, 65, 65)
|
|
Default : ProcedureReturn RGB( 50, 130, 220) ; #Info
|
|
EndSelect
|
|
EndProcedure
|
|
|
|
Procedure _DrawToast(Slot)
|
|
Protected W, H, MaxW
|
|
Protected Msg.s
|
|
|
|
If Not IsGadget(_Canvases(Slot)) : ProcedureReturn : EndIf
|
|
If Not StartDrawing(CanvasOutput(_Canvases(Slot))) : ProcedureReturn : EndIf
|
|
|
|
W = OutputWidth()
|
|
H = OutputHeight()
|
|
|
|
; Background
|
|
Box(0, 0, W, H, RGB(38, 38, 54))
|
|
|
|
; Accent bar
|
|
Box(0, 0, #Accent_W, H, _TypeColor(_Types(Slot)))
|
|
|
|
; Message — truncate with ellipsis if too wide
|
|
DrawingMode(#PB_2DDrawing_Transparent)
|
|
If IsFont(_Font) : DrawingFont(FontID(_Font)) : EndIf
|
|
|
|
Msg = _Messages(Slot)
|
|
MaxW = W - #Accent_W - 24
|
|
While Len(Msg) > 3 And TextWidth(Msg) > MaxW
|
|
Msg = Left(Msg, Len(Msg) - 4) + "..."
|
|
Wend
|
|
|
|
DrawText(#Accent_W + 14, (H - TextHeight("A")) / 2, Msg, RGB(220, 220, 220))
|
|
StopDrawing()
|
|
EndProcedure
|
|
|
|
Procedure _Dismiss(Slot)
|
|
Protected i
|
|
|
|
If Not IsWindow(_Wins(Slot)) : ProcedureReturn : EndIf
|
|
|
|
UnbindEvent(#PB_Event_Timer, @Handler_ToastTimer(), _Wins(Slot))
|
|
UnbindGadgetEvent(_Canvases(Slot), @Handler_ToastClick())
|
|
CloseWindow(_Wins(Slot))
|
|
|
|
For i = Slot To _Count - 2
|
|
_Wins(i) = _Wins(i + 1)
|
|
_Canvases(i) = _Canvases(i + 1)
|
|
_Types(i) = _Types(i + 1)
|
|
_Messages(i) = _Messages(i + 1)
|
|
Next
|
|
_Wins(_Count - 1) = 0
|
|
_Canvases(_Count - 1) = 0
|
|
_Types(_Count - 1) = 0
|
|
_Messages(_Count - 1) = ""
|
|
_Count - 1
|
|
|
|
_Reposition()
|
|
EndProcedure
|
|
|
|
Procedure _Reposition()
|
|
Protected DW, DH, i
|
|
|
|
DW = DesktopWidth(0)
|
|
DH = DesktopHeight(0)
|
|
For i = 0 To _Count - 1
|
|
ResizeWindow(_Wins(i), DW - #Toast_W - #Toast_Margin, DH - (i + 1) * (#Toast_H + #Toast_Margin), #PB_Ignore, #PB_Ignore)
|
|
Next
|
|
EndProcedure
|
|
|
|
Procedure _FindByWindow(Win)
|
|
Protected i
|
|
For i = 0 To _Count - 1
|
|
If _Wins(i) = Win : ProcedureReturn i : EndIf
|
|
Next
|
|
ProcedureReturn -1
|
|
EndProcedure
|
|
|
|
Procedure _FindByCanvas(Canvas)
|
|
Protected i
|
|
For i = 0 To _Count - 1
|
|
If _Canvases(i) = Canvas : ProcedureReturn i : EndIf
|
|
Next
|
|
ProcedureReturn -1
|
|
EndProcedure
|
|
|
|
Procedure _CloseConfirm()
|
|
UnbindGadgetEvent(_ConfirmOkBtn, @Handler_ConfirmOK())
|
|
UnbindGadgetEvent(_ConfirmCancelBtn, @Handler_ConfirmCancel())
|
|
UnbindEvent(#PB_Event_CloseWindow, @Handler_ConfirmClose(), _ConfirmWin)
|
|
CloseWindow(_ConfirmWin)
|
|
_ConfirmWin = 0
|
|
EndProcedure
|
|
|
|
Procedure _FireConfirm(Result)
|
|
_CloseConfirm()
|
|
If *_ConfirmCb
|
|
!notify$g__confirmcb(v_result);
|
|
*_ConfirmCb = 0
|
|
EndIf
|
|
EndProcedure
|
|
|
|
;- Event handlers
|
|
|
|
Procedure Handler_ToastTimer()
|
|
Protected Slot = _FindByWindow(EventWindow())
|
|
If Slot >= 0 : _Dismiss(Slot) : EndIf
|
|
EndProcedure
|
|
|
|
Procedure Handler_ToastClick()
|
|
Protected Slot
|
|
If EventType() <> #PB_EventType_LeftButtonUp : ProcedureReturn : EndIf
|
|
Slot = _FindByCanvas(EventGadget())
|
|
If Slot >= 0 : _Dismiss(Slot) : EndIf
|
|
EndProcedure
|
|
|
|
Procedure Handler_ConfirmOK()
|
|
_FireConfirm(1)
|
|
EndProcedure
|
|
|
|
Procedure Handler_ConfirmCancel()
|
|
_FireConfirm(0)
|
|
EndProcedure
|
|
|
|
Procedure Handler_ConfirmClose()
|
|
_FireConfirm(0)
|
|
EndProcedure
|
|
|
|
EndModule
|
|
|
|
; IDE Options = SpiderBasic 3.20 (Windows - x86)
|
|
; CursorPosition = 13
|
|
; Folding = BAw
|
|
; iOSAppOrientation = 0
|
|
; AndroidAppCode = 0
|
|
; AndroidAppOrientation = 0
|
|
; EnableXP
|
|
; DPIAware
|
|
; CompileSourceDirectory |