Page 2 of 2

Re: Context Menu on Left Click

Posted: Fri Dec 20, 2013 3:51 pm
by DaveLClarkI
While waiting for possible answers, I've been researching on the Internet and found some good things for a general purpose position calculation; but, am still no closer to getting the menu to appear at the mouse position. The following is what I have now and it works -- such as it is -- but the menu still appears lower than it is supposed to.

Code: Select all

/*	================================================================================
	showContextMenu()	positions a menu widget at the current mouse position and
						makes the menu visible.
*/
wob.showContextMenu = function(menuId, event)
{
	var offsetX, offsetY;					// define local variables

	if (self.pageYOffset)					// if scrolled, get page offset by browser
	{
		offsetX = self.pageXOffset;
		offsetY = self.pageYOffset;
	}
	else if (document.documentElement
		 && document.documentElement.scrollTop)
	{
		offsetX = document.documentElement.scrollLeft;
		offsetY = document.documentElement.scrollTop;
	}
	else
	{
		offsetX = document.body.scrollLeft;
		offsetY = document.body.scrollTop;
	}
	if (document.all)						// add mouse offset to that, by browser
	{
		offsetX += event.clientX;
		offsetY += event.clientY;
	}
	else
	{
		offsetX += event.pageX;
		offsetY += event.pageY;
	}
	var bodyOffsets = document.body.getBoundingClientRect(); // if client rect. has been shifted...
	offsetX -= bodyOffsets.left;			// subtract client rect. shifted to right
	offsetY -= bodyOffsets.top;				// subtract client rect. shifted down

	applyProperty(menuId, "left", (offsetX - 5) + "px"); // position the menu
	applyProperty(menuId, "top", (offsetY - 5) + "px");
	applyProperty(menuId, "z index", 100);				// put menu on top of everything
	applyProperty(menuId, "visibility", "visible");		// make menu visible
}

Re: Context Menu on Left Click

Posted: Fri Dec 20, 2013 4:45 pm
by DaveLClarkI
So, as a test, I changed this part of the code:

Code: Select all

   applyProperty(menuId, "left", (offsetX - 5) + "px"); // position the menu
   applyProperty(menuId, "top", (offsetY - 5) + "px");
to this:

Code: Select all

   applyProperty(menuId, "left", (offsetX - 5 - 5) + "px"); // position the menu
   applyProperty(menuId, "top", (offsetY - 5 - 60) + "px");
and now the menu appears where it needs to. But, then, if I maximize the browser window and try it, again, then the menu appears 3 or 4 hundred pixels too far to the right. It must have something to do with how the browser (or Profound?) centers my page content. Anybody have any ideas?

Re: Context Menu on Left Click

Posted: Tue Dec 24, 2013 11:18 am
by DaveLClarkI
I found where the 60 pixels are coming from. I now have the following in my code to resolve the top offset; but, the problem of what happens when the browser window is maximized is still unsolved for the left offset. Help?

Code: Select all

	hdr = getObj("wob-header");				// if there is a skin-defined header
	if (hdr)
	{
		offset.top -= hdr.offsetHeight;		// adjust for the skin header height
	}

	applyProperty(menuId, "left", (offset.left - 5 - 5) + "px"); // position the menu
	applyProperty(menuId, "top", (offset.top - 5) + "px");

Re: Context Menu on Left Click

Posted: Tue Dec 24, 2013 11:49 am
by Brian
David is out this week, but I may be able to help you here. If I am reading the previous posts correctly, you are capturing the coordinates of a mouse click and using it to display a context menu, right? But when you resize the screen, the menu doesn't adjust accordingly.

In theory, you could capture the width of the window when your context menu is displayed. So in your function to display your menu, you could store the browser width in a global variable. So in that function you could:

Code: Select all

pageWidth = window.innerWidth ;
Once you have that value stored. You could use it for comparison in a function for the "onresize" javascript event. So in your onload property for the screen you could do this:

Code: Select all

window.onresize = function () {
    var newWidth = window.innerWidth;
    var newXOffset = yourXOffset + (newWidth - pagewidth)/2 ;
    //  apply your new x offset to your context menu here
    }    
You would need to replace yourXOffset with whatever the current left property value is for the menu. You will most likely need to retrieve it using

Code: Select all

getObj(menuId).pui.properties["left"]
I have not tested this as I have a meeting in a moment with another customer, but I think this may get you on track. Let me know if this helps.

Re: Context Menu on Left Click

Posted: Tue Dec 24, 2013 12:17 pm
by DaveLClarkI
That is not going to help me because the browser window can be the "wrong" size when my page is first displayed. Thus, knowing the width of the current client area does not help me calculate where the menu should be positioned.

That is, of course, unless you'll next suggest that I use the width of the page I designed for and compare that to the client width of the run-time browser window. That might be a possibility.

But, what I'd really like to know is what properties and calculations does Profound UI use when displaying a right-click context menu at the mouse position? Those are exactly the calculations I need for my left-click selection menu.

Re: Context Menu on Left Click

Posted: Tue Dec 24, 2013 1:34 pm
by Brian
Ok, I think I misunderstood your issue. So you want to set the position to where the user clicked?

Have you looked at these functions?

getMouseX()
getMouseY()

