-- -- 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