Home Technical Talk

[MaxScript] start pickbutton picking by code not button click?

polycounter lvl 13
Offline / Send Message
xXm0RpH3usXx polycounter lvl 13
Hey folks,

could someone please tell me how to activate a maxscript pickbutton via a function?
Like, I dont want to start it by having the user click on the button (well, at least not at the time the line of code appears in my script), but rather by a line of code.

--------------------------------------------------------------------------
on pbtn_pick picked obj do
( if classof obj == line then ( pbtn_pick.text = obj.name ) --I do know about the automatic display settings
else
( if querybox "Please pick a closed spline! \nWant to change to ''shape selection mode''?" == true do 
( SetSelectFilter 3 )
))
--------------------------------------------------------------------------

So after the "SetSelectionFilter 3" line I would like to automatically restart the picking mode.

Thanks in advance!

Replies

  • Pac_187
    Options
    Offline / Send Message
    Pac_187 polycounter lvl 11
    You can use the PressButton function in the UIAccesor interface:
    UIAccessor.PressButton <hwnd>

    In your case:
    UIAccessor.PressButton pbtn_pick.hwnd[1]

    The [1] is needed since .hwnd returns the window pointer in an array.


  • xXm0RpH3usXx
    Options
    Offline / Send Message
    xXm0RpH3usXx polycounter lvl 13
    unfortunately this does not work so easily, doesnt throw an error, but neither does it reactivate the button. still i am really greatful for pointing me in the right direction.
    thank you! i will do some more research after having slept, it's late already! :smile:

  • Pac_187
    Options
    Offline / Send Message
    Pac_187 polycounter lvl 11
    Hmm that's weird. Which 3ds Max version are you using?
    I tested it myself with 2014 and it work's like a charm.

    Are you able to share your code?
  • xXm0RpH3usXx
    Options
    Offline / Send Message
    xXm0RpH3usXx polycounter lvl 13
    Everything works fine, as long as I point it to a normal button.
    It doesnt work specifically with the pickbutton, though.

    I dont know what you would need the rest of the code for, as it is not relevant to the problem, I believe?
    Just imagine a pickbutton, if you select geometry it pops up a window telling you to pick a spline and then it should reactivate the pickbutton. I am aware that I can code a filter for the pickbutton, but how it is set up now, depending on a dropdown list selection, you can either pick geometry or splines only. 
    I'm on 2015, so I do not see why it shouldnt work.
  • Pac_187
    Options
    Offline / Send Message
    Pac_187 polycounter lvl 11
    Ok, I have to excuse, you are right it doesn't work if it's called from within the pickbutton picked function. *Whoops*

    I guess it's one of those things where you have to use a dirty workaround, in this case a timer.
    Don't set the timer interval too low or it won't work properly.

    I call this dirty because timers can be dangerous if not handled right, always make sure to stop them,
    remove the eventhandler and dispose them if they are used for "one time call" stuff.

    Also make sure you declare the functions in the right order.

    Here's a working example:

    (<br>&nbsp;&nbsp;&nbsp; try(DestroyDialog ::mydialog)catch()<br>&nbsp;&nbsp;&nbsp; global mydialog<br>&nbsp;&nbsp;&nbsp; rollout mydialog "TEST"<br>&nbsp;&nbsp;&nbsp; (<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; pickbutton pick_btn "-pick something" autodisplay:true<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fn tickEvent s e =<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; s.stop()<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dotNet.removeAllEventHandlers s<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; UIAccessor.PressButton pick_btn.hwnd[1]<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; s.Dispose()<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; )<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fn DelayedPick = <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; local t = dotNetObject "System.Windows.Forms.Timer"<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; t.interval = 50<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; dotNet.addEventHandler t "Tick" tickEvent<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; t.start()<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; )<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; on pick_btn picked obj do<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (queryBox "Wubba lubba dub dub!" == true) then <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; SetSelectFilter 3<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; DelayedPick()<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; )<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; )<br>&nbsp;&nbsp;&nbsp; )<br>&nbsp;&nbsp;&nbsp; CreateDialog mydialog<br>&nbsp;&nbsp;&nbsp; <br>)<br>

  • Shive
    Options
    Offline / Send Message
    Shive polycounter lvl 2
    Another solution, no timers and no "dirty" UIAccessor.
    I used a checkbutton instead of a pickbutton, "outsource" the picking to a function. This way you can call the function from anywhere. I added another button to demonstrate. "mybutton" is optional parameter, so you can imitate the pressed button state. The filter function also checks for open/closed splines, so you don't have to check for that later. Have a look:
    try destroydialog ROL_aaa catch()
    
    fn shapeFilt o =
    (
    	if (classof o == line and isClosed o 1) then true
    	else false
    )
    
    fn pickfrombutton mybutton: =
    (
        try mybutton.checked = true catch()
        obj = pickObject message:"Pick a closed spline" count:1 filter:shapeFilt select:false pickFrozen:false
        try mybutton.checked = false catch()
    	
        if obj != undefined then
        (
    		try mybutton.text = obj.name catch()
    		return obj
        )
        else
        (
            messagebox "nothing selected"
            return undefined
        )
    )
    
    rollout ROL_aaa ""
    (
        local selSpline
        checkbutton pbtn_pick "FakePickButton"
        button BTN_ActivatePicking "normal button"
        on pbtn_pick changed state do selSpline = pickfrombutton mybutton:pbtn_pick
        on BTN_ActivatePicking pressed do selSpline = pickfrombutton mybutton:pbtn_pick
    )
    
    createdialog ROL_aaa
  • monster
    Options
    Offline / Send Message
    monster polycounter
    I'm not seeing a need to restart the pick code. You can just update the filter based on the dropdown. It even works while you are in pick mode.

    (
    	rollout rollPickTest "Pick Test"
    	(
    		local ddlClass = shape
    		
    		fn PickFilter obj = superclassof obj == ddlClass
    		
    		dropdownlist ddlClassPick "Pick Type" items:#("Shape", "Geometry")
    		pickbutton pickObj "Pick Object" filter:PickFilter autoDisplay:true
    		
    		on ddlClassPick selected val do
    		(
    			case val of
    			(
    				1: ddlClass = shape
    				2: ddlClass = GeometryClass
    			)
    		)
    	)
    	
    	createDialog rollPickTest
    )

  • xXm0RpH3usXx
    Options
    Offline / Send Message
    xXm0RpH3usXx polycounter lvl 13
    hey peeps, thanks for the responses!
    the week was hard, so I didnt get a chance to check back here.

    I avoided the issue by using several pickbuttons, which are hid and unhid by the dropdown selection.

    I am currently working through your comments to understand them, so thanks for sharing your knowledge!

    edit: i like your style, monster! very clean and understandable code, perfect! :)
Sign In or Register to comment.