How to process right-mouse click on the globe

1,095 views
Skip to first unread message

mikemcc

unread,
Dec 5, 2010, 6:35:14 AM12/5/10
to KML Developer Support - Google Earth Plug-in
I am trying to get the GE API to do something when the user releases
the right-mouse button on the GE globe.

Thanks to suggestions in this forum and associated API documentation,
I have developed the following code, but it only partly works. Any
ideas please why it doesn't work ?

When GE is loaded:
google.earth.addEventListener(ge.getWindow(), 'mouseup',
myEventListener);

Then:
function myEventListener(KmlMouseEvent) {
var mouseButton = KmlMouseEvent.getButton();
var hitGlobe = KmlMouseEvent.getDidHitGlobe();
if(mouseButton==2 && hitGlobe==1) {
alert("Right mouse button was clicked on globe.");
}
}

Then:
<body onload="init()" style="font-family: arial, sans-serif; font-
size: 13px; border: 0;">
<div id="map3d_container">
<div id="map3d"></div>
</div>
</body>

If I click on the right mouse button or the scrollwheel, the cursor
changes into what looks like a mini navigation control and no mouseup
is detected, so the function isn't executed.

A screen shot of the changed cursor is at:
http://www.around-the-world.co.uk/public/CursorAfterRightMouseClick.jpg

NB. If I add the following before if(mouseButton ..... :
alert("mouseButton: "+mouseButton);
alert("hitGlobe: "+hitGlobe);
and then click the left mouse button on the globe, I learn 2 things:

1. mouseButton = 0 whether I am browsing in IE or FF; having read the
documentation, I would expect IE to return 1, but never mind, that
doesn't affect me as I'm only interested in right mouse clicks.

2. hitGlobe = true = 1, which is what I wanted.

So I would be very grateful if someone can suggest how to get the
event listener to accept right mouse clicks. Thanks.

StarTraX

unread,
Dec 5, 2010, 6:31:25 PM12/5/10
to KML Developer Support - Google Earth Plug-in
You add an event listener for the "click" event, like:
google.earth.addEventListener(myPoints.item(points), 'click',
function(myKmlEvent)
then you interrogate the click to determine its type:
if (myKmlEvent.getButton() == 2) {
2 is "right"

Easy, once you know ;-)

kyonn

unread,
Dec 6, 2010, 1:07:23 AM12/6/10
to KML Developer Support - Google Earth Plug-in
The question "could the automatic cursor change be avoided ?"

may be answered by adding at the top of your event

event.preventDefault(); // event.stopPropagation();

But I don't have tested it so please tell us if you success.
'cause i'm interested with an eventual right-click custom contextual
menu. (http://abeautifulsite.net/blog/2008/09/jquery-context-menu-
plugin/ )

mikemcc

unread,
Dec 6, 2010, 6:09:03 PM12/6/10
to KML Developer Support - Google Earth Plug-in
Thanks v much StarTrax and Kyonn.

Not being an experienced JS programmer, I have tried to follow
StarTrax's instructions closely and have coded:

google.earth.addEventListener(ge.getGlobe(), 'click',
processClick(myKmlEvent));
and then:
function processClick(myKmlEvent) {
if (myKmlEvent.getButton() == 2) {
alert("Right mouse button was clicked on globe.");
}
}

But right mouse click still just changes the cursor into a mini
navigation control.
NB I'm happy for the function (which will be to add a draggable
placemark) to take place on right mouse button down, not on RMB up as
first mentioned).

Can you spot a problem in the above code please ? If not ....

