Files
2025-09-29 00:52:08 +02:00

337 lines
9.5 KiB
Plaintext
Executable File

--
-- Notify Popup Box
-- briefly shows a warning-box in corner of Max window, with optional object-select or other-function button
--
-- Neal D Corbett
-- Rockstar Leeds
-- 09/08/2011
--
-- USAGE: https://devstar.rockstargames.com/wiki/index.php/Dev:Notifier_Popup
-- To create get a simple message popup: (text message, with "OK" button to dismiss)
-- RsNotifyPopUp_create text:"Text" title:"Title"
global RsNotifyPopUp, RsNotifyPopUp_closeTimer, RsNotifyPopUp_scrollTimer
global RsNotifyPopUp_func, RsNotifyPopUp_selFunc, RsNotifyPopUp_objs, RsNotifyPopUp_scrollIncrement
global RsNotifyPopUp_startPos, RsNotifyPopUp_targetYPos, RsNotifyPopUp_targetHeight, RsNotifyPopUp_returning
-- Clear away the popup form and timers:
fn RsNotifyPopUp_cleanup =
(
if (RsNotifyPopUp != undefined) do
(
dotNet.removeAllEventHandlers RsNotifyPopUp
RsNotifyPopUp.close()
RsNotifyPopUp = undefined
)
for globalName in #("RsNotifyPopUp_closeTimer", "RsNotifyPopUp_scrollTimer") do
(
local val = globalVars.get globalName
if (val != undefined) do
(
globalVars.set globalName undefined
val.dispose()
)
)
RsNotifyPopUp_objs = undefined
RsNotifyPopUp_func = undefined
RsNotifyPopUp_selFunc = undefined
)
-- Create notify popup-box:
fn RsNotifyPopUp_create text:"" title:"" func: selFunc: width:270 objs: scrollIncrement:2 scrollInterval:10 timeOut:4000 instantly:True =
(
RsNotifyPopUp_cleanup()
-- Set up global variables for selecting/running functions:
if (func != unsupplied) do
(
RsNotifyPopUp_func = func
)
if (objs != unsupplied) do
(
RsNotifyPopUp_objs = objs
)
if (selFunc != unsupplied) do
(
RsNotifyPopUp_selFunc = selFunc
)
-- Define timer-event to move the popup up/down and trigger its actions when it reaches its up/down positions:
fn scrollTimerEvent =
(
try
(
local currentPosY = RsNotifyPopUp.location.y
case of
(
(not RsNotifyPopUp_returning and (currentPosY > RsNotifyPopUp_targetYPos)):
(
-- Expand the form:
if (RsNotifyPopUp.height < RsNotifyPopUp_targetHeight) do
(
RsNotifyPopUp.height += RsNotifyPopUp_scrollIncrement
)
-- Move the form up:
RsNotifyPopUp.location.y -= RsNotifyPopUp_scrollIncrement
)
(RsNotifyPopUp_returning and (currentPosY < RsNotifyPopUp_startPos.y)):
(
if (RsNotifyPopUp.bounds.contains RsNotifyPopUp.mousePosition) then
(
-- Send the form back up if it's moused over:
dotNet.removeAllEventHandlers RsNotifyPopUp
RsNotifyPopUp_returning = false
)
else
(
-- Shrink the form:
if (RsNotifyPopUp.height > 0) and ((RsNotifyPopUp_startPos.y - RsNotifyPopUp.height + 5) < currentPosY) do
(
RsNotifyPopUp.height -= RsNotifyPopUp_scrollIncrement
)
-- Move the form down (slower than it moved up)
RsNotifyPopUp.location.y += (RsNotifyPopUp_scrollIncrement / 2)
)
)
(RsNotifyPopUp_returning and (currentPosY == RsNotifyPopUp_startPos.y)):
(
RsNotifyPopUp_scrollTimer.stop()
RsNotifyPopUp_cleanup()
)
default:
(
-- Popup has reached its target position:
RsNotifyPopUp_scrollTimer.stop()
RsNotifyPopUp_closeTimer.start()
-- Resets close-timer (shouldn't be triggered by mousing over sub-controls)
fn mouseLeaveEvent =
(
if RsNotifyPopUp_closeTimer.enabled and not (RsNotifyPopUp.bounds.contains RsNotifyPopUp.mousePosition) do
(
RsNotifyPopUp_closeTimer.start()
)
)
dotNet.addEventHandler RsNotifyPopUp "mouseLeave" mouseLeaveEvent
)
)
)
catch
(
RsNotifyPopUp_scrollTimer.stop()
print "scrollTimerEvent fail"
print (getCurrentException())
)
)
-- Define timer-event to tell popup to go away once it's been onscreen for enough time (unless the mouse is over it)
fn closeTimerEvent =
(
try
(
if not (RsNotifyPopUp.bounds.contains RsNotifyPopUp.mousePosition) do
(
RsNotifyPopUp_returning = true
RsNotifyPopUp_closeTimer.stop()
RsNotifyPopUp_scrollTimer.start()
)
)
catch
(
RsNotifyPopUp_closeTimer.stop()
print "closeTimerEvent fail"
print (getCurrentException())
)
)
-- Cancel the popup-close timer if it gets focus:
fn popupClickedEvent =
(
RsNotifyPopUp_closeTimer.stop()
)
-- Run function if "Yes" button is pressed:
fn yesPressed =
(
local runFunc = RsNotifyPopUp_func
RsNotifyPopUp_cleanup()
if (runFunc != undefined) do
(
runFunc()
)
)
-- Select objs if "Select Objects" button is pressed:
fn selPressed =
(
RsNotifyPopUp_closeTimer.stop()
local selObjs = #()
case of
(
(RsNotifyPopUp_selFunc != undefined):
(
selObjs = for obj in objects where (RsNotifyPopUp_selFunc obj) collect obj
)
(isKindOf RsNotifyPopUp_objs array):
(
selObjs = for obj in RsNotifyPopUp_objs where isValidNode obj collect obj
)
)
undo "Select" on
(
clearSelection()
select selObjs
)
OK
)
local DNcolour = dotNetClass "System.Drawing.Color"
RsNotifyPopUp = RS_NoFocusDotNetForm()
RsNotifyPopUp.width = width
RsNotifyPopUp_returning = false
RsNotifyPopUp.controlBox = false
RsNotifyPopUp.backColor = DNcolour.FromArgb 255 255 200
RsNotifyPopUp.formBorderStyle = (dotNetClass "System.Windows.Forms.FormBorderStyle").FixedToolWindow
local graphics = RsNotifyPopUp.createGraphics()
-- Title label:
local titleLbl = dotNetObject "System.Windows.Forms.Label"
titleLbl.location.x = 4
titleLbl.location.y = 4
titleLbl.width = width - 8
local labelFont = dotnetobject "system.drawing.font" titleLbl.font.name (titleLbl.font.size + 2.5) (dotnetclass "system.drawing.fontstyle").bold
titleLbl.font = labelFont
titleLbl.text = replace_LF_with_CRLF title
titleLbl.height = (graphics.measureString titleLbl.text titleLbl.font titleLbl.width).height
RsNotifyPopUp.controls.add titleLbl
-- Notifier label:
local textLbl = dotNetObject "System.Windows.Forms.Label"
local bodyFont = dotnetobject "system.drawing.font" textLbl.font.name (textLbl.font.size + 1) (dotnetclass "system.drawing.fontstyle").Regular
textLbl.font = bodyFont
textLbl.text = replace_LF_with_CRLF text
textLbl.location.x = 4
textLbl.width = titleLbl.width
textLbl.location.y = titleLbl.location.y + titleLbl.height + 4
textLbl.height = (graphics.measureString textLbl.text textLbl.font titleLbl.width).height
RsNotifyPopUp.controls.add textLbl
local btnWidth = 50
local btnHeight = 20
-- BUTTONS --
-- OK/No button:
local closeBtn = dotNetObject "System.Windows.Forms.Button"
closeBtn.text = "OK"
closeBtn.width = btnWidth
closeBtn.height = btnHeight
local btnPos = [width - btnWidth - 6, textLbl.bottom + 12]
closeBtn.location.x = btnPos.x
closeBtn.location.y = btnPos.y
RsNotifyPopUp_targetHeight = closeBtn.bottom + 6
RsNotifyPopUp.controls.add closeBtn
dotnet.setLifetimeControl closeBtn #dotnet
dotNet.addEventHandler closeBtn "Click" RsNotifyPopUp_cleanup
-- "Yes" button runs function "func", if supplied:
if (func != unsupplied) do
(
closeBtn.text = "No"
local yesBtn = dotNetObject "System.Windows.Forms.Button"
yesBtn.text = "Yes"
yesBtn.width = btnWidth
yesBtn.height = btnHeight
yesBtn.location.x = (btnPos.x -= btnWidth)
yesBtn.location.y = btnPos.y
RsNotifyPopUp.controls.add yesBtn
dotnet.setLifetimeControl yesBtn #dotnet
dotNet.addEventHandler yesBtn "Click" yesPressed
RsNotifyPopUp_targetHeight = yesBtn.bottom + 6
)
-- If "objs" or "selFunc" is supplied, add a "Select Objects" button:
if (objs != unsupplied) or (selFunc != unsupplied) do
(
local selBtn = dotNetObject "System.Windows.Forms.Button"
selBtn.text = "Select Objects"
selBtn.height = btnHeight
selBtn.width = 90
selBtn.location.x = (btnPos.x -= selBtn.width)
selBtn.location.y = btnPos.y
RsNotifyPopUp.controls.add selBtn
dotnet.setLifetimeControl selBtn #dotnet
dotNet.addEventHandler selBtn "Click" selPressed
)
-- END BUTTONS --
local windowPos = getMAXWindowPos()
local windowSize = getMAXWindowSize()
RsNotifyPopUp_startPos = windowPos + windowSize - [width + 14, 14]
RsNotifyPopUp_targetYPos = windowPos.y + windowSize.y - RsNotifyPopUp_targetHeight - 14
RsNotifyPopUp.height = 0
-- If box is set to instantly appear, it's moved up all in one go:
-- (it's first drawn off-screen though, as otherwise controls draw in blank to begin with)
if (instantly) do
(
scrollIncrement = RsNotifyPopUp_targetHeight
)
RsNotifyPopUp.Show (RS_dotNetMaxHWND())
RsNotifyPopUp.location.x = RsNotifyPopUp_startPos.x
RsNotifyPopUp.location.y = RsNotifyPopUp_startPos.y
-- Scroll-timer:
RsNotifyPopUp_scrollTimer = dotNetObject "System.Windows.Forms.Timer"
RsNotifyPopUp_scrollIncrement = scrollIncrement
RsNotifyPopUp_scrollTimer.interval = scrollInterval
-- Wait-timer:
RsNotifyPopUp_closeTimer = dotNetObject "System.Windows.Forms.Timer"
RsNotifyPopUp_closeTimer.interval = timeOut
--Add Event Handlers:
dotNet.addEventHandler RsNotifyPopUp_scrollTimer "Tick" scrollTimerEvent
dotNet.addEventHandler RsNotifyPopUp_closeTimer "Tick" closeTimerEvent
dotNet.addEventHandler RsNotifyPopUp "Click" popupClickedEvent
RsNotifyPopUp_scrollTimer.start()
return RsNotifyPopUp
)
--RsNotifyPopUp_create text:"Text" title:"Title" func:testPress