Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Ctrl up and down sensing

Guest
Jan 23, 2013 Jan 23, 2013

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');

    }

   

}

TOPICS
ActionScript
1.9K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

LEGEND , Jan 24, 2013 Jan 24, 2013

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

...
Translate
Guru ,
Jan 24, 2013 Jan 24, 2013

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');

    }

}

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jan 24, 2013 Jan 24, 2013

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:

http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf64a29-7fdb.html#WS2db454920e96...

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Jan 24, 2013 Jan 24, 2013

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?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Jan 24, 2013 Jan 24, 2013

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.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Jan 24, 2013 Jan 24, 2013

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.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Jan 24, 2013 Jan 24, 2013

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!!!!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jan 24, 2013 Jan 24, 2013

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?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Jan 24, 2013 Jan 24, 2013

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

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jan 24, 2013 Jan 24, 2013

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:

http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/fl/core/UIComponent.html#focusEna...

// stage (or last object selected) retains focus

myDatagrid.focusEnabled = false;

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Jan 24, 2013 Jan 24, 2013

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

?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jan 24, 2013 Jan 24, 2013

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.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Jan 24, 2013 Jan 24, 2013

Agreed. Disabling the focus ability is better. While you are at it: disable the mouseFocusEnabled property, too. Otherwise it could be a Pyrrhic victory.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Jan 24, 2013 Jan 24, 2013

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.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Jan 24, 2013 Jan 24, 2013

just write:

myDataGrid.focusEnabled = false;

myDataGrid.mouseFocusEnabled = false;

and forget about:

myDataGrid.addEventListener(KeyboardEvent.KEY_UP, onKeyBoardUp);

myDataGrid.addEventListener(KeyboardEvent.KEY_DOWN, onKeyBoardDown);   

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Jan 24, 2013 Jan 24, 2013

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.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jan 24, 2013 Jan 24, 2013

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.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Jan 24, 2013 Jan 24, 2013

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.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jan 24, 2013 Jan 24, 2013
LATEST

We've all been there. You're welcome and glad it's working for you. Hit that deadline!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Jan 24, 2013 Jan 24, 2013

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

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Jan 24, 2013 Jan 24, 2013

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.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines