Notifications
Clear all

[Closed] creating help button

Hi everyone

I want to provide some info for the user of my dialog, like a guidance with using the dialog.
The first thing I thought of was to have a functionality like the “?” button on some M$ dialogs, where when pressed and you click on dialog elements, it shows you information what they are and so on.

For this to achieve, I tried to use the tool function, but I have no clue how to get back the dialog control.
Is there a function I can use to get controls at a specific position?

I hoped the “toolTip” property would work for more than just buttons in maxscript, but then I thought, it is rather limited with just text…

So I want to create a function which shows up another dialog to the left or right of the dialog control, show information about it, when hovering out or to some other control, the information dialog disappears and another one will open with updated info on the new dialog control.

The only problem I have to achieve this, I don’t know how to get the dialog control on the specific position. (I have about 100 dialog controls I need to document…)

Thanks for any help!

9 Replies

I don’t know about hover, but you could have the user click the “help button” and then click the control in question. Once this occurs you can trap the click in the controls handler and then using the .position property, you should be able to display what ever you like…

It’s a lot of work though…

color me confused, but didn’t you already ask this?
http://forums.cgsociety.org/showthread.php?f=98&t=629767

Rusty: one of the problems with that approach is that there’s many controls (most of them) for which there is no clicking event or, if there is, that clicking event may be associated directly with user activity or even scene elements.

A cool alternative would be to use the RIGHT-click of the buttons for this. It is a separate handler and could be implemented for each control to show just help.

6 Replies
(@rustyknight)
Joined: 11 months ago

Posts: 0

Didn’t say it was going to be easy or pretty?!

You could set a flag that puts the dialog into “help” mode, so when the user clicks the control you can trigger and alternative “help” branch…

The other idea (I think RPManager does something like this…or is it deadline…). Instead of single “help” button, provide one for each “control” or “control group” that when clicked would provide the required help information associated with that control. If you were really clever you could associate that with an xml file and go nuts!

Shane

(@bobo)
Joined: 11 months ago

Posts: 0

Yep, Submit Max To Deadline script does that, but it is rather crowded. It launches the default web browser and links to the corresponding page:

(@zeboxx2)
Joined: 11 months ago

Posts: 0

Never alleged that you did

You could set a flag that puts the dialog into “help” mode, so when the user clicks the control you can trigger and alternative “help” branch…
But that’s the thing – you can’t register a click on most of the controls.

quick evolution…


 rollout test "test" (
 button button1 "button 1" tooltip:"This is a tooltip"
 label label1 "label 1" style_sunkenedge:true tooltip:"So is this, but it's invalid on a label"
 )
 createDialog test
 

Hover over the label and you’ll note that there’s no tooltip… Perhaps in Max2010 -all- controls can be tooltipped, or maybe they’ll just tell users to drop maxscript UIs altogether and use .NET UIs instead… I certainly wouldn’t put it past them. Anyway, won’t do us any good for 2009, 2008, 9, or the funny people running 8, 7, 6, 5 or even 4 (eek).
Besides, the original poster wanted to be able to show a little more than just a tooltip.

So, enter the tooltip mode toggle.


 rollout test "test" (
 	checkbutton helpmode "?" tooltip:"help mode"
 	button button1 "button1" tooltip:"button tooltip.  Enter help mode to get more details."
 	label label1 "label1					  " style_sunkenedge:true
 
 	on button1 pressed do (
 		if (helpmode.state) then ( messagebox "this button does something" )
 		else (
 			label1.text = (timeStamp()) as string
 		)
 	)
 	
 	on label1 pressed do ( ) -- no such thing
 	on label1 lbuttondown do ( ) -- also no such thing
 )
 createDialog test
 

Works great for the button, as that’s actually a control we can click. We could do the same for listboxes (make sure the original listbox selection is restored when in help mode), spinners’ up/down arrows (again, restore the original value when in help mode), etc.
But we can’t do this for, say, labels. They simply don’t have a ‘pressed’ event, nor some manner of buttondown event.

