I'm trying to enable a double click event on a flex control without disabling the default mouseup/mousedown behaviors.
I'm using the ESRI Flex API for arcgis server, and I have a map control with one background layer and a GraphicLayer. The graphics layer has several Graphic objects that respond to mouseover, and allow the user to pan the map if they click and hold. However, when I implement a double click event handler for the graphic objects, they no longer seem to bubble up their default behavior to the map.
Is there a way to implement a double click on a Graphic object while preserving the old behavior from clicking and holding?
I solved this by attaching the double click event to the map, rather than the graphic, and using the target attribute of the event to get the graphic I wanted to use.
Like this:
map.addEventListener(MouseEvent.DOUBLE_CLICK, function(event:MouseEvent):void
{
var graphic:Graphic = event.target as Graphic;
if(graphic)
{
...
}
});
If you set the "checkForMouseListeners" property to false on your Graphic objects, then the default map click/drag behavior will be preserved.
graphic.addEventListener(MouseEvent.DOUBLE_CLICK, function(event:MouseEvent):void {
var graphic:Graphic = event.target as Graphic;
if(graphic) {
...
}
});
//preserve the default click/drag behavior on the map
graphic.checkForMouseListeners = false;
http://resources.esri.com/help/9.3/ArcGISServer/apis/Flex/apiref/com/esri/ags/Graphic.html#checkForMouseListeners
Related
I am creating a custom confirmation dialog in Google App Maker and would like the Confirm button to call a passed-in function. I don't see an "onclick" event in the button widget. Any suggestions on how to do this?
function confirmationDialog(msg, confirmFunction)
{
var desc = app.pageFragments.ConfirmationDialog.descendants;
var label = desc.Label;
var confirmButton = desc.Confirm;
label.text = msg;
confirmButton.onClick = confirmFunction; // does not work
app.showDialog(app.pageFragments.ConfirmationDialog);
}
Thanks
It'd be great if this was a bit easier, but the best bet is to use Custom Properties (https://developers.google.com/appmaker/ui/viewfragments).
You can set up a custom property of type "Dynamic" and call it anything, take "onConfirmCallback", for example. Then you can set the function on that custom property:
Code to invoke dialog:
app.pageFragments.ConfirmationDialog.properties.onConfirmCallback = function(param) {
alert(param);
};
app.showDialog(app.pageFragments.ConfirmationDialog);
And then in the onClick for the close button:
app.pageFragments.ConfirmationDialog.properties.onConfirmCallback("hi");
app.closeDialog();
Also note that there are slightly better ways to set up labels than in your example, also using custom properties.
Create custom properties for any widget properties you want to customize, and then bind those custom properties (#properties.propertyName) to the widget property. For example you might have a confirmText property, with the confirm buttons text property boudn to #properties.confirmText.
Then when you invoke your dialog, you can just set those custom properties. Quick modification of your example code using properties for everything:
function confirmationDialog(msg, confirmFunction)
{
var properties = app.pageFragments.ConfirmationDialog.properties;
properties.text = msg;
properties.confirmCallback = confirmFunction;
app.showDialog(app.pageFragments.ConfirmationDialog);
}
For my confirmation dialogs, I just set the onclick of the OK button before I show the dialog (everything is in one place, which is easier for the dummy (me) who will have to maintain it in six months:
var dialog=app.pages.ConfirmationDialog;
dialog.descendants.message.text='Are you sure...?'
dialog.descendants.btnOk.getElement().onclick=function(){
//do something here
app.closeDialog();
});
};
app.showDialog(dialog);
}
I converted my gridview to tile view and I added some format rules. When I run my project, format rules doesn't work.I'm sure my rule is correct. What should I do ?
As I discovered till now, To customize the tile conditionally then you should handle TileView.ItemCustomize Event.
Refer this: Tile View
The TileView.ItemCustomize event fires for each tile before this tile
is displayed. When handling this event, you can read its e.Item
parameter to access the completely generated, ready to be displayed
tile item. Afterwards, you can apply required changes. For instance,
apply a different background color or access the TileItem.Elements
collection to modify specific elements.
All TileViewItemElements within the view can be customized by accessing appearance settings available through the TileView.AppearanceItem property. At the same time, each individual element has its own appearance settings that override this global appearance. To access these appearances, use the TileItemElement.Appearance property.
example:
private void tileView1_ItemCustomize(object sender, DevExpress.XtraGrid.Views.Tile.TileViewItemCustomizeEventArgs e) {
e.Item.Elements[6].Text = String.Format("${0}M", ((Decimal)(Int32)tileView1.GetRowCellValue(e.RowHandle, colPrice) / 1000000).ToString("0.0"));
if ((bool)tileView1.GetRowCellValue(e.RowHandle, colSold) == true) {
e.Item.Elements[1].Image = global::TileViewHomes.Properties.Resources.gray_element;
e.Item.Elements[6].Text = "SOLD";
//Changes background colour of non selected tileitem
e.Item.AppearanceItem.Normal.BackColor = Color.Red;
}
}
References:
tileView_ItemCustomize is not updating until resize
I am currently working on a strategy game and I want to preform actions using GUI.Button on game objects. I am using ray cast and mouse click to select the object however when I click on GUI.Button to take out another action the button disappears. I want to use that button to open up another GUI.Box to show some descriptions.
I know why the button is disappearing, it is because I am projecting the ray cast to my button clicks in the update function but how can I avoid this? I also know that I have to use EventTrigger however I am not familiar with javascript event trigger, I searched online but I couldn't find any helpful javascript.
Screenshots:
Here is my script:
#HideInInspector
var isCalled:int = 0;
#HideInInspector
var scWidth:int = 0;
#HideInInspector
var scHeight:int = 0;
function Start () {
scWidth = Screen.width;
scHeight = Screen.height;
}
function Update () {
if (Input.GetMouseButtonDown(0)) {
var ray : Ray = Camera.main.ScreenPointToRay (Input.mousePosition);
var hit : RaycastHit;
if (Physics.Raycast (ray, hit)) {
if (hit.collider.tag == "House") {
isCalled = 1;
} else{
isCalled = 0;
}
}
}
}
function OnGUI(){
if(isCalled==1)
GUI.Button(Rect(scWidth/2,(scHeight/2)+(scHeight/4),120,120), name);
}
}
If I understood you right, the problem is that when you click on button the raycast is fired up before button click and you select different object or no object at all and button disappears or reappears but for another object, what you need to do is check if you clicked on GUI and if yes don't project the raycast that selects the objects. Here is how you are gonna do it.
var selectedUI : GameObject = EventSystem.current.currentSelectedGameObject;
if (Input.GetMouseButtonDown(0) && selectedUI) {
var ray : Ray = Camera.main.ScreenPointToRay (Input.mousePosition);
var hit : RaycastHit;
if (Physics.Raycast (ray, hit)) {
if (hit.collider.tag == "House") {
isCalled = 1;
} else{
isCalled = 0;
}
}
}
I work in C#, so I might have done some syntax errors, but the logic is right.
There is a good trick when using legacy GUI system to avoid raycast when mouse is over GUI elements. Using tooltip to controll if you may cast your ray =)
Something like this (I also don't work with US so may I it needs some work):
var hover : String;
function OnGUI(){
if(GUI.Button (Rect (10,10,100,20), "My Button"));
hover = GUI.tooltip;
function Update () {
if(hover != "") {
// raycast logic
}
}
If you need to avoid raycast when your "popUp" window/panel is shown but you don't want a tooltip on it you may approach using a MouseOverGUI manager too.
It is just a static or singleton holding a boolean that you will set true when your mouse is over some rect that you don't want to cast rays using Rect.Contains(Event.current.mousePosition) and to false whenever it runs out of this rect.
Use this bool with or without tooltip var to allow raycast:
if(!MouseManager.MouseOverGUI) {
// raycast logic
}
Note that creating your rect on each OnGUI cycle will difficult to catch it and control the MouseOveGUI. Also it is a bad practice for performance because OnGUI runs more than once per frame so I'll suggest you to create you rects just once (recalculate it just when needed) and pass it to your GUI elements ;)
I think the easiest way is to create a GameObject(input blocker) which is not visible but have a collider. Place it in between the camera and level objects and deactivate it. When you select a GameObject using Raycast you enable that input blocker GameObject and place it around the area of selected GameObject and GUI. Then you have to ignore the selection if raycast is collided with Input Blocker. When you deselect the Gameobject then you deactivate input blocker
You should also maintain current state of the game for example:
enum State
{
NothingSelected = 0,
GameobjectSelected,
BigMenuOpen
}
State currentState;
So according to state you can define the behavior on mouse click. Like if Full screen menu is Open then raycast does not fire.
I understand how to get my current location with HTML5.
How do I add a click handler, so when a button is pressed it shows my current position on the map?
Google's example pretty much explains how it's done, but the button is set to predefined coordinates. How do I attach the "Home" button to current position coordinates instead?
Custom Control Example
From Google demo
navigator.geolocation.getCurrentPosition(function(position) {
initialLocation = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
map.setCenter(initialLocation);
As initialLocation is global you can use this to set the click event listeners: simply set the map to initialLocation
google.maps.event.addDomListener(controlUI, 'click', function() {
map.setCenter(initialLocation)
});
I am trying to drag and drop an object across the SkinnableContainer- am coming across a very strange issue
The drop occurs only at a few places- elsewhere it just shows the "X" sign and on dropping there, reverts to original position. I have used very standard commands... from function 2 to function 3, the call occurs very rarely as seen in trace statements- any guidance on why this happens?
I added the following code to SkinnableContainer: dragEnter="dragEnterHandler(event);" dragDrop="dragDropHandler(event);
(1):
private function mouseMoveHandler(event:MouseEvent):void
{
var dragInitiator:Image = Image(event.currentTarget);
var ds:DragSource = new DragSource();
ds.addData(dragInitiator,"img"); //made change here
DragManager.doDrag(dragInitiator, ds, event);
}
(2):
private function dragEnterHandler(event:DragEvent):void {
if (event.dragSource.hasFormat("img"))
{
trace("came here"); //comes here for each mouse move
DragManager.acceptDragDrop(SkinnableContainer(event.currentTarget));
}
(3):
private function dragDropHandler(event:DragEvent):void {
trace("in drag drop handler"); //doesn't come here for most places
According to the Using Flex 4 reference:
To use a container as a drop target, you must use the backgroundColor property of the container to set a color. Otherwise, the background color of the container is transparent, and the Drag and Drop Manager is unable to detect that the mouse pointer is on a possible drop target.
In the subsequent example, they use an mx container (Canvas), but I checked the AS3 reference, and spark.components.SkinnableContainer does have a style backgroundColor.
I haven't tried this myself, so please confirm whether it is the issue. From your description that only certain parts of the container are registering the dragEnter event, this seems like a consideration that would lead to such effects.