/**
* Copyright itou_hiroki ( http://wonderfl.net/user/itou_hiroki )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/swLA
*/
// -*- coding:utf-8-unix -*-
// Copyright (c) 2010 Itou Hiroki
// キーボード作成を2つしようとした。うまくいかない
// キーボード作成をカスタムクラスにした
// 「入力文字を下に表示する shift対応 IME対応 dropshadow Shiftの右と左を判断する 入力した最後の文字が赤くなる」
// Todo
// - Shiftの右と左を両方押して離すとShift残りが発生するが、両方押すことはないとしよう
package {
import flash.display.Sprite;
import flash.display.*;
import flash.events.*;
import flash.text.*;
import flash.system.IME;
import flash.filters.*;
[SWF(width="465",height="465",backgroundColor="0x888888",frameRate="60")]
public class FlashTest extends Sprite {
var mykbd1:TheKeyboard = new TheKeyboard(10, 10);
var mykbd2:TheKeyboard = new TheKeyboard(10, 275);
}
}
import flash.display.Sprite;
import flash.display.*;
import flash.events.*;
import flash.text.*;
import flash.system.IME;
import flash.filters.*;
class TheKeyboard extends Sprite {
private const STAGE_PADDING:uint= 3;
private const KEY_PADDING:uint = 2;
private const KEY_AREA:uint = 30;
private const KEY_COLOR:int = 0xeee8e8;
private const KEY_TRANCEPARENCY:Number = 1.0;
private const KEY_HIT_COLOR:int = 0xffcc00;
private const KEY_HIT_TRANCEPARENCY:Number = 0.5;
private const KEY_COLOR_OUTLINE:int = 0x333333;
private const KEY_CHAR_COLOR:int = 0x333333;
private const MAX_BOARD_LENGTH:int = 10;
private const KEYCODE_SHIFT_RIGHT:int = 255;
private var keyCodes:Array = new Array();
private var keys:Array = new Array();
private var brd:TextField = new TextField();
public function TheKeyboard(_x:int, _y:int) {
var i:int;
// write as3 code here..
if (IME.enabled){
IME.enabled = false;
}
make_japanese_keyboard_obj(_x, _y);
make_board(_x, _y);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
}
private function onKeyDown(e:KeyboardEvent):void {
var kc:uint = e.keyCode;
var i:int;
//trace('onKeyDown:', e.keyCode);
//IMEをONにしようとしたなら、OFFにする
if (IME.enabled){
IME.enabled = false;
}
// '229' is HanZen or IME enable key
if (keys[kc] === null || kc === 229){ return; }
//右shift
//trace('down keyloc=',e.keyLocation);
if (kc === 16 && e.keyLocation === 2) { kc = KEYCODE_SHIFT_RIGHT; }
keys[kc].pushed = true;
addChild(keys[kc].hit);
//16 or KEYCODE_SHIFT_RIGHT is 'Shift'
if (keys[16].pushed || keys[KEYCODE_SHIFT_RIGHT].pushed){
for (i=0; i<keyCodes.length; i++){
keys[keyCodes[i]].textfield.text = keys[keyCodes[i]].char_display_shift;
}
put_char_on_board(keys[kc].char_input_shift);
}else{
put_char_on_board(keys[kc].char_input);
}
}
private function onKeyUp(e:KeyboardEvent):void {
var kc:uint = e.keyCode;
var i:int;
//trace('onKeyUp:', e.keyCode);
//IMEをONにしようとしたなら、OFFにする
if (IME.enabled){
IME.enabled = false;
}
// '243' is HanZen key up code
if (keys[kc] === null || kc === 243){ return ; }
//右shift
if (kc === 16){
//trace('up keyloc=',e.keyLocation);
//右シフト押したまま文字キーを押して離して、それから右シフト離したときに
// e.keyLocationが2にならず0になるのはなぜだAdobe in FlashPlayer10.0.42.34
if (e.keyLocation === 2 || keys[KEYCODE_SHIFT_RIGHT].pushed) {
kc = KEYCODE_SHIFT_RIGHT;
}
}
if (keys[kc].pushed){
removeChild(keys[kc].hit);
keys[kc].pushed = false;
}
//16 or KEYCODE_SHIFT_RIGHT is 'Shift'
if (! keys[16].pushed && ! keys[KEYCODE_SHIFT_RIGHT].pushed){
for (i=0; i<keyCodes.length; i++){
keys[keyCodes[i]].textfield.text = keys[keyCodes[i]].char_display;
}
}
// '229' is HanZen or IME enable key
if (keys[229].pushed){
removeChild(keys[229].hit);
keys[229].pushed = false;
}
}
private function make_board(_x:int, _y:int):void {
//make board
brd.x = 20 + _x;
brd.y = 200 + _y;
brd.width = stage.stageWidth - 20*2;
trace(brd.width);
//brd.y = Math.floor(stage.stageHeight / 3 * 2 );
brd.height = 50;
//brd.border = true;
//brd.multiline = true;
//brd.wordWrap = true;
brd.autoSize = TextFieldAutoSize.RIGHT;
//brd.antiAliasType = flash.text.AntiAliasType.NORMAL;
var tfm:TextFormat = new TextFormat();
tfm.font = 'Verdana';
tfm.size = 84;
tfm.color=0xeeeeee;
brd.defaultTextFormat = tfm;
var flt:DropShadowFilter = new DropShadowFilter(8,45,0.2, 12,12, 20);
brd.filters = [flt];
addChild(brd);
}
private function put_char_on_board(_char:String):void {
var tfm_new:TextFormat = new TextFormat();
tfm_new.color = 0xff3333;
if (_char === 'NULL') { return; }
else if (_char === 'Space') { _char = ' '; }
var str:String = brd.text + _char;
if (str.length > MAX_BOARD_LENGTH) {
brd.text = str.substr(str.length - MAX_BOARD_LENGTH);
}else{
brd.text = str;
}
brd.setTextFormat(tfm_new, brd.text.length-1);
}
private function add_text_on_key(_tfd:TextField, _char:String, _x:int,_y:int):void {
var tfm:TextFormat = new TextFormat();
tfm.font = "Verdana";
if (_char.length > 1){
tfm.size = 12;
_tfd.x = _x+STAGE_PADDING;
_tfd.y = _y+STAGE_PADDING;
}else{
tfm.size = 18;
_tfd.x = _x+STAGE_PADDING + KEY_PADDING;
_tfd.y = _y+STAGE_PADDING - KEY_PADDING;
}
tfm.color = KEY_CHAR_COLOR;
//_tfd.antiAliasType = flash.text.AntiAliasType.ADVANCED;
_tfd.autoSize = TextFieldAutoSize.LEFT;
_tfd.defaultTextFormat = tfm;
if (_char != 'Space'){
_tfd.text = _char;
}
}
private function make_japanese_keyboard_obj(_x:int, _y:int):void {
var i:int;
var tfd:TextField;
var key_str:String = '';
var key_ary:Array = [];
//http://livedocs.adobe.com/flex/3_jp/langref/flash/events/KeyboardEvent.html
key_str = '27 ';
key_str += '229 49 50 51 52 53 54 55 56 57 48 189 222 220 8 ';
key_str += '9 81 87 69 82 84 89 85 73 79 80 192 219 13 ';
key_str += '20 65 83 68 70 71 72 74 75 76 187 186 221 ';
key_str += '16 90 88 67 86 66 78 77 188 190 191 226 ' + KEYCODE_SHIFT_RIGHT + ' ';
key_str += '17 29 32 28';
keyCodes = key_str.split(' ');
key_str = 'Esc ';
key_str += 'HanZen Num1 Num2 Num3 Num4 Num5 Num6 Num7 Num8 Num9 Num0 Minus Accent Yen BackSpace ';
key_str += 'Tab Q W E R T Y U I O P AtMark LeftBracket Enter ';
key_str += 'Eisuu A S D F G H J K L SemiColon Colon RightBracket ';
key_str += 'Shift Z X C V B N M Comma Period Slash Backslash RightShift ';
key_str += 'Ctrl NoConvert Space Convert';
var charNameJP:Array = key_str.split(' ');
key_str = 'Esc ';
key_str += '半全 1 2 3 4 5 6 7 8 9 0 - ^ ¥ BS ';
key_str += 'Tab q w e r t y u i o p @ [ Enter ';
key_str += '英数 a s d f g h j k l ; : ] ';
key_str += 'Shift z x c v b n m , . / \\ Shift ';
key_str += 'Ctrl 無変換 変換'; //全角空白使ってます
var dispCharJP:Array = key_str.split(' ');
key_str = 'Esc ';
key_str += '半全 ! " # $ % & \' ( ) = ~ | BS '; //全角空白使ってます
key_str += 'Tab Q W E R T Y U I O P ` { Enter ';
key_str += '英数 A S D F G H J K L + * } ';
key_str += 'Shift Z X C V B N M < > ? _ Shift ';
key_str += 'Ctrl 無変換 変換'; //全角空白使ってます
var dispCharJP_shift:Array = key_str.split(' ');
key_str = 'NULL ';
key_str += 'NULL 1 2 3 4 5 6 7 8 9 0 - ^ ¥ NULL ';
key_str += 'Space q w e r t y u i o p @ [ NULL ';
key_str += 'NULL a s d f g h j k l ; : ] ';
key_str += 'NULL z x c v b n m , . / \\ NULL ';
key_str += 'NULL NULL Space NULL';
var inputCharJP:Array = key_str.split(' ');
key_str = 'NULL ';
key_str += 'NULL ! " # $ % & \' ( ) NULL = ~ | NULL ';
key_str += 'Space Q W E R T Y U I O P ` { NULL ';
key_str += 'NULL A S D F G H J K L + * } ';
key_str += 'NULL Z X C V B N M < > ? _ NULL ';
key_str += 'NULL NULL Space NULL';
var inputCharJP_shift:Array = key_str.split(' ');
var w:uint = KEY_AREA;
key_ary = [];
//ESC
var y:int = 0;
var x:int = 0;
key_ary.push([x,y,w]);
//数字の段 (半角全角とBackSpace含む)(含めていいのは幅が同じだから)
// キーボード横幅は 数字段で、15個。
// (画面横幅pixel)465÷15=31 余白を考えて1key 30pxで使う
y = w*1;
x = 0;
key_ary.push(
[x,y,w],[x+w,y,w],[x+w*2,y,w],[x+w*3,y,w],[x+w*4,y,w],
[x+w*5,y,w],[x+w*6,y,w],[x+w*7,y,w],[x+w*8,y,w],[x+w*9,y,w],
[x+w*10,y,w],[x+w*11,y,w],[x+w*12,y,w],[x+w*13,y,w],[x+w*14,y,w]
);
//TAB
y = w*2;
x = 0;
key_ary.push([x,y,w+w/2]);
//QWERTYの段
x = w+w/2;
key_ary.push(
[x,y,w],[x+w,y,w],[x+w*2,y,w],[x+w*3,y,w],[x+w*4,y,w],
[x+w*5,y,w],[x+w*6,y,w],[x+w*7,y,w],[x+w*8,y,w],[x+w*9,y,w],
[x+w*10,y,w],[x+w*11,y,w]
);
//Enter (日本語キーボードの場合ここに来る)(英語キーボードならもう一つ下なんだけど)
x = x+w*12;
key_ary.push([x,y,'ENTER']);
//Eisuu
y = w*3;
x = 0;
key_ary.push([x,y,w+w/2+Math.floor(w/4)]);
//ASDFの段
x = w+w/2+Math.floor(w/4);
key_ary.push(
[x,y,w],[x+w,y,w],[x+w*2,y,w],[x+w*3,y,w],[x+w*4,y,w],
[x+w*5,y,w],[x+w*6,y,w],[x+w*7,y,w],[x+w*8,y,w],[x+w*9,y,w],
[x+w*10,y,w],[x+w*11,y,w]
);
//Shift
y = w*4;
x = 0;
key_ary.push([x,y, w+w/2+Math.floor(w/4)+w/2]);
//ZXCVの段
x = w+w/2+Math.floor(w/4)+w/2;
key_ary.push(
[x,y,w],[x+w,y,w],[x+w*2,y,w],[x+w*3,y,w],[x+w*4,y,w],
[x+w*5,y,w],[x+w*6,y,w],[x+w*7,y,w],[x+w*8,y,w],[x+w*9,y,w],
[x+w*10,y,w]
);
//RightShift
var x_shift_rightside:int = x+w*11;
x = x+w*11;
key_ary.push([x,y, w*15 - x_shift_rightside]);
//Ctrl
y = w*5;
x = 0;
key_ary.push([x,y,w+w/2]); //Tabと同じ幅
//NoConvert
x = w+w/2+Math.floor(w/4)+w/2 + w + w - Math.floor(w/4);
key_ary.push([x,y,w+w/2]); //Tabと同じ幅
//Space
x = w+w/2+Math.floor(w/4)+w/2 + w + w - Math.floor(w/4) + w+w/2;
key_ary.push([x,y,w+w+w/2]); //2.5キーぶんの幅
//Convert
x = w+w/2+Math.floor(w/4)+w/2 + w + w - Math.floor(w/4) + w+w/2 + w+w+w/2;
key_ary.push([x,y,w+w/2]); //Tabと同じ幅
for (i=0; i<keyCodes.length; i++) {
x = key_ary[i][0] + _x;
y = key_ary[i][1] + _y;
tfd = new TextField();
var spr_key:Sprite = new Sprite();
var spr_hit:Sprite = new Sprite();
if (key_ary[i][2]==='ENTER') {
make_enterkey_image(spr_key, x,y, KEY_COLOR,KEY_TRANCEPARENCY);
addChild(spr_key);
add_text_on_key(tfd, dispCharJP[i], x,y);
addChild(tfd);
make_enterkey_image(spr_hit, x,y, KEY_HIT_COLOR,KEY_HIT_TRANCEPARENCY);
}else{
make_key_image(spr_key, x,y, key_ary[i][2], KEY_COLOR,KEY_TRANCEPARENCY);
addChild(spr_key);
add_text_on_key(tfd, dispCharJP[i], x,y);
addChild(tfd);
make_key_image(spr_hit, x,y, key_ary[i][2], KEY_HIT_COLOR,KEY_HIT_TRANCEPARENCY);
}
keys[keyCodes[i]] = [];
keys[keyCodes[i]].x = x;
keys[keyCodes[i]].y = y;
keys[keyCodes[i]].key = spr_key;
keys[keyCodes[i]].hit = spr_hit;
keys[keyCodes[i]].textfield = tfd;
keys[keyCodes[i]].name = charNameJP[i];
keys[keyCodes[i]].char_display = dispCharJP[i];
keys[keyCodes[i]].char_display_shift = dispCharJP_shift[i];
keys[keyCodes[i]].char_input = inputCharJP[i];
keys[keyCodes[i]].char_input_shift = inputCharJP_shift[i];
keys[keyCodes[i]].pushed = false;
}
for (i=0; i<=255; i++) {
if (keys[i] === undefined){
keys[i] = null;
}
}
}
private function make_key_image(_obj:Sprite, _x:int,_y:int, _w:int, _col:int,_tp:Number):void {
//http://livedocs.adobe.com/flex/3_jp/langref/flash/display/Graphics.html
_obj.graphics.lineStyle(1,KEY_COLOR_OUTLINE);
_obj.graphics.beginFill(_col,_tp);
_obj.graphics.drawRect(_x+STAGE_PADDING,_y+STAGE_PADDING,
_w-KEY_PADDING*2,KEY_AREA-KEY_PADDING*2);
_obj.graphics.endFill();
}
private function make_enterkey_image(_obj:Sprite, _x:int,_y:int, _col:int,_tp:Number):void {
_obj.graphics.lineStyle(0,KEY_COLOR_OUTLINE);
_obj.graphics.beginFill(_col,_tp);
_obj.graphics.moveTo(_x+STAGE_PADDING,_y+STAGE_PADDING);
//→
_obj.graphics.lineTo(_x+STAGE_PADDING + KEY_AREA*15 - (_x+STAGE_PADDING)-KEY_PADDING*2 + 3,
_y+STAGE_PADDING);
//↓
_obj.graphics.lineTo(_x+STAGE_PADDING + KEY_AREA*15 - (_x+STAGE_PADDING)-KEY_PADDING*2 + 3,
_y+STAGE_PADDING + KEY_AREA-KEY_PADDING*2 + KEY_AREA-KEY_PADDING*2 + (KEY_PADDING*2));
//←
_obj.graphics.lineTo(_x+STAGE_PADDING+Math.floor(KEY_AREA/4),
_y+STAGE_PADDING + KEY_AREA-KEY_PADDING*2 + KEY_AREA-KEY_PADDING*2 + (KEY_PADDING*2));
//↑
_obj.graphics.lineTo(_x+STAGE_PADDING+Math.floor(KEY_AREA/4),
_y+STAGE_PADDING + KEY_AREA-KEY_PADDING*2);
//←
_obj.graphics.lineTo(_x+STAGE_PADDING,
_y+STAGE_PADDING + KEY_AREA-KEY_PADDING*2);
//↑
_obj.graphics.lineTo(_x+STAGE_PADDING,_y+STAGE_PADDING);
_obj.graphics.endFill();
}
}//class