So let’s abuse the dialog’s main events:


 rollout test "test" (
 	checkbutton helpmode "?" tooltip:"help mode"
 	label label1 "label 1" style_sunkenedge:true
 
 	on test lbuttondown pos do (
 		if (helpmode.state) then (
 			-- we need to get the Box2 of the label
 			-- the position
 			local labelPos = label1.pos
 			-- the dimensions.  Except that we can't get a .size, .width, .height of a label.
 			-- We could use getTextExtent and assume the border size if it's a 1-line label.
 			-- If it's multi-line, or changes in size, we're somewhat screwed.
 			-- Nevermind other controls, but more on that later.
 			-- For now, let's just assume it's 100 by 16 pixels.
 			local labelSize = [100,16]
 			local labelBox = (Box2 labelPos.x labelPos.y labelSize.x labelSize.y)
 			
 			-- now check the clicked position against that box
 			if (contains labelBox pos) then (
 				messagebox "This label does absolutely nothing"
 			)
 		)
 	)
 )
 createDialog test
 

Great! Except now it’s not a label, it’s a multi-line edittext.


 rollout test "test" width:200 height:100 (
 	checkbutton helpmode "?" tooltip:"help mode"
 	edittext edt_1 "" width:150 height:64
 
 	on edt_1 changed text do ( messagebox ("You changed text to: " + text) )
 	on edt_1 entered text do ( messagebox ("You entered: " + text) )
 	on test lbuttondown pos do (
 		messagebox "You clicked in the dialog"
 	)
 )
 createDialog test

Try as you might, just clicking on the edittext will not get you the lbuttondown event, nor the changed or entered events (unless you did make a change).

You might wonder if the dialog’s mouseMove event does work; I’m afraid it doesn’t.

So we can’t register a click on several UI elements via the dialog (as we can’t get the mouse’s position in that dialog), which also have no ‘clicked’ type event of their own.

We can, however, get the mouse’s position on the screen at any one point in time. We can relate that screen position to the dialog’s client area via simple math:


 rollout test "test" width:200 height:100 (
 	on test mousemove pos do (
 		format "% -> % : %
" mouse.screenpos pos (mouse.screenPos - (getDialogPos test))
 	)
 )
 createDialog test
 

You’ll notice that there’s a discrepancy between the calculated value and the actual value from the mousemove event. That discrepancy depends on the user’s operating system UI interface settings for things like the titlebar height and border widths. But as we have the correct value from pos when we are over an area of the dialog which -does- have a mousemove event, we can store that.


 rollout test "test" width:200 height:100 (
 	local ui_clientOffset = undefined
 	
 	on test mousemove pos do (
 		if (ui_cilentOffset == undefined) then (
 			ui_clientOffset = pos - (mouse.screenPos - (getDialogPos test))
 		)
 		format "% -> % : %
" mouse.screenpos pos (mouse.screenPos - (getDialogPos test) + ui_clientOffset)
 	)
 )
 createDialog test
 

So now we can go back to our edittext problem. We can’t register a mouseMove over it either, so instead let’s exploit a timer (be it maxscript or .NET, your choice):


 rollout test "test" width:200 height:100 (
 	local ui_clientOffset = undefined
 
 	checkbutton helpmode "?" tooltip:"help mode"
 	edittext edt_1 "" width:150 height:64
 	
 	timer tick_tock interval:250 active:true
 	
 	on tick_tock tick do (
 		if ((helpmode.state) AND (ui_clientOffset != undefined)) then (
 			local mouseClientPos = mouse.screenPos - (getDialogPos test) + ui_clientOffset
 			
 			local edtPos = edt_1.pos
 			-- again, we can't get the size by code;
 			-- good idea to hardcode it in the UI, now we can just use that.
 			local edtSize = [150,64]
 			local edtBox = (Box2 edtPos.x edtPos.y edtSize.x edtSize.y)
 
 			local dialogPos = getDialogPos test
 			local dialogBox = (Box2 dialogPos.x dialogPos.y test.width test.height)
 			if (contains edtBox mouseClientPos) then (
 				print "The mouse is over the edit text"
 			)
 			else if (contains dialogBox mouse.screenPos) then (
 				print "The mouse is inside the dialog's client area"
 			)
 			else (
 				print "The mouse is outside the dialog's client area"
 			)
 		)
 	)
 	
 	on test mousemove pos do (
 		if (ui_cilentOffset == undefined) then ( ui_clientOffset = pos - (mouse.screenPos - (getDialogPos test)) )
 	)
 )
 createDialog test
 

