package gpsalarmclock.util;
/*
* VKey.java
*
* @author Shawn Fitzgerald
* @version 1.0
* License: LGPL (see notice below)
*/
/*
© 2006, Shawn Fitzgerald
info@OnShoreSystems.com
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
import java.awt.Button;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.FontMetrics;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Point;
import java.awt.TextComponent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
/**
* VKey - is a virtual keyboard for the BugLab display
* this component provide a QWERTY keyboard that can inject
* characters into a TextComponent type object, or any component
* that supports taking text using a setText(String _text) method
* and maintains the cursor position using the setCaretPosition(int _pos)
* method.
* The Keyboard can be closed by clicking on the close button
* at the upper left corner of the keyboard, or by setting the focused
* item to null using the method setFocusedItem(null);
* The keyboard can be positioned on the screen by dragging it
* using a stylus to select and drag to the desired location.
* Once the stylus is lifted the keyboard will be displayed in
* the new location.
*
*/
public class VKey extends Dialog implements FocusListener, MouseListener, ActionListener
{
private static final String TITLE = "VKeyboard";
private Component focusedItem;
private Frame myFrame;
private Button done = new Button("close");
private boolean shifted = false;
private String[] special = {"Shft","Del ","Tab","Rtn"," Space ", "<-","->"};
private char[][] unshiftRow =
{ {'`','1','2','3','4','5','6','7','8','9','0','-','='},
{'\002','q','w','e','r','t','y','u','i','o','p','[',']','\\',},
{'\000','a','s','d','f','g','h','j','k','l',';','\'','\003'},
{'\001','z','x','c','v','b','n','m',',','.','/',},
{'\004','\005','\006'}
};
private char[][] shiftRow =
{ {'~','!','@','#','$','%','^','&','*','(',')','_','+'},
{'\002','Q','W','E','R','T','Y','U','I','O','P','{','}','|'},
{'\000','A','S','D','F','G','H','J','K','L',':','"','\003'},
{'\001','Z','X','C','V','B','N','M','<','>','?',},
{'\004','\005','\006'}
};
private Object[][] keyCoord =
{
new Object[unshiftRow[0].length],
new Object[unshiftRow[1].length],
new Object[unshiftRow[2].length],
new Object[unshiftRow[3].length],
new Object[unshiftRow[4].length],
};
private int charWidth;
private int charHeight;
private int boxHeight;
private Insets ins;
private int specialWidth;
private int maxWidth =0;
private FontMetrics fm ;
private void setupUI()
{
ins = getInsets();
charWidth = fm.charWidth('W');
charHeight = fm.getHeight();
boxHeight = fm.getHeight()+6;
specialWidth = charWidth+4;
specialWidth *= 3;
specialWidth -= 8;
int row =0;
keyCoord[row][0] = new int[]{specialWidth+5,boxHeight*(row+1)+ins.top};
for(row=1; row < 4; row++)
keyCoord[row][0] = new int[]{5,boxHeight*(row+1)+ins.top};
int[] lastCoord = null;
for(int i=1; i<14; i++)
{
for(row=0; row < 4; row++)
{
if(i < unshiftRow[row].length)
{
int cw = charWidth+4;
if(unshiftRow[row][i-1]<10)
cw = specialWidth;
lastCoord = (int[]) keyCoord[row][i-1];
keyCoord[row][i] = (Object) new int[]{lastCoord[0]+cw,lastCoord[1]};
int tmpMax = lastCoord[0]+cw+specialWidth;
if(tmpMax > maxWidth)
maxWidth = tmpMax;
}
}
}
// setup last row info.
int one4th = getWidth()/4;
keyCoord[4][0] = (Object) new int[]{one4th,boxHeight*5+ins.top};
keyCoord[4][1] = (Object) new int[]{one4th*2,boxHeight*5+ins.top};
keyCoord[4][2] = (Object) new int[]{((int[])keyCoord[4][1])[0]+specialWidth,boxHeight*5+ins.top};
setSize(maxWidth,boxHeight*6+ins.top);
Button b = new Button("X");
add(b);
b.setBounds(5,0,charWidth*2,boxHeight);
b.addActionListener(this);
}
public void paint(Graphics _gfx)
{
if(fm == null)
{
fm = _gfx.getFontMetrics();
setupUI();
}
char[][] keyChars = (shifted?shiftRow:unshiftRow);
for(int i=0; i<14; i++)
{
for(int row=0; row < 4; row++)
{
if(i < keyCoord[row].length)
{
int[] coords = (int[]) keyCoord[row][i];
if(keyChars[row][i]<10 )
{
_gfx.drawString(special[(int)keyChars[row][i]], coords[0]+2, (coords[1]+3)-(boxHeight/2));
_gfx.drawRoundRect(coords[0], coords[1]-boxHeight,specialWidth, boxHeight, 5, 5);
}else
{
_gfx.drawChars(keyChars[row],i,1, coords[0]+2, (coords[1]+3)-(boxHeight/2));
_gfx.drawRoundRect(coords[0],coords[1]-boxHeight,charWidth+2, boxHeight, 5, 5 );
}
}
}
}
int[] coords = (int[]) keyCoord[4][0];
int one4th = getWidth()/4;
_gfx.drawString(special[(int)keyChars[4][0]], coords[0]+2, (coords[1]+3)-(boxHeight/2));
_gfx.drawRoundRect(coords[0], coords[1]-boxHeight,one4th, boxHeight, 5, 5);
coords = (int[]) keyCoord[4][1];
_gfx.drawString(special[(int)keyChars[4][1]], coords[0]+2, (coords[1]+3)-(boxHeight/2));
_gfx.drawRoundRect(coords[0], coords[1]-boxHeight,specialWidth, boxHeight, 5, 5);
coords = (int[]) keyCoord[4][2];
_gfx.drawString(special[(int)keyChars[4][2]], coords[0]+2, (coords[1]+3)-(boxHeight/2));
_gfx.drawRoundRect(coords[0], coords[1]-boxHeight,specialWidth, boxHeight, 5, 5);
}
public void setFocusedItem(Component _comp)
{
focusedItem = _comp;
if( focusedItem == null)
hide();
}
//********** FocusListener methods ***************/
public void focusGained(FocusEvent _evt)
{
if(_evt.getComponent() == this)
return;
focusedItem = _evt.getComponent();
if(!isVisible())
show();
else
{
hide();
show();
}
// }
}
public void focusLost(FocusEvent _evt)
{
}
//********** Constructors ***************/
public VKey(Frame _frame)
{
this(_frame,TITLE, false);
}
public VKey(Frame _frame, boolean _model)
{
this(_frame,TITLE, _model);
}
public VKey(Frame _frame, String _title) {
this(_frame,_title, false);
}
public VKey(Frame _frame, String _title, boolean _model) {
super(_frame, _title, _model);
myFrame = _frame;
setSize(myFrame.getWidth(),(int)(myFrame.getHeight()*.6));
addMouseListener(this);
setLayout(null);
setUndecorated(true);
//addFocusListener(this);
// setupUI();
}
public void mouseClicked(MouseEvent _evt)
{
char[][] keyChars = (shifted?shiftRow:unshiftRow);
Point pt = _evt.getPoint();
int row = (pt.y)/boxHeight;
int col = ((pt.x-5)-(charWidth*2))/(charWidth+4);
if( col < 0 )
col = 0;
if( row < 0 )
row = 0;
if( !(row < shiftRow.length-1) )
{
row = shiftRow.length-1;
if( pt.x >= ((int[])keyCoord[4][0])[0] && pt.x < (((int[])keyCoord[4][0])[0]+(getWidth()/4) ))
col = 0;
else if( pt.x >= ((int[])keyCoord[4][1])[0] && pt.x < ((int[])keyCoord[4][1])[0]+specialWidth)
col = 1;
else if( pt.x >= ((int[])keyCoord[4][2])[0] && pt.x < ((int[])keyCoord[4][2])[0]+specialWidth)
col = 2;
}else
{
if( col >= shiftRow[row].length)
col = shiftRow[row].length-1;
if(row == 0 && col > 0)
col--;
}
char val = keyChars[row][col];
if( val == 0)
{
shifted = !shifted;
repaint();
return;
}
if( focusedItem != null)
{
TextComponent comp = (TextComponent)focusedItem;
StringBuffer buf = new StringBuffer(comp.getText());
int carPos = comp.getCaretPosition();
switch(val)
{
case 0:
return;
case 1: // del
if(carPos > 0)
buf.deleteCharAt(--carPos);
break;
case 2: // tab
buf.insert(carPos,'\t');
carPos++;
break;
case 3: // enter
buf.insert(carPos,'\n');
carPos++;
break;
case 4: // space
buf.insert(carPos,' ');
carPos++;
break;
case 5: // <- left
carPos--;
break;
case 6: // -> right
carPos++;
break;
default:
buf.insert(carPos,val);
carPos++;
}
comp.setText(buf.toString());
if( carPos < 0)
carPos = 0;
comp.setCaretPosition(carPos);
}
}
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
private int stX = 0;
private int stY = 0;
public void mousePressed(MouseEvent _evt)
{
stX = _evt.getX();
stY = _evt.getY();
}
public void mouseReleased(MouseEvent _evt)
{
if(stX == 0 && stY == 0)
return;
int endX = _evt.getX();
int endY = _evt.getY();
Point where = getLocation();
where.x += (endX-stX);
where.y += (endY-stY);
setLocation(where);
stX = 0;
stY = 0;
}
public void actionPerformed(ActionEvent _evt)
{
hide();
}
}