Notifications
Clear all

[Closed] Modal dialog and mouse

I’ve created two dialogs, we can call them now MainDialog(non-modal) and SubDialog(modal). MainDialog is opened first and when button is pressed, SubDialog opens. SubDialog does some stuff and then closes itself.

Problem is, that when the SubDialog is open and I press mouse button over some MainDialog control(for example checkbox) the MainDialog’s control gets that mouse command AFTER the SubDialog is closed (unchecked checkbox becomes checked etc.). I dont want user to interact with MainDialog controls at all when SubDialog is open.

Is there a way to prevent this for happening? Of course I could use some flags to check if SubDialog is open dont check buttons blahblah, but i’m looking for better way

16 Replies

there is no easy way to temporally disable mouse click in MXS, but if you want to know how to do it using c# I can give you the snippet…

Cheap hack could be to lock (.enabled = false) the Main-Dialog options on Sub-Dialog open, or assign them to variables, and then unlock (.enabled = true) them or reassign the original values from the variables on Sub-Dialog close.

-Eric

2 Replies
(@denist)
Joined: 11 months ago

Posts: 0

the problem is: you can protect your ui elements, but you can’t protect max ui or max viewports from clicking…

(@pixel_monkey)
Joined: 11 months ago

Posts: 0

I was responding to this statement: of:

In which my example does what was asked for. You are correct in that it won’t lock interaction with the UI, but VVaari seemed to be more concerned with the With locking the MainDialog interaction.

-Eric

…but VVaari seemed to be more concerned with the With locking the MainDialog interaction.

because he doesn’t know yet how bad with max interaction is…

What about the CreateDialog modal:<boolean> setting? Set this to true on the Sub Dialog and you can’t access anything in Max outside that dialog. Problem you may run into is if you set the main dialog to modal and launch a new dialog, in this case the modal precident has been set by the main dialog, and you can’t override that with the sub dialog.

-Eric

Modal dialog is definitely a solution in many cases. But it doesn’t work in some another. Let’s say I want to have a progress bar as a window. I have some run process in my main tool (dialog) and I want to show the progress in other window. In this case I can’t make secondary dialog modal…

I understand that it isn’t perfect, but so far both of my options will work for the case presented here. I will let VVaari figure out what really does and doesn’t work for what he is trying to do.

-Eric

Thanks guys for answers!

I already have SubDialog as modal. It’s kind of loading dialog where user doesn’t click anything, he just waits and after stuff is loaded, SubDialog closes. But if the user clicks mouse over some MainDialog or Max UI component while SubDialog is running, component gets “activated” after SubDialog is closed. It’s like mouse click gets stored in some “mouse-click-buffer” and it gets released after SubDialog closes

I have done cheap hack for my MainDialog where components gets enabled after SubDialog is closed. I was just wondering if there is better way. I don’t really care about Max UI components here.

denisT, sure would be nice to see how its done in C#

Here is it:
/* C# code
using System.Runtime.InteropServices;
class Input
{
[DllImport(“user32.dll”)]
public static extern bool BlockInput(bool fBlockIt);
}
*/

The BlockInput function blocks keyboard and mouse input events from reaching applications.


/*********** Compile C# ON FLY ************/
fn getInputClass = 
(
 source = ""
 source += "using System.Runtime.InteropServices;
"
 source += "class Input 
"
 source += "{
"
 source += "	[DllImport(\"user32.dll\")]
"
 source += "	public static extern bool BlockInput(bool fBlockIt);
"
 source += "}
"
 -- Compile on fly
 csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
 compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
 compilerParams.GenerateInMemory = on
 compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(source)
 
 input = compilerResults.CompiledAssembly.CreateInstance "Input"
)
 
/****** Sample ************/
try(destroydialog theRol) catch()
global theTimer -- it's better to have it global 
rollout theRol "Block Input by denisT"
(
 label lb "" align:#left offset:[0,2]
 local ticks = 0, input
 fn testTimer =
 (
  fn printTime = 
  (
   lb.text = "Local Time: " + localtime
   ticks += 1
   if keyboard.escpressed or ticks > 10 do -- keyboard.escpressed BLOCKED
   (
	theTimer.stop()
	input.BlockInput off -- UNBLOCK Input
	try(destroydialog theRol) catch()
   )
  )
  theTimer = dotNetObject "System.Windows.Forms.Timer" --create Timer for 10 ticks
  dotnet.addEventHandler theTimer "tick" printTime
  theTimer.interval = 1000
  theTimer.start()
  theTimer
 )
 on theRol open do 
 (
  input = getInputClass()
  lb.text = "Local Time: " + localtime
  input.BlockInput on -- BLOCK Input
  theTimer = testTimer()
 )
)
createDialog theRol width:200 height:30 modal:on -- (it might not be modal)
/************************************/

if you are interested how to hide/show and position mouse cursor let me know…

That snippet looks interesting and the way you can generate C#-code inside maxscript is totally new to me, thanks a lot!

Would it be possible to create something like maxscript’s mouseTracker() using C#? I guess it would but how hard is it? I don’t like mouseTracker that much because you can’t stop tracking unless cursor goes over viewport, so starting and stopping tracking using rollout controls doesn’t work. Atleast I haven’t figured out how to do it.

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

You can stop tracking using rollout controls


try(destroydialog mouseTracker) catch()
rollout mouseTracker "Mouse Tracking" 
(
 local act = off
 fn mouseTracking msg ir obj faceNum shift ctrl alt =
 (
  if msg == #mouseAbort or msg == undefined or not act then #abort else #continue 
 )
 button start "Start" width:80 across:2
 button stop "Stop" width:80
 
 on start pressed do
 (
  start.enabled = not (act = on)
  mouseTrack trackCallback:mouseTracking
  start.enabled = not (act = off)
 )
 on stop pressed do act = off
)
createDialog mouseTracker width:190 height:30

Page 1 / 2