So now we can detect that the mouse is over the edit text, at least. This, in itself, is enough information to generate an automated tooltip using any number of functions. However, if you only want it when the user -clicks-, then there’s a problem. Remember, we still can’t get the lbuttondown and the control itself doesn’t have a ‘clicked’ event.

What about “mouse.buttonstates?” you might ask. Well, unfortunately, those only work within a viewport. You could probably get the mouse’s button states from .NET, but I wouldn’t quite know how (Forms.MouseButtons seems to be for .NET controls, unsurprisingly).

Now, I thought maybe there was a way to get the click variant by using an imgtag control (which can be transparent so it wouldn’t obscure the underlaying controls); simply move an imgtag control around so that it would overlap the Box2 of the area we want to respond to, and move it back out when appropriate. However, edit texts and several other controls happily get a higher z-order in terms of where you’re clicking as far as windows is concerned, so the click never registers. So much for that idea

==========

Anyway, long story short – no, it’s not simple, because there’s a ton of obstacles in maxscript and otherwise that you’d have to overcome. The above examples should be enough for anybody to make their own automated tooltip bit – if somebody figures out how to get a mouse’s button states reliable, that will solve the clickable variant as well.

However, unless you (the original duplicate poster) really want to go through that trouble, I’d say that the approach where just showing another dialog next to your existing one with ah HTML in it that has clickable regions is 1. simple, 2. clean and 3. flexible. It might not be as fancy, but unless maxscript magically gets mouseover/click events for every control, the fancy way is also the long and hard way.

(@zeboxx2)
Joined: 11 months ago

Posts: 0

I know it’s not what you meant – but I suddenly envisioned an UI made entirely out of buttons 😮

Well, almost. Anywhere you’ve got an editing field, you’ve got a context menu to contend with. Anywhere you’ve got a spinner, you’ve got the set-to-zero (unnngh) to deal with. Can’t think of any others off the top of my head, but those might be problematic enough.

(@bobo)
Joined: 11 months ago

Posts: 0

I thought we were talking about help on BUTTONS, not on any UI control. I must have misunderstood it, probably because the title was “help buttons”. You are right, right-click does not work for spinners.

Btw, drop-down lists and checkboxes now have tooltips in Max 2009, and tooltips are automatically (or manually) multi-lined. Only spinners would be an issue as I don’t think they expose tooltips yet.

(@zeboxx2)
Joined: 11 months ago

Posts: 0

Are you referring to a specific interface here? As far as I can tell, tooltip support seems to be (no idea about max 1-2.5) as follows (d:definable, r/w:read/write access):


angle: none(1)
bitmap: none
button: d:R3+ r/w:R9
checkbox: d/r/w:R2009
checkbutton: d:R3+ r/w:R9
colorpicker: none
curveControl: none
comboBox: none
dropdownList: d/r/w:R2009(2)
edittext: none
group: none
groupBox: none
hyperlink: none(3)
imgtag: d/r/w:R4
label: none
listBox: none
mapButton: d:R3 r/w:R9
materialButton: d:R3 r/w:R9
multiListBox: none
pickButton: d:R3 r/w:R9
progressBar: none
slider: none
spinner: none
subRollout: none(4)

1) angle has a built-in tooltip that shows the angle value, so that might clash when within the angle-setting area.
2) dropdownlist tooltip only on the actual drop-down area, not on the caption area
3) hyperlink has a built-in tooltip to display the address the link points to.  This is a good thing.  P.S. the default address still points to www.ktx.com =)
4) a tooltip on a subRollout probably wouldn't make much sense; the controls within would have their own tooltips