Copy link to clipboard
Copied
Hi
I want to set a public var to true when ctrl of shift are pressed, and then false when they are not pressed. This is to tie in with some datagrid functions that react differntly when Ctrl or shift are down.
onKeyBoardDown() is sussessfully tracing when the keys are down, but onKeyboardUp is not when they are released. Why is that? THANKS!
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyBoardUp);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyBoardDown);
private function onKeyBoardDown(event:KeyboardEvent):void
{
if ( event.ctrlKey ) //if control key is down
{
trace ('CTRL on');
}
else if ( event.shiftKey )
{
trace ('SHIFT on');
}
else
{
trace('NONE!!!');
}
}
private function onKeyBoardUp(event:KeyboardEvent):void
{
if ( event.ctrlKey ) //if control key is up
{
trace ('CTRL off');
}
else if ( event.shiftKey )
{
trace ('SHIFT off');
}
}
To answer why your original code doesn't work, you're using KeyboardEvent to indicate the current state of the 2 keys in an "if/else" manner.
For example, when you release CTRL, event.ctrlKey is always going to be false (because it's no longer down of course). Same thing with releasing SHIFT if you release that, it will always be false.
Use the keyCode as moccamaximum mentioned but you should detect combinations by not limiting it to "if/else".
e.g.:
...
var ctrlIsDown:Boolean = false;
var shiftIsDown:B
Copy link to clipboard
Copied
It`s weird, I `ll give you that.
Workaround: use keyCode (tested under win 7 64bit)
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyBoardUp);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyBoardDown);
function onKeyBoardDown(e:KeyboardEvent):void
{
//trace("Down:"+e.keyCode);
if ( e.keyCode == 17 )
{
trace ('CTRL on');
}
else if ( e.keyCode == 16 )
{
trace ('SHIFT on');
}
}
function onKeyBoardUp(e:KeyboardEvent):void
{
//trace("UP:"+e.keyCode);
if ( e.keyCode == 17 )
{
trace ('CTRL off');
}
else if ( e.keyCode == 16 )
{
trace ('SHIFT off');
}
}
Copy link to clipboard
Copied
To answer why your original code doesn't work, you're using KeyboardEvent to indicate the current state of the 2 keys in an "if/else" manner.
For example, when you release CTRL, event.ctrlKey is always going to be false (because it's no longer down of course). Same thing with releasing SHIFT if you release that, it will always be false.
Use the keyCode as moccamaximum mentioned but you should detect combinations by not limiting it to "if/else".
e.g.:
var ctrlIsDown:Boolean = false;
var shiftIsDown:Boolean = false;
function onKeyBoardDown(e:KeyboardEvent):void
{
if ( e.keyCode == 17 )
{
trace ('CTRL on');
// set state var for CTRL
ctrlIsDown = true;
}
// don't use else here, separate logic
if ( e.keyCode == 16 )
{
trace ('SHIFT on');
// set state var for SHIFT
shiftIsDown = true;
}
}
function onKeyBoardUp(e:KeyboardEvent):void
{
if ( e.keyCode == 17 )
{
trace ('CTRL off');
// set state var for CTRL
ctrlIsDown = false;
}
// dont use else here, separate logic
if ( e.keyCode == 16 )
{
trace ('SHIFT off');
// set state var for SHIFT
shiftIsDown = false;
}
// make a function to check key states
// if necessary here and do any adjustments
// based on shift or control separately
}
keyCode has limits, beware. Alternate keyboards are known to change keyCode values to unexpected results. Change as necessary. Consider charCode as well as keyCode has other limits:
Copy link to clipboard
Copied
Thank you both.
Is there a reason that event.ctrlKey doesn't work on release that I'm misunderstanding?
Also, are you guys familiar with Macs ie are shift and ctrl used in the same as Windows for multi selection, or should I be setting up extra key codes to test on Macs as well?
Copy link to clipboard
Copied
I must admit, since I always used keyCode, I never thought to deeply about how the named "special" keys work differently from the "common". But sinious' explanation is really good.
Copy link to clipboard
Copied
Yeah - I missed the the link when I first read his post.
It's working, but clicking on certain areas of the datagrid turns off the keyboard listeners, and then click in other areas turns them back on. I'm going to try setting the listeners in the doc class so they are a bit more global.
Copy link to clipboard
Copied
Yep - it's working now. I set up the listener in the doc class, and used a setter (thanks for teaching me about setters Sinious!!!!) to set booleans for Ctrl and Shift in the class that has my datagrid, and it's obeying!!!
Cheers guys!!!!
Copy link to clipboard
Copied
You're welcome and good luck!
edit: Didn't see the last 2 as well. Yes setting focus back to the stage is ideal as that's where the listeners are anyhow.
Any component is free to use KeyboardEvent listeners as well. If they don't bubble their events back to stage which is listening then you won't receive the event. You can either add listeners only to the DataGrid itself (so CTRL/SHIFT are only affected using the grid) or both to the DG and the stage (if that's your desired behavior). If you have other components, I'd just listen to the DG rather than stage.
As for removing an item, if it's in an event dispatching context (extends the event dispatch interface, like a display object) you can dispatch an event before removing the item. The original event may not bubble but the new event should dispatch.
What exactly is the issue that's happening here?
Copy link to clipboard
Copied
Yes - putting stage.focus=stage in my data_gridClicked(event:ListEvent) function seems to fix it.
No issue - I'm not removing anything. Just clicking certain areas of the DG made the keyboard listeners not function (until putting stage.focus=stage in).
I'll see how it all works now once I get some more functionality in there.
Cheers guys
Copy link to clipboard
Copied
Don't forget the focusEnabled property of a DataGrid which can force the DataGrid NOT to take focus when clicked, which can be much cleaner:
// stage (or last object selected) retains focus
myDatagrid.focusEnabled = false;
Copy link to clipboard
Copied
Just re-read your post Sinious - so if I set it up so just the datagrid is listening for the events, do I still put stage.focus=stage to overcome the problem (where clciking certain areas seems to mute the keyboard listener), and is the set up in the class still:
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyBoardUp);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyBoardDown);
or would it be
myDataGrid.addEventListener(KeyboardEvent.KEY_UP, onKeyBoardUp);
myDataGrid.addEventListener(KeyboardEvent.KEY_DOWN, onKeyBoardDown);
and then
myDataGrid.focus = myDataGrid
?
Copy link to clipboard
Copied
This is almost a chat room at this speed . I think my previous post will be a better solution. But to answer you would use either both of those (if there are no other uses for CTRL/SHIFT watching) or just the latter if you wish other components to handle those keys separately.
I'm away a few, try the focusEnabled method and leave all your code how it used to be, just on stage listeners.
Copy link to clipboard
Copied
Agreed. Disabling the focus ability is better. While you are at it: disable the mouseFocusEnabled property, too. Otherwise it could be a Pyrrhic victory.
Copy link to clipboard
Copied
So both need to go in the datagrid class?:
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyBoardUp);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyBoardDown);
myDataGrid.addEventListener(KeyboardEvent.KEY_UP, onKeyBoardUp);
myDataGrid.addEventListener(KeyboardEvent.KEY_DOWN, onKeyBoardDown);
I tried just the latter, and it wouldn't fire the function.
Copy link to clipboard
Copied
just write:
myDataGrid.focusEnabled = false;
myDataGrid.mouseFocusEnabled = false;
and forget about:
myDataGrid.addEventListener(KeyboardEvent.KEY_UP, onKeyBoardUp);
myDataGrid.addEventListener(KeyboardEvent.KEY_DOWN, onKeyBoardDown);
Copy link to clipboard
Copied
Dumb question...
But leave
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyBoardUp);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyBoardDown);
in, right (to capture my Ctrl and Shift events)?
And just to be extra sure... using
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyBoardUp);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyBoardDown);
in the datagrid's class means only that class listens for the events, as opposed to using it in the doc class.
If I have a question quota - I reckon I've used it up tonight!!!!!
Cheers guys.
Copy link to clipboard
Copied
Yep just those 2 stage listeners.
It means the DataGrid will use event bubbling and custom functionality to avoid taking focus while still functioning as a DataGrid normally.
Copy link to clipboard
Copied
Cheers - I'll leave you guys in peace now!!!
It's taken a while to get my head around the logic of what I'm trying to achieve with the DG, but after four days and a lot of help from the forum, I think it's almost there.
Thank you.
Copy link to clipboard
Copied
We've all been there. You're welcome and glad it's working for you. Hit that deadline!
Copy link to clipboard
Copied
There is this somehow strange behavior, that if you click on a displayobject to remove it from the stage it takes the focus with it.
And since its no more part of the DisplayList it can not bubble up to it.
Only way to get this eventlisteners running again (that I know of) is to manually force the focus back to stage:
stage.focus=stage
Copy link to clipboard
Copied
Yep - spoke too soon. Will have to investigate what you mentioned Mocca. It's find if I click on a text input in the datagrid, but if I click anywhere else it seems to ignore the listener.
Find more inspiration, events, and resources on the new Adobe Community
Explore Now