I also have:
google.earth.addEventListener(ge.getWindow(), 'mouseup', mouseUp);
just before the click listener (obviously to perform a different
function which I won't bore you with - yet).
The click listener still doesn't do anything when I comment out the
mouseUp listener, so I don't think that the mouseUp listener and/or
function prevent the click listener from calling the processClick
function. NB One is listening in the window; the other is listening in
the globe.

I will try Kyonn's idea once I get the above working. Do you mean put
it at the start of the function triggered by the event ?

Thanks very much for any extra help.

StarTraX

unread,
Dec 6, 2010, 9:16:17 PM12/6/10
to KML Developer Support - Google Earth Plug-in
This "mini navigation control" is a challenge.
I suspect it's to do with some setting in your browser - what are you
using IE, FF, Chrome? Have you tried with another? I get the that
control in FF with the centre button press, but not in IE8.

mikemcc

unread,
Dec 7, 2010, 7:47:30 PM12/7/10
to KML Developer Support - Google Earth Plug-in
Thanks StarTrax.

In answer to your question, I tried my initial code on 2 PCs in:
- FF 3.6
- IE 7 and 8
- Chrome 8.0.552.215
- Opera 10.63
and in each one, the mini navigation control is displayed on a right
mouse button click. I don't really change browser settings other than
in Opera.

BTW I wonder if anyone happens to know what that mini nav control
thing is officially called ? I haven't had time to look yet. It is
displayed after a rmb click on my other GE API pages (which is OK cos
I don't try to trap rmb clicks). Anyway ...

Today I found a recent and very detailed study of mouse clicks in
different browsers at:
http://unixpapa.com/js/mouse.html

I have created a stripped-down attempt to follow your suggestion at:
http://www.around-the-world.co.uk/public/listen4click.html

and an attempt to follow unixpapa's suggestion at:
http://www.around-the-world.co.uk/public/listen4mouseup.html

However, I notice in his source code that his test at "Click here with
various mouse buttons to test" uses onmouseup in the html rather than
the recommended approach of listening for mouseup, which I've tried to
use above.

When I tried his onmouseup approach at:
http://www.around-the-world.co.uk/public/onmouseup.html
LMB and RMB on the white surrounds to the map3d are reported if the
onmouseup is in the <body> tag, but LMB and RMB on the map3d do
nothing if the onmouseup is in the <div> tags for map3d or
map3d_container.

I imagine we could do a lot of people a favour if we can trap a simple
right mouse button click - or perhaps we are the last 3 people in the
world to work out how to do so !

It would be great if you or some other GE API gurus could click on
those links and see if they experience anything different and/or spot
any source code errors like bad use of the DOM.

Thanks.

StarTraX

unread,
Dec 8, 2010, 2:47:11 AM12/8/10
to KML Developer Support - Google Earth Plug-in
My listeners for the mouse click event (which work as described) are
attached to a placemark.
You have attached it to the globe. Why would you want to add the
listener to the globe rather than to a placemark?
I wonder if that's the problem?

mikemcc

unread,
Dec 8, 2010, 6:11:05 AM12/8/10
to KML Developer Support - Google Earth Plug-in
Hmm. Thanks StarTraX.

Well, I'm trying to allow the user to right-click on the globe where
he wants to add a new placemark, so I thought that I should listen for
clicks on the globe. When the user clicks on the globe, the placemark
isn't there. Surely adding the listener to placemarks would only be
useful when I want the user to be able to click on an existing
placemark to change, drag or delete it (which is the next function I
have to add, so that code will be great, thanks) ? Or am I
misunderstanding things ?

4thParty

unread,
Dec 8, 2010, 9:16:49 PM12/8/10
to KML Developer Support - Google Earth Plug-in
The Globe right mouse controls the zoom-rotate functions, you may be
better off attaching it to an area defined by an overlay or polyline.

mikemcc

unread,
Dec 12, 2010, 5:53:11 AM12/12/10
to KML Developer Support - Google Earth Plug-in
Thanks to all your help, I have developed a solution.

Because of 4thParty's observation, I abandoned the right-mouse click.
Forum threads show how complex it is to use double-click, so the best
option was to use ctrl-click.

So I added this to the initial script:

google.earth.addEventListener(ge.getGlobe(), 'mouseup', myKmlEvent);

and added this function:

function myKmlEvent(kmlEvent) {
var ctrlKey = kmlEvent.getCtrlKey();
if(ctrlKey==1) {
createPlacemarkDrag(kmlEvent);
}
kmlEvent.preventDefault();
}

RBinSFla

unread,
Sep 29, 2011, 5:42:06 PM9/29/11
to google-earth-...@googlegroups.com
This is my first blog post EVER so I hope some one finds it usefull.  I'm trying to give back to the community since I have benifitted so much from other people's posts.

Background:
I have been trying to display a context menu when a user right-clicks anywhere in the window and I've had problems similar to those described by mikemcc
Specifically the "mini-navigation control" is displayed and the mouse up event does not seem to be activated.

The application I am writing is in Windows Presentation Foundation (WPF) and I am hosting a Google Earth enabled web page in a WebBrowser control.
In the JavaScript page for google earth I am using windows extensions so I can write the bulk of the code in C# since I am more familliar with this than JavaScript.
The code is similar enough that it should be understandable.  For people who want to do this all in JavaScript there is no reason my C# functions could not be ported ito the JavaScript event handlers.

If anyone is interested in taking the C# combined with JavaScript approach that I am using be WARNED that the windows extensions will not work with older versions of Google Earth Plugin. 
I'm not sure which versions don't work but I think you have to use at least version 6.
I'm using Google Earth Plugin version 6.0.3.2197.

If anything is not clear or you have problems let me know.

Solution:

The basic solution is that you HAVE to have a mousedown event handler with e.preventDefault() in it and the context menu MUST be opened in a mouseup event handler.
See code sections below.

I know it looks easy now but I spent a lot of time trying different approaches to get this to work.

Question:
I'm not sure what the defaults are for the left, middle, and right mouse clicks and therefore I'm not sure when to use e.preventDefault().
I've been using a trial and err approach.
If anyone knows about this I would be happy to see a post.

JavaScript Code:

//standard Google Earth Plugin creation function.
function init() {
    google.earth.createInstance('map3d', initCallback, failureCallback);
}

function initCallback(pluginInstance) {
    ge = pluginInstance;
    ge.getWindow().setVisibility(true);

    // tell the application the plugin is ready
    window.external.JSInitSuccessCallback_(pluginInstance);  //this calls a C# function that returns the plugin instance object and allows me to do other initialization in the C# code.

    //setup javascript mousedown and mouseup event handlers.
    google.earth.addEventListener(ge.getWindow(), 'mousedown', MouseDownEventHandler, false);
    google.earth.addEventListener(ge.getWindow(), 'mouseup', MouseUpEventHandler, false);
}


function MouseDownEventHandler(event) {
    window.external.csGE_MouseDown_EventHandler(event); //Handler in C# code see below.
}

function MouseUpEventHandler(event) {
    window.external.csGE_MouseUp_EventHandler(event); //Handler in C# code see below.
}

C# Code:

        public void csGE_MouseDown_EventHandler(KmlMouseEventCoClass e)
        {
            e.preventDefault(); //This is needed to prevent going into navigation mode when the mouse is right clicked.
 //Without this the first right-click will bring up the context menu like it should but after that
 //it display's the mini-navigation control and does not work right.
        }

        //This was originally tied to the MouseDown event but this caused a problem.  
        //When used with the wb.ContextMenu the mouse up event was not captured by GE and the globe would move around after the context menu was closed.
        public void csGE_MouseUp_EventHandler(KmlMouseEventCoClass e)
        {
            if (e.getTarget().getType().Equals("KmlPlacemark"))
            {
                KmlPlacemarkCoClass pm = (KmlPlacemarkCoClass)e.getTarget();

                if (e.getButton().Equals(KmlMouseButton.Left) )//if left click and placemark show the description info in full( with css/html/javascript)
                {
                    // Prevent the default balloon from appearing. This didn't seem to be needed.
                    //e.preventDefault();
                    string descriptionStr = pm.getDescription();
                    GEHtmlStringBalloonCoClass balloon = ge.createHtmlStringBalloon("");
                    balloon.setFeature(pm);
                    balloon.setContentString(descriptionStr);
                    ge.setBalloon(balloon);
                }
                else if (e.getButton().Equals(KmlMouseButton.Right) )
                {
                    IKmlObject ko = pm.getParentNode();
                    string pmName = pm.getName();
                    object ro = pm.getRootObject();
                    string r = ro.ToString();

                    //these didn't seem to be needed here.
                    //e.preventDefault();
                    //e.stopPropagation();

                    // check to see if this is a KmlFolder.
                    string s = ko.getType();
                    if (ko.getType().Equals("KmlFolder")) //make sure this is a folder.
                    {
//there was some other code here but it was not relevant to the solution being demonstrated.
                        wb.ContextMenu.IsOpen = true;  //This causes the WebBrowser's Context menu to be displayed when a placemark is right-clicked.  //
//The Context Menu is defined elsewhere and not shown here.
                    }
                }
            }
            else if (e.getButton().Equals(KmlMouseButton.Right))
            {
                //these didn't seem to be needed here.
                //e.preventDefault();
                //e.stopPropagation();
                wb.ContextMenu.IsOpen = true;  //This causes the WebBrowser's Context menu to be displayed a user right-clicks on anything that is not a placemark.  
            }
        }

Reply all
Reply to author
Forward
0 new messages