They should return the X and Y coordinates of your click event.

The code to handle this inside Profound UI uses these functions as the base for positioning. There are some other tweaks made to handle special circumstances, but those are based on properties that are not publicly accessible. I think the two functions above will simplify this.

Re: Context Menu on Left Click

Posted: Tue Dec 24, 2013 2:44 pm
by DaveLClarkI
Those give me the same numbers I was getting on my own; thus, they don't help with the calculations. However, they do simplify my code a bit so I will use them, instead. The following is what I have now. Lastly, as they say, a picture is worth a thousand words. So, I've attached two pictures -- and displayed at the bottom -- menu1.png and menu2.png where menu1 is with the browser sized for a client area of 1024x768 and menu2 is with the browser maximized. Note that in both cases I clicked on the gear icon in the first column of the grid. So, the question is: How can I make the position calculation automatically adjust for whatever size browser window?

Code: Select all

wob.showContextMenu = function(menuId, event)
{
	var bodyOffsets, css, hdr,				// define local variables
		offset = wob.browserPageOffset();	// and get scrolled offset of page

	offset.left += getMouseX(event);		// add mouse coordinates
	offset.top += getMouseY(event);

	if (document.body
	&& document.body.getBoundingClientRect)	// adjust for a bounding client rectangle
	{
		bodyOffsets = document.body.getBoundingClientRect();
		offset.left -= bodyOffsets.left;	// subtract client rect. shifted to right
		offset.top -= bodyOffsets.top;		// subtract client rect. shifted down
	}

	hdr = getObj("wob-header");				// if there is a skin-defined header
	if (hdr)
	{
		offset.top -= hdr.offsetHeight;		// adjust for the skin header height
	}

	applyProperty(menuId, "left", (offset.left - 5 - 5 - 5) + "px"); // position the menu
	applyProperty(menuId, "top", (offset.top - 5) + "px");
	applyProperty(menuId, "z index", 100);			// put menu on top of everything
	applyProperty(menuId, "visibility", "visible");	// make menu visible
}
menu1.png
menu1.png (62.29 KiB) Viewed 837 times
menu2.png
menu2.png (66.56 KiB) Viewed 837 times

Re: Context Menu on Left Click

Posted: Tue Dec 24, 2013 3:24 pm
by Scott Klement
Dave,
But, what I'd really like to know is what properties and calculations does Profound UI use when displaying a right-click context menu at the mouse position? Those are exactly the calculations I need for my left-click selection menu.
The code for most of Profound UI's runtime framework is open source, so you can see the code if you want!

One caveat, though: Profound UI's code is 'obfuscated'. We run a tool called Closure from Google to combine all of the JavaScript files (there are quite a few) together into one file, and make it as small as possible. This way it loads faster and uses less memory. The problem this creates for you is that you won't be able to simply call all of the same routines, or access the same properties that PUI uses because they'll have been changed to different/smaller names. And we do not recommend using the obfuscated names because they can change the next time we build it.

Having said that, though... if you dig deep enough, you should be able to find all of the needed details, it just might end up being a lot of code. You'd need to reproduce the stuff that's obfuscated in your own code.

The code is online at the following link:
https://github.com/ProfoundLogic/profoundui-framework

In the above open source code (which does not include Genie or Atrium, but does include the Rich Display environment, and that includes all of the widgets) we have the 'obfuscated' result in runtime.js, which is basically unreadable. But the 'source code' that's used to create runtime.js is also there, in the profoundui/js directory. So you can go there and see how it works, if you're so inclined.

In this specific case, you're looking for code inside the grid widget, which is under widgets/grid/Grid.js, and starts around line 3882. Here's a direct link:
https://github.com/ProfoundLogic/profou ... id/Grid.js

IMHO, it's probably easier to wait until our David has a chance to make an API for you.

Re: Context Menu on Left Click

Posted: Tue Dec 24, 2013 3:29 pm
by Alex
Looking in our code to for displaying the context menu in the Grid, it looks like we resolve the offset by using the following values:
pui.runtimeContainer.offsetLeft
pui.runtimeContainer.offsetTop

Can you try using these as offsets and see if helps to properly position the menu?

Re: Context Menu on Left Click

Posted: Thu Dec 26, 2013 10:49 am
by DaveLClarkI
Perfect! Not only did that take care of the fudging I was having to adjust into the left-right position, but it removed the need for me to check for a skin-defined header. So, what I have now is as follows and is working as desired. Thanks.

Code: Select all

/*	================================================================================
	showContextMenu()	positions a menu widget at the current mouse position and
						makes the menu visible.
*/
wob.showContextMenu = function(menuId, event)
{
	var offset = wob.browserPageOffset();	// get scrolled offset of page

	offset.left += getMouseX(event);		// add mouse coordinates
	offset.top += getMouseY(event);

	offset.left -= pui.runtimeContainer.offsetLeft;	// adjust for Profound's outer container
	offset.top -= pui.runtimeContainer.offsetTop;

	applyProperty(menuId, "left", (offset.left - 5) + "px"); // position the menu
	applyProperty(menuId, "top", (offset.top - 5) + "px");
	applyProperty(menuId, "z index", 100);			// put menu on top of everything
	applyProperty(menuId, "visibility", "visible");	// make menu visible
}