19 |
20 | JDasher is a port derived from the Dasher project; for information on
21 | the project see www.dasher.org.uk; for information on JDasher itself
22 | and related projects see www.smowton.net/chris
23 |
24 | */
25 |
26 | package dasher;
27 |
28 | import static dasher.CDasherModel.CROSS_X;
29 | import dasher.CDasherView.MutablePoint;
30 |
31 | /**
32 | * This is an InputFilter implementation which accepts mouse clicks
33 | * and causes Dasher to zoom to the location of successive clicks.
34 | *
35 | * The filter does not pay any attention to the mouse position
36 | * except for when the user clicks the display, and does not
37 | * decorate the display in any way.
38 | *
39 | * In order to zoom smoothly to a given location, it invokes
40 | * CDasherModel.ScheduleZoom, which interpolates a number of points
41 | * between the current crosshair location and the point clicked by
42 | * the user, and jumps to these points on each successive frame.
43 | *
44 | * This filter registers itself with the name Click Mode.
45 | */
46 |
47 | public class CClickFilter extends CStaticFilter {
48 |
49 | private long minX;
50 | /**
51 | * Sole constructor. Calls the CInputFilter constructor with a type of 7,
52 | * an ID of 1, and the name Click Mode.
53 | *
54 | * @param EventHandler Event handler.
55 | * @param SettingsStore Settings repository.
56 | * @param Interface Interface with which the filter should be registered.
57 | */
58 | public CClickFilter(CDasherComponent creator, CDasherInterfaceBase iface) {
59 | super(creator, iface, "Click Mode");
60 | HandleEvent(Elp_parameters.LP_MAX_ZOOM);
61 | }
62 |
63 | /**
64 | * KeyDown is to be called by the Interface when the user
65 | * presses a key or clicks the mouse. ClickFilter responds to:
66 | *
67 | * Left mouse button: Schedules a zoom to the clicked location.
68 | *
69 | * @param iTime Current system time as a UNIX timestamp.
70 | * @param iId Key/button identifier.
71 | * @param Model DasherModel which should be zoomed in response to clicks.
72 | */
73 | @Override public void KeyDown(long iTime, int iId, CDasherView pView, CDasherInput pInput, CDasherModel Model) {
74 |
75 | switch(iId) {
76 | case 100: // Mouse clicks
77 | pInput.GetDasherCoords(pView,inputCoords);
78 | scheduleZoom(Model, Math.max(minX, (inputCoords.x*(1024+GetLongParameter(Elp_parameters.LP_S)))/1024),inputCoords.y);
79 | m_Interface.Redraw(false);
80 | break;
81 | }
82 | }
83 | private final MutablePoint inputCoords = new MutablePoint();
84 |
85 | @Override public void HandleEvent(EParameters eParam) {
86 | if (eParam==Elp_parameters.LP_MAX_ZOOM)
87 | minX = Math.max(2, CROSS_X/GetLongParameter(Elp_parameters.LP_MAX_ZOOM));
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/dasher/CCompassMode.java:
--------------------------------------------------------------------------------
1 | package dasher;
2 |
3 | import static dasher.CDasherModel.MAX_Y;
4 |
5 | public class CCompassMode extends CDasherButtons {
6 | private int iTargetWidth;
7 | public CCompassMode(CDasherComponent creator, CDasherInterfaceBase iface) {
8 | super(creator, iface, "Compass Mode");
9 | }
10 |
11 | @Override protected SBox[] SetupBoxes() {
12 | final int iDasherY = (int)MAX_Y;
13 |
14 | SBox[] m_pBoxes = new SBox[4];
15 |
16 | iTargetWidth = (int)(iDasherY * 1024 / GetLongParameter(Elp_parameters.LP_RIGHTZOOM));
17 |
18 | // FIXME - need to relate these to cross-hair position as stored in the parameters
19 |
20 | // Not sure whether this is at all the right algorithm here - need to check
21 | int iTop = (2048 - iTargetWidth / 2);
22 | m_pBoxes[1] = new SBox(iTop, 4096 - iTop, 0);
23 |
24 | // Make this the inverse of the right zoom option
25 |
26 | int backTop = -2048 * iTop / (2048 - iTop);
27 | m_pBoxes[3] = new SBox(backTop, 4096 - backTop, 0);
28 |
29 | m_pBoxes[0] = new SBox(-iTargetWidth, iDasherY - iTargetWidth, 0);
30 | m_pBoxes[2] = new SBox(iTargetWidth,iDasherY + iTargetWidth, 0);
31 |
32 | return m_pBoxes;
33 | }
34 |
35 | @Override public boolean DecorateView(CDasherView pView, CDasherInput pInput) {
36 | boolean bFirst=true;
37 | for (int iPos = 2048 - iTargetWidth / 2; iPos >= 0; iPos -= iTargetWidth) {
38 |
39 | pView.Dasherline(-100, iPos, -1000, iPos, 1, bFirst ? 1 : 2);
40 |
41 | pView.Dasherline(-100, 4096 - iPos, -1000, 4096-iPos, 1, bFirst ? 1 : 2);
42 |
43 | bFirst = false;
44 | }
45 | return false; //never changes!
46 | }
47 |
48 | @Override public void HandleEvent(EParameters eParam) {
49 | if (eParam == Elp_parameters.LP_RIGHTZOOM) {
50 | m_pBoxes=SetupBoxes(); m_bDecorationChanged = true;
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/dasher/CConversionHelper.java:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of JDasher.
3 |
4 | JDasher is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | JDasher is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with JDasher; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | Copyright (C) 2006 Christopher Smowton
19 |
20 | JDasher is a port derived from the Dasher project; for information on
21 | the project see www.dasher.org.uk; for information on JDasher itself
22 | and related projects see www.smowton.net/chris
23 |
24 | */
25 |
26 | package dasher;
27 |
28 | import java.util.ArrayList;
29 |
30 | abstract public class CConversionHelper {
31 | abstract boolean Convert(final String strSource, ArrayList> vResult);
32 | }
33 |
--------------------------------------------------------------------------------
/src/dasher/CCustomColours.java:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of JDasher.
3 |
4 | JDasher is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | JDasher is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with JDasher; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | Copyright (C) 2006 Christopher Smowton
19 |
20 | JDasher is a port derived from the Dasher project; for information on
21 | the project see www.dasher.org.uk; for information on JDasher itself
22 | and related projects see www.smowton.net/chris
23 |
24 | */
25 |
26 | package dasher;
27 |
28 | import java.util.ArrayList;
29 |
30 | /**
31 | * Represents a custom colour scheme, wrapping a ColourInfo object
32 | * and importing its contents into Collections suitable for random
33 | * access.
34 | *
35 | * This also ensures that the ColourInfo object is read-only
36 | * when in use.
37 | */
38 | public class CCustomColours {
39 |
40 | /**
41 | * Wrapped colour info object.
42 | */
43 | protected CColourIO.ColourInfo m_ColourInfo;
44 |
45 | /**
46 | * Fast-access array of available colours' red values.
47 | */
48 | protected ArrayList m_Red = new ArrayList();
49 |
50 | /**
51 | * Fast-access array of available colours' green values.
52 | */
53 | protected ArrayList m_Green = new ArrayList();
54 |
55 | /**
56 | * Fast-access array of available colours' blue values.
57 | */
58 | protected ArrayList m_Blue = new ArrayList();
59 |
60 | /**
61 | * Sole constructor; copies the data from a given ColourInfo
62 | * object.
63 | *
64 | * @param ColInfo ColourInfo object detailing the scheme we wish to represent.
65 | */
66 | public CCustomColours(CColourIO.ColourInfo ColInfo) {
67 | m_ColourInfo = ColInfo;
68 |
69 | // Add all the colours.
70 | for(int i = 0; i < m_ColourInfo.Reds.size(); i++) { // loop colours
71 | m_Red.add(m_ColourInfo.Reds.get(i));
72 | m_Green.add(m_ColourInfo.Greens.get(i));
73 | m_Blue.add(m_ColourInfo.Blues.get(i));
74 | }
75 | }
76 |
77 | /**
78 | * Gets number of available colours.
79 | *
80 | * @return Number of available colours.
81 | */
82 | public int GetNumColours() {
83 | return m_Red.size();
84 | }
85 |
86 | /**
87 | * Gets the red value of a given colour.
88 | *
89 | * @param colour Index of the colour to look up.
90 | * @return Red value, on a scale from 0 to 255.
91 | */
92 | public int GetRed(int colour) {
93 | return m_Red.get(colour);
94 | }
95 |
96 | /**
97 | * Gets the green value of a given colour.
98 | *
99 | * @param colour Index of the colour to look up.
100 | * @return green value, on a scale from 0 to 255.
101 | */
102 | public int GetGreen(int colour) {
103 | return m_Green.get(colour);
104 | }
105 |
106 | /**
107 | * Gets the blue value of a given colour.
108 | *
109 | * @param colour Index of the colour to look up.
110 | * @return blue value, on a scale from 0 to 255.
111 | */
112 | public int GetBlue(int colour) {
113 | return m_Blue.get(colour);
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/src/dasher/CDasherButtons.java:
--------------------------------------------------------------------------------
1 | package dasher;
2 |
3 | import dasher.CDasherView.MutablePoint;
4 |
5 | public abstract class CDasherButtons extends CStaticFilter {
6 | protected int m_iActiveBox;
7 | protected SBox m_pBoxes[];
8 | protected boolean m_bDecorationChanged;
9 |
10 | //protected void ChangeBoxes() {m_pBoxes = SetupBoxes(); m_bDecorationChanged=true;}
11 |
12 | public CDasherButtons(CDasherComponent creator, CDasherInterfaceBase iface, String szName) {
13 | super(creator, iface, szName);
14 | m_pBoxes = SetupBoxes();
15 | }
16 |
17 | protected static class SBox {
18 | /**target of zoom*/
19 | final int iX,iY;
20 | /**location of top/bottom on screen*/
21 | final int iDisplayTop, iDisplayBottom;
22 | SBox(int iTop, int iBottom, int iDisplayTop, int iDisplayBottom) {
23 | if (iTop>=iBottom || iDisplayTop>=iDisplayBottom) throw new IllegalArgumentException();
24 | iY = (iTop+iBottom)/2;
25 | iX = (iBottom-iTop)/2;
26 | this.iDisplayTop=iDisplayTop;
27 | this.iDisplayBottom=iDisplayBottom;
28 | }
29 | SBox(int iDisplayTop, int iDisplayBottom, int safety) {
30 | this(iDisplayTop-safety, iDisplayBottom+safety, iDisplayTop, iDisplayBottom);
31 | }
32 | public String toString() {
33 | return "{"+iDisplayTop+" - "+iDisplayBottom+" => " +iX+","+iY+"}";
34 | }
35 | }
36 |
37 | @Override public void Activate() {
38 | if (m_pBoxes==null) m_pBoxes = SetupBoxes();
39 | }
40 |
41 | protected abstract SBox[] SetupBoxes();
42 |
43 | private final MutablePoint mouseCoords = new MutablePoint();
44 | private long m_iLastTime;
45 |
46 | @Override public void KeyDown(long iTime, int iId, CDasherView pView, CDasherInput pInput, CDasherModel pModel) {
47 | if (iId == 100) {
48 | //Mouse!
49 | m_iActiveBox=-1;
50 | pInput.GetDasherCoords(pView, mouseCoords);
51 | for (int i = 0; i < m_pBoxes.length; i++) {
52 | if (isInBox(mouseCoords.x,mouseCoords.y,m_pBoxes[i])) {
53 | m_iActiveBox=i;
54 | break;
55 | }
56 | }
57 | if (m_iActiveBox==-1) return; //not in any box
58 | } else if(iId == 1)
59 | m_iActiveBox = m_pBoxes.length - 1; //last box = zoom out
60 | else if(iId <= m_pBoxes.length)
61 | m_iActiveBox = iId-2;
62 | else
63 | m_iActiveBox = m_pBoxes.length-2;
64 | scheduleZoom(pModel, m_pBoxes[m_iActiveBox].iX, m_pBoxes[m_iActiveBox].iY);
65 | m_iLastTime = iTime;
66 | m_bDecorationChanged = true; //we set m_iActiveBox and m_iLastTime, so it'll be highlighted for awhile
67 | }
68 |
69 | protected boolean isInBox(long iDasherX, long iDasherY, SBox box) {
70 | return iDasherY <= box.iDisplayBottom &&
71 | iDasherY >= box.iDisplayTop &&
72 | iDasherX <= box.iDisplayBottom - box.iDisplayTop;
73 | //(iDasherX < box.iDisplayBottom - box.iDisplayTop || box == m_pBoxes[m_pBoxes.length-1]);
74 | }
75 |
76 | @Override public void Timer(long Time, CDasherView m_pDasherView, CDasherInput pInput, CDasherModel pModel) {
77 | if ((Time - m_iLastTime) > 200) {
78 | //end any highlight
79 | if (m_iActiveBox!=-1) m_bDecorationChanged = true;
80 | m_iActiveBox = -1;
81 | }
82 | }
83 |
84 | @Override public boolean DecorateView(CDasherView pView, CDasherInput pInput) {
85 | for(int i = 0; i < m_pBoxes.length; ++i) {
86 | if(i != m_iActiveBox)
87 | DrawBox(pView, m_pBoxes[i], false);
88 | }
89 | if (m_iActiveBox!=-1) DrawBox(pView, m_pBoxes[m_iActiveBox],true);
90 |
91 | boolean bRV = m_bDecorationChanged;
92 | m_bDecorationChanged = false;
93 | return bRV;
94 | }
95 |
96 | protected void DrawBox(CDasherView pView, SBox box, boolean bActive) {
97 |
98 | final long iMaxX = //(box.iDisplayBottom <= pView.VisibleRegion().minY && box.iDisplayTop <= pView.VisibleRegion().maxY) ? pView.VisibleRegion().maxX :
99 | box.iDisplayBottom - box.iDisplayTop;
100 |
101 | int iColour;
102 | int iWidth;
103 |
104 | if(bActive) {
105 | iColour = 1;
106 | iWidth = 3;
107 | } else {
108 | iColour = 2;
109 | iWidth = 1;
110 | }
111 |
112 | pView.DasherDrawRectangle(iMaxX, box.iDisplayTop, 0, box.iDisplayBottom, -1, iColour, iWidth);
113 | }
114 |
115 | }
--------------------------------------------------------------------------------
/src/dasher/CDasherInput.java:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of JDasher.
3 |
4 | JDasher is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | JDasher is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with JDasher; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | Copyright (C) 2006 Christopher Smowton
19 |
20 | JDasher is a port derived from the Dasher project; for information on
21 | the project see www.dasher.org.uk; for information on JDasher itself
22 | and related projects see www.smowton.net/chris
23 |
24 | */
25 |
26 | package dasher;
27 |
28 | import dasher.CDasherView.MutablePoint;
29 |
30 | /**
31 | * DasherInput is the base class for all modules which provide
32 | * some sort of co-ordinate input.
33 | *
34 | * To serve as a co-ordinate source, a device must be able to
35 | * provide synchronous or quasi-synchronous readout of its
36 | * current co-ordinates, such that a call to GetCoordinates
37 | * will return almost instantaneously.
38 | *
39 | * Devices are free to return their co-ordinates relative
40 | * to the screen, using pixels as their unit of measure, or
41 | * relative to the Dasher world, using Dasher co-ordinates.
42 | *
43 | * @see CDasherModule
44 | */
45 | abstract public class CDasherInput implements CDasherModule {
46 |
47 | private final String m_szName;
48 |
49 | public CDasherInput(String szName) {
50 | this.m_szName = szName;
51 | }
52 |
53 | public String getName() {return m_szName;}
54 |
55 | /**
56 | * Gets the current position of the input in Dasher coordinates.
57 | * Default implementation is to call {@link #GetScreenCoords(CDasherView, MutablePoint)}, and then
58 | * transform the coordinates using {@link CDasherView#Screen2Dasher(MutablePoint)}; subclasses must
59 | * override at least one of this and {@link #GetScreenCoords(CDasherView, MutablePoint)}.
60 | * @param pView View which may be used for coordinate transforms
61 | * @param coords 2-element array into which to write coordinates
62 | * (for 1-dimensional inputs, suggest fixing x=0).
63 | * @return true iff coordinates were available
64 | */
65 | public boolean GetDasherCoords(CDasherView pView, MutablePoint coords) {
66 | if (!GetScreenCoords(pView, coords)) return false;
67 | pView.Screen2Dasher(coords);
68 | return true;
69 | }
70 |
71 | /**
72 | * Gets the current position of the input in screen coordinates.
73 | * Default implementation is to call {@link #GetDasherCoords(CDasherView, MutablePoint)}, and then
74 | * transform the coordinates using {@link CDasherView#Dasher2Screen(MutablePoint)}; subclasses must
75 | * override at least one of this and {@link #GetDasherCoords(CDasherView, MutablePoint)}.
76 | * @param pView View which may be used for coordinate transforms
77 | * @param coords 2-element array into which to write coordinates
78 | * (for 1-dimensional inputs, suggest fixing x=0).
79 | * @return true iff coordinates were available
80 | */
81 | public boolean GetScreenCoords(CDasherView pView, MutablePoint coords) {
82 | if (!GetDasherCoords(pView, coords)) return false;
83 | pView.Dasher2Screen(coords);
84 | return true;
85 | }
86 |
87 | /**
88 | * Activates the input device. If threads must be started
89 | * to support the device, this is the place to do it.
90 | */
91 | public void Activate() {};
92 |
93 | /**
94 | * Deactivates the device; resources should be freed at this point.
95 | *
96 | */
97 | public void Deactivate() {};
98 |
99 | }
100 |
--------------------------------------------------------------------------------
/src/dasher/CDasherModule.java:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of JDasher.
3 |
4 | JDasher is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | JDasher is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with JDasher; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | Copyright (C) 2006 Christopher Smowton
19 |
20 | JDasher is a port derived from the Dasher project; for information on
21 | the project see www.dasher.org.uk; for information on JDasher itself
22 | and related projects see www.smowton.net/chris
23 |
24 | */
25 |
26 | package dasher;
27 |
28 | public interface CDasherModule {
29 |
30 | /*public long GetID() {
31 | return m_iID;
32 | }*/
33 |
34 | /**
35 | * Gets this module's name
36 | *
37 | * @return Name
38 | */
39 | public String getName();
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/dasher/CDasherScreen.java:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of JDasher.
3 |
4 | JDasher is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | JDasher is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with JDasher; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | Copyright (C) 2006 Christopher Smowton
19 |
20 | JDasher is a port derived from the Dasher project; for information on
21 | the project see www.dasher.org.uk; for information on JDasher itself
22 | and related projects see www.smowton.net/chris
23 |
24 | */
25 |
26 | package dasher;
27 |
28 |
29 | /**
30 | * Defines a screen which Dasher can use to draw graphics
31 | * primitives.
32 | */
33 | public interface CDasherScreen {
34 |
35 | /**
36 | * Gets the width, and hence maximum X screen co-ordinate.
37 | *
38 | * @return width
39 | */
40 | public abstract int GetWidth();
41 |
42 | /**
43 | * Gets the height, and hence maximum Y screen co-ordinate.
44 | *
45 | * @return height
46 | */
47 | public abstract int GetHeight();
48 |
49 | /**
50 | * Determines / guesses the size of a given string as drawn on this screen.
51 | *
52 | * This is used in determining how much to displace other drawn
53 | * strings in order to prevent them from overlapping.
54 | *
55 | * This must be carried out by the screen because only the
56 | * actual drawing surface can know how fonts appear when
57 | * rendered.
58 | *
59 | * @param string String whose size we wish to determine
60 | * @param Size Font size in points
61 | * @return Point specifying the width and height of this string.
62 | */
63 | public abstract CDasherView.Point TextSize(String string, int Size);
64 |
65 |
66 | /**
67 | * Draws a string
68 | *
69 | * @param string String to draw
70 | * @param x1 Top-left hand corner x co-ordinate
71 | * @param y1 Top-left hand corner y co-ordinate
72 | * @param Size Font size in points
73 | */
74 | public abstract void DrawString(String string, int x1, int y1, int Size);
75 |
76 | /** Draw a filled rectangle
77 | *
78 | * @param x1 top left of rectangle (x coordinate)
79 | * @param y1 top left corner of rectangle (y coordinate)
80 | * @param x2 bottom right of rectangle (x coordinate)
81 | * @param y2 bottom right of rectangle (y coordinate)
82 | * @param iFillColour fill colour to be used (numeric, -1 => don't fill)
83 | * @param iOutlineColour colour to draw outline (numeric, -1 => don't outline)
84 | * @param ColorScheme Which colourscheme is to be used
85 | * @param iThickness Line thickness for outline (<1 => don't outline)
86 | */
87 | public abstract void DrawRectangle(int x1, int y1, int x2, int y2, int iFillColour, int iOutlineColour,int iThickness);
88 |
89 | /**
90 | * Draw a circle
91 | *
92 | * @param iCX X co-ordinate of the centre
93 | * @param iCY Y co-ordinate of the centre
94 | * @param iR Radius in pixels
95 | * @param iFillColour Colour number to fill (-1 = don't fill)
96 | * @param iLineColour Colour number to outline (-1 = use default)
97 | * @param iLineWidth line width of outline (<=0 = don't outline)
98 | */
99 | public abstract void DrawCircle(int iCX, int iCY, int iR, int iFillColour, int iLineColour, int iLineWidth);
100 |
101 | /**
102 | * Draws a line segment.
103 | * @param x0 Starting x coordinate
104 | * @param y0 Starting y coordinate
105 | * @param x1 End x coordinate
106 | * @param y1 End y coordinate
107 | * @param iWidth Line width
108 | * @param Colour Colour number. Use -1 if you don't want to specify a colour...
109 | */
110 | public abstract void drawLine(int x0, int y0, int x1, int y1, int iWidth, int Colour);
111 |
112 | /**
113 | * Draw a filled polygon - given vertices and color id.
114 | * This is not (currently) used in standard Dasher. However, it could be very
115 | * useful in the future. Please implement unless it will be very difficult,
116 | * in which case make this function call Polyline.
117 | * Draw a filled polygon
118 | *
119 | * @param Points array of points defining the edge of the polygon
120 | * @param Number number of points in the array
121 | * @param fillColour colour of the polygon (numeric)
122 | * @param iOutlineColour colour for border (-1 => no border)
123 | * @param iWidth line width of border (<1 => no border)
124 | */
125 | public abstract void Polygon(CDasherView.Point[] Points, int fillColour, int iOutlineColour, int iWidth);
126 |
127 | /**
128 | * Sets the colour scheme to use
129 | *
130 | * @param ColourScheme New colour scheme
131 | */
132 | public abstract void SetColourScheme(CCustomColours ColourScheme);
133 |
134 | }
135 |
--------------------------------------------------------------------------------
/src/dasher/CDelayedDraw.java:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of JDasher.
3 |
4 | JDasher is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | JDasher is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with JDasher; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | Copyright (C) 2006 Christopher Smowton
19 |
20 | JDasher is a port derived from the Dasher project; for information on
21 | the project see www.dasher.org.uk; for information on JDasher itself
22 | and related projects see www.smowton.net/chris
23 |
24 | */
25 |
26 | package dasher;
27 |
28 | import java.util.ArrayList;
29 |
30 | /**
31 | * Simple class permitting the delayed drawing of Strings when
32 | * drawing the DasherNodes to the screen.
33 | *
34 | * The idea is that we can both
35 | * a) Cause all text to appear above other drawn objects, and
36 | * b) Draw text at the same time as its Node, allowing the
37 | * drawing process to remain modular.
38 | *
39 | * Essentially, all strings which are drawn with this class are
40 | * added to a list, which is emptied and drawn when Draw is called.
41 | */
42 | public class CDelayedDraw {
43 |
44 | /**
45 | * Queues up a piece of text for drawing.
46 | *
47 | * @param str String to draw
48 | * @param x1 x co-ordinate of top-left corner of the string's bounding box
49 | * @param y1 y co-ordinate of top-left corner of the string's bounding box
50 | * @param Size Font size to use
51 | */
52 | public void DelayDrawText(String str, int x1, int y1, int Size) {
53 | CTextString obj;
54 | if (nextFree allTextStrings = new ArrayList();
80 |
81 | /** Next index of an unused object (all up to this index, exclusive, are
82 | * to be drawn; from this index onwards, are free) */
83 | private int nextFree;
84 |
85 | /**
86 | * Class representing a String to be drawn plus information
87 | * needed to draw it
88 | */
89 | private static class CTextString {
90 |
91 | /**
92 | * Default constructor
93 | *
94 | * @param str String to draw
95 | * @param x x co-ordinate of top-left corner of the string's bounding box
96 | * @param y y co-ordinate of top-left corner of the string's bounding box
97 | * @param iSize font size
98 | */
99 | CTextString() {
100 | }
101 | void init(String str, int x, int y, int iSize) {
102 | m_String = str;
103 | m_x = x;
104 | m_y = y;
105 | m_iSize = iSize;
106 |
107 | }
108 | /**
109 | * String to be drawn
110 | */
111 | String m_String;
112 | /**
113 | * x co-ordinate of top-left corner of the string's bounding box
114 | */
115 | int m_x;
116 | /**
117 | * y co-ordinate of top-left corner of the string's bounding box
118 | */
119 | int m_y;
120 | /**
121 | * Font size
122 | */
123 | int m_iSize;
124 | }
125 |
126 | }
127 |
--------------------------------------------------------------------------------
/src/dasher/CDynamicButtons.java:
--------------------------------------------------------------------------------
1 | package dasher;
2 |
3 | import static dasher.CDasherModel.CROSS_Y;
4 |
5 | public abstract class CDynamicButtons extends CDynamicFilter {
6 |
7 | private CDasherModel model;
8 |
9 | /** Meaningless if we are paused */
10 | private boolean reversing;
11 |
12 | public CDynamicButtons(CDasherComponent creator, CDasherInterfaceBase iface, String szName) {
13 | super(creator, iface, szName);
14 | }
15 |
16 | /** When reversing, backs off; when paused, does nothing; when running, delegates to TimerImpl */
17 | @Override
18 | public void Timer(long iTime, CDasherView pView, CDasherInput pInput, CDasherModel pModel) {
19 | if (isPaused()) return;
20 |
21 | if (reversing)
22 | pModel.ScheduleOneStep(41904, CROSS_Y, iTime, getSpeedMul(pModel, iTime));
23 | else
24 | TimerImpl(iTime, pView, pModel);
25 | }
26 |
27 | protected abstract void TimerImpl(long iTime, CDasherView pView, CDasherModel pModel);
28 |
29 | protected void ApplyOffset(CDasherModel model, int off) {
30 | (this.model=model).Offset(off);
31 | }
32 |
33 | @Override public void pause() {
34 | if (model!=null) model.AbortOffset();
35 | super.pause();
36 | }
37 |
38 | protected void reverse(long iTime, CDasherModel pModel) {
39 | if (model!=null) model.AbortOffset();
40 | reversing=true;
41 | super.unpause(iTime);
42 | }
43 | protected final boolean isReversing() {return !isPaused() && reversing;}
44 | protected void run(long iTime, CDasherModel pModel) {
45 | reversing=false;
46 | super.unpause(iTime);
47 | }
48 | protected final boolean isRunning() {return !isPaused() && !reversing;}
49 | @Override protected final void unpause(long iTime) {
50 | throw new AssertionError("Subclasses should not call directly; call run/reverse instead");
51 | }
52 | }
--------------------------------------------------------------------------------
/src/dasher/CDynamicFilter.java:
--------------------------------------------------------------------------------
1 | package dasher;
2 |
3 | public abstract class CDynamicFilter extends CInputFilter {
4 |
5 | private long m_iStartTime;
6 |
7 | public CDynamicFilter(CDasherComponent creator, CDasherInterfaceBase iface,
8 | String szName) {
9 | super(creator, iface, szName);
10 | }
11 |
12 | @Override
13 | public boolean supportsPause() {return true;}
14 |
15 | /** Computes multiplier to apply to speed for this frame.
16 | * The default implementation returns the model's viscosity, unless it's less than
17 | * LP_SLOW_START_TIME
time since we last unpaused, in which case we
18 | * interpolate from 0.1 to 1.0 times that.
19 | * @param Time current time
20 | * @return multiplier to apply to speed; 0.0 = go nowhere, 1.0 = normal speed, higher = faster!
21 | */
22 | protected float getSpeedMul(CDasherModel pModel, long Time) {
23 | float dMul = pModel.getViscosity();
24 | //if (m_iStartTime==-1) m_iStartTime=Time;
25 | if (Time-m_iStartTime < GetLongParameter(Elp_parameters.LP_SLOW_START_TIME)) {
26 | dMul *= 0.1f+0.9f*(Time-m_iStartTime)/GetLongParameter(Elp_parameters.LP_SLOW_START_TIME);
27 | }
28 | return dMul;
29 | }
30 |
31 | @Override public void pause() {m_bPaused=true;}
32 |
33 | protected void unpause(long iTime) {
34 | if (!m_bPaused) return;
35 | m_iStartTime=iTime;
36 | m_bPaused=false;
37 | m_Interface.Redraw(false);
38 | }
39 |
40 | protected final boolean isPaused() {return m_bPaused;}
41 | private boolean m_bPaused=true;
42 | }
--------------------------------------------------------------------------------
/src/dasher/CDynamicPresses.java:
--------------------------------------------------------------------------------
1 | package dasher;
2 |
3 | public abstract class CDynamicPresses extends CDynamicButtons {
4 |
5 | protected static final int SINGLE_PRESS=1, DOUBLE_PRESS=2, LONG_PRESS=0;
6 |
7 | private boolean m_bKeyDown;
8 | private int m_iKeyId;
9 | private long m_iKeyDownTime;
10 |
11 | public CDynamicPresses(CDasherComponent creator, CDasherInterfaceBase iface, String szName) {
12 | super(creator, iface, szName);
13 | }
14 |
15 | @Override
16 | protected void TimerImpl(long iTime, CDasherView pView, CDasherModel pModel) {
17 | if (m_bKeyDown && (iTime-m_iKeyDownTime)>GetLongParameter(Elp_parameters.LP_HOLD_TIME)) {
18 | Event(iTime,m_iKeyId, LONG_PRESS, pModel);
19 | }
20 | }
21 |
22 | @Override
23 | public void KeyDown(long iTime, int iId, CDasherView pView, CDasherInput pInput, CDasherModel pModel) {
24 | if (m_bKeyDown) return; //ignore any key after first
25 | m_bKeyDown = true;
26 | if (m_iKeyId==iId && iTime>m_iKeyDownTime && iTime - m_iKeyDownTime <= GetLongParameter(Elp_parameters.LP_DOUBLE_CLICK_TIME)) {
27 | Event(iTime, iId, DOUBLE_PRESS, pModel);
28 | } else {
29 | m_iKeyDownTime = iTime;
30 | m_iKeyId = iId;
31 | Event(iTime, iId, SINGLE_PRESS, pModel);
32 | }
33 | }
34 |
35 | protected void Event(long iTime, int iId, int pressType, CDasherModel pModel) {
36 | if (isReversing()) {
37 | pause();
38 | } else if (pressType!=SINGLE_PRESS) {
39 | reverse(iTime, pModel);
40 | } else if (isPaused()) {
41 | run(iTime, pModel);
42 | }
43 | }
44 |
45 | @Override
46 | public void KeyUp(long iTime, int iId, CDasherView pView, CDasherInput pInput, CDasherModel pModel) {
47 | if (iId==m_iKeyId) m_bKeyDown=false;
48 | }
49 |
50 | @Override public void pause() {
51 | m_iKeyDownTime = Long.MAX_VALUE;
52 | super.pause();
53 | }
54 |
55 | @Override protected void reverse(long iTime,CDasherModel pModel) {
56 | m_iKeyDownTime = Long.MAX_VALUE;
57 | super.reverse(iTime, pModel);
58 | }
59 |
60 | @Override protected void run(long iTime, CDasherModel pModel) {
61 | m_iKeyDownTime = Long.MAX_VALUE;
62 | super.run(iTime,pModel);
63 | }
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/src/dasher/CFileLogger.java:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of JDasher.
3 |
4 | JDasher is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | JDasher is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with JDasher; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | Copyright (C) 2006 Christopher Smowton
19 |
20 | JDasher is a port derived from the Dasher project; for information on
21 | the project see www.dasher.org.uk; for information on JDasher itself
22 | and related projects see www.smowton.net/chris
23 |
24 | */
25 |
26 | package dasher;
27 |
28 | /**
29 | * Stub at the moment; may potentially be developed into a logfile
30 | * writer in the future!
31 | */
32 | public class CFileLogger {
33 |
34 | /**
35 | * Destroy the logger, which doesn't exist :)
36 | *
37 | */
38 | public void Destroy() {
39 | //stub
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/dasher/CFrameRate.java:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of JDasher.
3 |
4 | JDasher is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | JDasher is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with JDasher; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | Copyright (C) 2006 Christopher Smowton
19 |
20 | JDasher is a port derived from the Dasher project; for information on
21 | the project see www.dasher.org.uk; for information on JDasher itself
22 | and related projects see www.smowton.net/chris
23 |
24 | */
25 |
26 | package dasher;
27 |
28 | import static dasher.Elp_parameters.LP_X_LIMIT_SPEED;
29 | import static dasher.Elp_parameters.LP_MAX_BITRATE;
30 | import static dasher.Elp_parameters.LP_FRAMERATE;
31 |
32 | /**
33 | * Monitors the framerate by taking records every time CountFrame
34 | * is called; this is used to control how far to make Dasher move per frame.
35 | */
36 | public class CFrameRate extends CDasherComponent {
37 | /*private int logCount;
38 | private double logFrames;*/
39 | /**
40 | * (Approximate) number of frames which we should take to move
41 | * to the location under the mouse pointer; based on a decaying
42 | * average of the current framerate.
43 | */
44 | private int m_iSteps; // the 'Steps' parameter. See djw thesis.
45 |
46 | /**
47 | * Number of bits which'd take us all the way to the x limit,
48 | * i.e. the point at which we are entering data at the maximum speed.
49 | */
50 | private double m_dBitsAtLimX;
51 |
52 | /**
53 | * Number of frames elapsed
54 | */
55 | private int m_iFrames=-1;
56 |
57 | /**
58 | * Number of frames to allow to elapse before computing average framerate over that period
59 | */
60 | private int m_iSamples=2;
61 |
62 | /**
63 | * Time of first frame in period being measured
64 | */
65 | private long m_iTime=0;
66 |
67 | /**
68 | * Cache of the natural log of 2
69 | */
70 | private static final double LN2 = Math.log(2.0);
71 |
72 | /** Cache of base-2-logarithm of 5, used in calculating iSteps */
73 | private static final double LOG_MAXY = Math.log(CDasherModel.MAX_Y);
74 |
75 | /**
76 | * Gets m_iSteps; see its description
77 | *
78 | * @return m_iSteps
79 | */
80 | protected int Steps() {
81 | return m_iSteps;
82 | }
83 |
84 | /**
85 | * Creates a new framerate monitor; all initial values
86 | * are currently hard coded in.
87 | *
88 | * We start with a frame rate of 32FPS.
89 | */
90 | public CFrameRate(CDasherComponent creator) {
91 | super(creator);
92 | HandleEvent(LP_X_LIMIT_SPEED);
93 | }
94 |
95 | /**
96 | * Insert a new frame and recompute the frame rate, if enough
97 | * samples have been gathered.
98 | *
99 | * If this would result in a Steps parameter of 0 it is set to 1.
100 | *
101 | * @param Time Time at which the new frame began, as a UNIX timestamp.
102 | */
103 | protected void CountFrame(long Time)
104 | {
105 | if (++m_iFrames == 0) {
106 | //First frame
107 | m_iTime = Time;
108 | }
109 |
110 | // compute framerate if we have sampled enough frames
111 | if(m_iFrames == m_iSamples) {
112 | if(Time - m_iTime < 50)
113 | m_iSamples++; // increase sample size
114 | else if(Time - m_iTime > 80)
115 | m_iSamples = Math.max(2, m_iSamples-1);;
116 |
117 | //Calculate the framerate and reset sampling statistics
118 | // for the next sampling period
119 | if(Time - m_iTime != 0) {
120 | double dFrNow = m_iFrames * 1000.0 / (Time - m_iTime);
121 | SetLongParameter(LP_FRAMERATE, (long)(GetLongParameter(LP_FRAMERATE) + (dFrNow*100))/2);
122 | m_iTime = Time;
123 | m_iFrames = 0;
124 | }
125 |
126 | /*logFrames+=m_dFr;
127 | if (++logCount==20) {
128 | System.out.println("Framerate: "+logFrames/logCount);
129 | logFrames = logCount=0;
130 | }*/
131 | }
132 |
133 | }
134 |
135 | /**
136 | * Clears our frame count. We'll start recounting/timing on the next frame.
137 | */
138 | public void ResetFramecount() {
139 | m_iFrames = -1;
140 | }
141 |
142 | @Override public void HandleEvent(EParameters eParam) {
143 | if (eParam==LP_X_LIMIT_SPEED) {
144 | //log (MAX_Y / (2*LP_X_LIM))
145 | //= log(MAX_Y) - log(2) - log(LP_X)
146 | m_dBitsAtLimX = (LOG_MAXY - LN2 - Math.log(GetLongParameter(LP_X_LIMIT_SPEED)))/LN2;
147 | //fallthrough
148 | } else if (eParam!=LP_MAX_BITRATE && eParam!=LP_FRAMERATE) return;
149 | // => for either LP_MAX_BITRATE or LP_FRAMERATE, fallthrough
150 |
151 | //Calculate m_iSteps from the decaying-average framerate, as the number
152 | // of steps that, at the X limit, will cause LP_MAX_BITRATE bits to be
153 | // entered per second
154 | m_iSteps = Math.max(1,(int)(GetLongParameter(LP_FRAMERATE)*m_dBitsAtLimX/GetLongParameter(LP_MAX_BITRATE)));
155 | }
156 | }
157 |
--------------------------------------------------------------------------------
/src/dasher/CMarkerScreen.java:
--------------------------------------------------------------------------------
1 | package dasher;
2 |
3 | public interface CMarkerScreen extends CDasherScreen {
4 |
5 | /**
6 | * Informs the screen of certain drawing phases.
7 | *
8 | * A '0' will be sent when beginning to draw persistent
9 | * features (ie. those which should remain the same from
10 | * frame to frame), and a '1' will be sent prior to drawing
11 | * ephemeral details which should vanish if not redrawn next
12 | * frame.
13 | *
14 | * @param iMarker Marker number
15 | */
16 | public abstract void SendMarker(int iMarker);
17 |
18 | /**
19 | * Signals the end of a frame.
20 | *
21 | */
22 | public abstract void Display();
23 | }
24 |
--------------------------------------------------------------------------------
/src/dasher/CMenuMode.java:
--------------------------------------------------------------------------------
1 | package dasher;
2 |
3 | import static dasher.CDasherModel.MAX_Y;
4 |
5 | /*static SModuleSettings sSettings[] = {
6 | // TRANSLATORS: The number of time steps over which to perform the zooming motion in button mode.
7 | {LP_ZOOMSTEPS, T_LONG, 1, 63, 1, 1, _("Zoom steps")},
8 | {LP_BUTTON_SCAN_TIME, T_LONG, 0, 2000, 1, 100, _("Scan time in menu mode (0 to not scan)")},
9 | {LP_B, T_LONG, 2, 10, 1, 1, _("Number of boxes")},
10 | {LP_S, T_LONG, 0, 256, 1, 1, _("Safety margin")},
11 | // TRANSLATORS: The boxes (zoom targets) in button mode can either be the same size, or different sizes - this is the extent to which the sizes are allowed to differ from each other.
12 | // XXX PRLW: 128 log(2) = 89, where 2 is the ratio of adjacent boxes
13 | // however the code seems to use ratio = (129/127)^-r, instead of
14 | // ratio = exp(r/128) used in the design document
15 | //
16 | {LP_R, T_LONG, -89, 89, 1, 10, _("Box non-uniformity")},
17 | // TRANSLATORS: Intercept keyboard events for 'special' keys even when the Dasher window doesn't have keyboard focus.
18 | {BP_GLOBAL_KEYBOARD, T_BOOL, -1, -1, -1, -1, _("Global keyboard grab")}
19 | };*/
20 |
21 | public class CMenuMode extends CScanning {
22 | public CMenuMode(CDasherComponent creator, CDasherInterfaceBase iface, String szName) {
23 | super(creator, iface, szName);
24 | }
25 |
26 | protected SBox[] SetupBoxes() {
27 | final int iDasherY = (int)MAX_Y;
28 |
29 | int iForwardBoxes = (int)GetLongParameter(Elp_parameters.LP_B);
30 | SBox[] m_pBoxes = new SBox[iForwardBoxes+1];
31 |
32 | // Calculate the sizes of non-uniform boxes using standard
33 | // geometric progression results
34 |
35 | // FIXME - implement this using DJCM's integer method?
36 | // See ~mackay/dasher/buttons/
37 | final double dRatio = Math.pow(129/127.0, GetLongParameter(Elp_parameters.LP_R));
38 | final int lpS = (int)GetLongParameter(Elp_parameters.LP_S);
39 |
40 | double dMaxSize;
41 | if(dRatio == 1.0)
42 | dMaxSize = iDasherY / (double)iForwardBoxes;
43 | else
44 | dMaxSize = ((dRatio - 1)/(Math.pow(dRatio, iForwardBoxes) - 1)) * iDasherY;
45 |
46 | double dMin = 0.0;
47 |
48 | for(int i = 0; i < iForwardBoxes; ++i) { // One button reserved for backoff
49 | double dMax = dMin + dMaxSize * Math.pow(dRatio, i);
50 |
51 | // m_pBoxes[i].iDisplayTop = (i * iDasherY) / (m_iNumBoxes.length - 1);
52 | // m_pBoxes[i].iDisplayBottom = ((i+1) * iDasherY) / (m_iNumBoxes.length - 1);
53 | m_pBoxes[i] = new SBox((int)dMin, (int)dMax,lpS);
54 | dMin = dMax;
55 | }
56 |
57 | m_pBoxes[m_pBoxes.length-1]=new SBox((iDasherY * (1-iForwardBoxes))/ 2,(iDasherY * (1+iForwardBoxes))/2,0,iDasherY);
58 |
59 | return m_pBoxes;
60 | }
61 |
62 | @Override public void HandleEvent(EParameters eParam) {
63 | if (eParam == Elp_parameters.LP_B || eParam == Elp_parameters.LP_R) {
64 | m_pBoxes = SetupBoxes(); m_bDecorationChanged = true;
65 | }
66 | }
67 |
68 | }
--------------------------------------------------------------------------------
/src/dasher/CModuleManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of JDasher.
3 |
4 | JDasher is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | JDasher is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with JDasher; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | Copyright (C) 2006 Christopher Smowton
19 |
20 | JDasher is a port derived from the Dasher project; for information on
21 | the project see www.dasher.org.uk; for information on JDasher itself
22 | and related projects see www.smowton.net/chris
23 |
24 | */
25 |
26 | package dasher;
27 |
28 | import java.util.Map;
29 | import java.util.HashMap;
30 | import java.util.Collection;
31 |
32 | /**
33 | * Helper class for the InterfaceBase which enumerates the modules
34 | * present in supplied module factories and returns said modules
35 | * by ID or by name on request.
36 | *
37 | * A list of all available modules can also be supplied.
38 | */
39 | public class CModuleManager {
40 | /**
41 | * Map from modules' Strings to the modules themselves
42 | */
43 | protected final Map m_mapModules = new HashMap();
44 |
45 | /**
46 | * Store the module in our internal map so it can be retrieved
47 | * using GetModuleByName
48 | *
49 | * @param mod the new module; must have a unique name
50 | */
51 | public void RegisterModule(CDasherModule mod) {
52 | String s = mod.getName();
53 | if (m_mapModules.containsKey(s))
54 | throw new IllegalArgumentException("Module "+s+" already exists!");
55 | m_mapModules.put(s, mod);
56 | }
57 |
58 | /**
59 | * Gets a module with the given name and supertype (typically {@link CDasherInput} or {@link CInputFilter})
60 | *
61 | * @param iID ID of the required module
62 | * @return Matching Module, or null if none was found.
63 | */
64 | public T GetModuleByName(Class clazz, String strName) {
65 | CDasherModule m = m_mapModules.get(strName);
66 | return (clazz.isInstance(m)) ? clazz.cast(m) : null;
67 | }
68 |
69 | /**
70 | * Retrieves a list of all modules of a given type.
71 | *
72 | * @param clazz Type of modules to enumerate - typically {@link CDasherInput} or {@link CInputFilter}
73 | * @param vList Collection to be filled with the names of available
74 | * modules
75 | */
76 | public void ListModules(Class clazz, Collection super T> vList) {
77 | for(CDasherModule m : m_mapModules.values())
78 | if(clazz.isInstance(m))
79 | vList.add(clazz.cast(m));
80 | }
81 |
82 | }
83 |
--------------------------------------------------------------------------------
/src/dasher/COneDimensionalFilter.java:
--------------------------------------------------------------------------------
1 | package dasher;
2 |
3 | import static dasher.CDasherModel.*;
4 | import dasher.CDasherView.MutablePoint;
5 |
6 | /** Overrides ApplyTransform to apply 1D remapping (using old x coord as radius)
7 | * if and only if {@link Ebp_parameters#BP_ONE_DIMENSIONAL_MODE} is enabled.
8 | * @author Alan Lawrence
9 | */
10 | public class COneDimensionalFilter extends CDefaultFilter {
11 |
12 | public COneDimensionalFilter(CDasherComponent creator, CDasherInterfaceBase iface, String szName) {
13 | super(creator, iface, szName);
14 | }
15 |
16 | /**
17 | * If {@link Ebp_parameters#BP_ONE_DIMENSIONAL_MODE} is set, calls {@link #Apply1DTransform}
18 | * (and then skips superclass method); otherwise, falls back to superclass.
19 | */
20 | @Override public void ApplyTransform(CDasherView pView, MutablePoint coords) {
21 | if (GetBoolParameter(Ebp_parameters.BP_ONE_DIMENSIONAL_MODE))
22 | Apply1DTransform(pView, coords);
23 | else
24 | super.ApplyTransform(pView, coords);
25 | }
26 |
27 | private final int forwardmax=(int)(MAX_Y/2.5); //of 1D transform
28 |
29 | /**
30 | * Applies the 1D remapping: as Y increases from 0 to LP_MAX_Y, starts & ends at the origin,
31 | * then moves in two semicircles round the back, joined by a larger semicircle allowing forwards motion.
32 | * X co-ordinate is used as radius: X=0 => full radius, X=(max visible x) => 0-radius. This is calculated
33 | * using dasher co-ords (inc. logarithmic compression left of crosshair), so the input x has to be quite
34 | * far to the left (=high) to reduce the radius significantly.
35 | * @param pView
36 | * @param coords
37 | */
38 | protected void Apply1DTransform(CDasherView pView, MutablePoint coords) {
39 | // The distance between the Y coordinate and the centreline in pixels
40 | final long disty=CROSS_Y-coords.y;
41 |
42 | final long circlesize = (long)(forwardmax*(1.0-coords.x/(double)pView.VisibleRegion().maxX));
43 | final long yforwardrange = (MAX_Y*5)/16;
44 | final long yfullrange = MAX_Y/2;
45 |
46 | double x,y; //0,0=on crosshair; positive=forwards/up...
47 |
48 | if (disty<=yforwardrange && disty>=-yforwardrange) {
49 | //go forwards!
50 | final double angle=((disty*3.14159/2)/(double)yforwardrange);
51 | x=Math.cos(angle);
52 | y=-Math.sin(angle);
53 | } else if (disty<=yfullrange && disty>=-yfullrange) {
54 | final long ybackrange = yfullrange-yforwardrange;
55 | final long ellipse_eccentricity=6;
56 | //backwards, off bottom or top...
57 | final double yb = (Math.abs(disty)-yforwardrange)/(double)ybackrange;
58 | final double angle=(yb*3.14159)*(yb+(1-yb)*(ybackrange/(double)yforwardrange/ellipse_eccentricity));
59 |
60 | x=-Math.sin(angle)*ellipse_eccentricity/2.0;
61 | y=(1.0+Math.cos(angle))/2.0;
62 | if (disty>yforwardrange) y=-y; //backwards off top
63 | } else {
64 | //off limits, go nowhere
65 | x=0; y=0;
66 | }
67 | coords.x = CROSS_X-(long)(x*circlesize);
68 | coords.y = CROSS_Y+(long)(y*circlesize);
69 | }
70 |
71 | @Override protected void CreateStartHandler() {
72 | if (GetBoolParameter(Ebp_parameters.BP_CIRCLE_START)) {
73 | m_StartHandler= new CCircleStartHandler(this) {
74 | private CDasherView.Point fwdCircle;
75 | @Override protected CDasherView.Point getScreenCenter(CDasherView pView) {
76 | if (filter.isPaused()
77 | && GetBoolParameter(Ebp_parameters.BP_ONE_DIMENSIONAL_MODE)) {
78 | //move circle
79 | if (fwdCircle==null) {
80 | long rad = GetLongParameter(Elp_parameters.LP_CIRCLE_PERCENT)*CROSS_Y/100;
81 | fwdCircle = pView.Dasher2Screen(CROSS_X-forwardmax+rad, CROSS_Y);
82 |
83 | }
84 | return fwdCircle;
85 | }
86 | return super.getScreenCenter(pView);
87 | }
88 | };
89 | } else
90 | super.CreateStartHandler();
91 | }
92 |
93 | }
94 |
--------------------------------------------------------------------------------
/src/dasher/CParameterNotFoundException.java:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of JDasher.
3 |
4 | JDasher is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | JDasher is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with JDasher; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | Copyright (C) 2006 Christopher Smowton
19 |
20 | JDasher is a port derived from the Dasher project; for information on
21 | the project see www.dasher.org.uk; for information on JDasher itself
22 | and related projects see www.smowton.net/chris
23 |
24 | */
25 |
26 | package dasher;
27 |
28 | /**
29 | * Exception to be thrown by a CSettingsStore object when it attempts
30 | * to load a setting but is unable to find a record of it in its
31 | * backing store.
32 | *
33 | * This exception is caught within CSettingsStore, and is never
34 | * seen by external classes.
35 | *
36 | * Typically the SettingsStore responds to this problem by loading
37 | * a default setting.
38 | *
39 | * The base implementation of CSettingsStore throws this for all
40 | * calls to LoadSetting, as it does not know about a backing store.
41 | */
42 | public class CParameterNotFoundException extends Exception {
43 | /**
44 | * Name of the parameter which couldn't be loaded.
45 | */
46 | public String paramName;
47 |
48 | /**
49 | * Creates a new ParameterNotFoundException.
50 | *
51 | * @param p Parameter which couldn't be loaded
52 | */
53 | public CParameterNotFoundException(String p) {
54 | this.paramName = p;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/dasher/CScanning.java:
--------------------------------------------------------------------------------
1 | package dasher;
2 |
3 | import dasher.CDasherView.MutablePoint;
4 | import dasher.Opts.ScreenOrientations;
5 |
6 | public abstract class CScanning extends CDasherButtons {
7 | private long m_iScanTime;
8 |
9 | public CScanning(CDasherComponent creator, CDasherInterfaceBase iface, String szName) {
10 | super(creator, iface, szName);
11 | }
12 |
13 | @Override public void Activate() {
14 | super.Activate();
15 | m_iScanTime = Integer.MIN_VALUE;
16 | }
17 |
18 | @Override public void KeyDown(long iTime, int iId, CDasherView pView, CDasherInput pInput, CDasherModel pModel) {
19 | if (iId==100) {
20 | pInput.GetScreenCoords(pView, coords);
21 | iId = (coords.y0) {
50 | m_bDecorationChanged = true; //pretend - so the screen repaints!!
51 | if (Time > m_iScanTime) {
52 | m_iScanTime = Time + GetLongParameter(Elp_parameters.LP_BUTTON_SCAN_TIME);
53 |
54 | if(++m_iActiveBox == m_pBoxes.length)
55 | m_iActiveBox = 0;
56 | }
57 | }
58 | }
59 |
60 | }
--------------------------------------------------------------------------------
/src/dasher/CStylusFilter.java:
--------------------------------------------------------------------------------
1 | package dasher;
2 |
3 | import static dasher.CDasherModel.CROSS_X;
4 | import dasher.CDasherView.MutablePoint;
5 |
6 | /**
7 | *
8 | * @author acl33
9 | */
10 | public class CStylusFilter extends CDefaultFilter {
11 | private long m_iKeyDownTime;
12 | private long minX;
13 | private CDasherModel model; //model with which any zoom was scheduled
14 |
15 | public CStylusFilter(CDasherComponent creator, CDasherInterfaceBase iface) {
16 | this(creator, iface, "Stylus Control");
17 | }
18 |
19 | protected CStylusFilter(CDasherComponent creator, CDasherInterfaceBase iface, String sName) {
20 | super(creator, iface, sName);
21 | HandleEvent(Elp_parameters.LP_MAX_ZOOM);
22 | }
23 |
24 | @Override
25 | public void KeyDown(long iTime, int keyId, CDasherView pView, CDasherInput pInput, CDasherModel model) {
26 | if (keyId == 100) {
27 | model.clearScheduledSteps();
28 | unpause(iTime);
29 | m_iKeyDownTime = iTime;
30 | }
31 | }
32 |
33 | @Override
34 | public void KeyUp(long iTime, int keyId, CDasherView pView, CDasherInput pInput, CDasherModel model) {
35 | if(keyId == 100) {
36 | pause(); //stops continuous motion...
37 | if ((iTime - m_iKeyDownTime < GetLongParameter(Elp_parameters.LP_TAP_TIME))) {
38 | pInput.GetDasherCoords(pView, lastInputCoords);
39 | ApplyClickTransform(pView, lastInputCoords);
40 | (this.model=model).ScheduleZoom(Math.max(minX,lastInputCoords.x),lastInputCoords.y);
41 | m_Interface.Redraw(false);
42 | //...as we've scheduled quite a few frames, instead
43 | }
44 | }
45 | }
46 |
47 | @Override
48 | public void Timer(long iTime, CDasherView view, CDasherInput pInput, CDasherModel model) {
49 | if (model.ScheduledSteps()==0) //zoom cleared by KeyDown
50 | super.Timer(iTime, view, pInput, model);
51 | //else, continue zoom previously scheduled - must have been in middle
52 | // (and no click since)
53 |
54 | //note that this skips the rest of CDefaultFilter::Timer;
55 | //however, given we're paused, this is only the Start Handler,
56 | //which we're not using anyway.
57 | }
58 |
59 | /** Whilst we do kinda support pause, if you can start the filter, you can also
60 | * stop it (Users who cannot remove finger from screen/mouse-pointer, can use
61 | * {@link CDefaultFilter} with a Start Handler).
62 | * @return false
63 | */
64 | @Override public boolean supportsPause() {return false;}
65 |
66 | @Override public void pause() {
67 | if (model!=null) model.clearScheduledSteps();
68 | super.pause();
69 | }
70 |
71 | /**
72 | * Called to apply any coordinate transform required for
73 | * click coords (i.e. for a scheduled zoom, rather
74 | * than continuous movement towards.)
75 | * The default is to multiply the x coordinate to incorporate the {@link Elp_parameters#LP_S}
76 | * safety margin, but not to call {@link #ApplyTransform(CDasherView, long[])};
77 | * subclasses may override to provide different behaviour.
78 | * @param dasherCoords x&y dasher coordinates which will be target of zoom.
79 | */
80 | protected void ApplyClickTransform(CDasherView pView, MutablePoint dasherCoords) {
81 | dasherCoords.x = (dasherCoords.x*(1024+GetLongParameter(Elp_parameters.LP_S))/1024);
82 | }
83 |
84 | @Override public void HandleEvent(EParameters eParam) {
85 | if (eParam==Elp_parameters.LP_MAX_ZOOM)
86 | minX = Math.max(2, CROSS_X/GetLongParameter(Elp_parameters.LP_MAX_ZOOM));
87 | super.HandleEvent(eParam);
88 | }
89 |
90 | /** Make sure no start handler is created - even tho we ignore changes
91 | * to BP_CIRCLE_START and BP_MOUSEPOS_MODE, this still gets called by
92 | * the superclass constructor (if a preference enabling a start handler
93 | * was saved by a previous session)
94 | */
95 | @Override public void CreateStartHandler() {
96 |
97 | }
98 | }
--------------------------------------------------------------------------------
/src/dasher/CUserLog.java:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of JDasher.
3 |
4 | JDasher is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | JDasher is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with JDasher; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | Copyright (C) 2006 Christopher Smowton
19 |
20 | JDasher is a port derived from the Dasher project; for information on
21 | the project see www.dasher.org.uk; for information on JDasher itself
22 | and related projects see www.smowton.net/chris
23 |
24 | */
25 |
26 | package dasher;
27 |
28 | import java.util.ArrayList;
29 |
30 | /**
31 | * Stubbed logging class. These methods should be implemented
32 | * if we want to start generating a textual log.
33 | */
34 | public class CUserLog {
35 |
36 | public CUserLog(CDasherComponent creator, int loglevel) {
37 | //stub
38 | }
39 |
40 | public void OutputFile() {
41 | // stub
42 | }
43 |
44 | public void Close() {
45 | // stub
46 | }
47 |
48 | public void InitIsDone() {
49 | // stub
50 | }
51 |
52 | public void StopWriting(float x) {
53 | // stub
54 | }
55 |
56 | public void StartWriting() {
57 | // stub
58 | }
59 | }
--------------------------------------------------------------------------------
/src/dasher/Document.java:
--------------------------------------------------------------------------------
1 | package dasher;
2 |
3 | /**
4 | * Representation of text in terms of java characters, i.e. unicode values 0-65535.
5 | * Unicode characters above this (i.e. 32-bits) are represented as TWO such characters,
6 | * at distinct (adjacent) offsets.
7 | * IOW, much as Java Strings.
8 | * @author acl33
9 | *
10 | */
11 | public interface Document {
12 | /** Get the character at the specified index, or null if the document does not contain
13 | * such an index. (Note, it is suggested to use Character.valueOf(...)
to
14 | * reduce allocation.)
15 | * @param pos Position in the document (0=first). Note, if this method returns null for
16 | * some value of pos, it should also return null for all indices greater than that value.
17 | * @return Character object for the char at the specified index, or null if that's beyond
18 | * the end of the Document.
19 | */
20 | public Character getCharAt(int pos);
21 | }
22 |
--------------------------------------------------------------------------------
/src/dasher/EParameters.java:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of JDasher.
3 |
4 | JDasher is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | JDasher is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with JDasher; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | Copyright (C) 2006 Christopher Smowton
19 |
20 | JDasher is a port derived from the Dasher project; for information on
21 | the project see www.dasher.org.uk; for information on JDasher itself
22 | and related projects see www.smowton.net/chris
23 |
24 | */
25 |
26 | package dasher;
27 |
28 | import java.util.HashMap;
29 | import java.util.Map;
30 |
31 | /**
32 | * Interface implemented by all parameter enumerations, allowing
33 | * an EParameters to be passed as a generic parameter of indeterminate
34 | * type.
35 | * All C++-style integer based enums have now been replaced by three Enum types
36 | * which implement EParameters, meaning one can pass both a generic parameter AND
37 | * a specialised parameter. For references into the tables, the .ordinal() of
38 | * a specialised parameter is used. All switch() statements should now check
39 | * the parameter's type, cast it to the appropriate one, and then switch on
40 | * the relevant enum. Alternatively it may be possible to have cases of a
41 | * child-type, I've yet to check this.
42 | *
43 | * 14/07: The whole codebase is now converted to use the new parameter scheme.
44 | * It's broadly very solid; everything is passed around as enum types until the actual
45 | * load/store instructions in CSettingsStore, whereupon ordinals are taken.
46 | *
47 | * The only weakness is that one CANNOT in fact switch on an EParameters, since
48 | * there is no way for the compiler to know that all its children are Enums.
49 | * There may be some way around this -- some sort of enum-interface -- but
50 | * I haven't found it yet. This can be solved by splitting any switch
51 | * into three, type-checking, casting, and then switching in a type-specific
52 | * manner.
53 | */
54 | public interface EParameters {
55 |
56 | public int key();
57 | public String regName();
58 | public void reset(CSettingsStore ss);
59 | public static final Map BY_NAME=new HashMap();
60 |
61 | /* CSFS: This space intentionally left blank.
62 | *
63 | * This is the parent class for the enumerations of all three types of parameters.
64 | * Ebp_parameters houses the boolean parameters,
65 | * Elp_parameters the longs,
66 | * and Esp_parameters the strings.
67 | */
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/src/dasher/Ebp_parameters.java:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of JDasher.
3 |
4 | JDasher is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | JDasher is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with JDasher; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | Copyright (C) 2006 Christopher Smowton
19 |
20 | JDasher is a port derived from the Dasher project; for information on
21 | the project see www.dasher.org.uk; for information on JDasher itself
22 | and related projects see www.smowton.net/chris
23 |
24 | */
25 |
26 | package dasher;
27 |
28 | /**
29 | * Enumeration of possible boolean parameter references. See
30 | * CParamTables for a list and definitions.
31 | */
32 | public enum Ebp_parameters implements EParameters {
33 | BP_REMAP_XTREME("RemapXtreme", false, "Remap y & limit x at top/bottom extremes"),
34 | BP_DRAW_MOUSE_LINE("DrawMouseLine", true, "Draw Mouse Line"),
35 | BP_DRAW_MOUSE("DrawMouse", true, "Draw Mouse Position"),
36 | BP_SHOW_SLIDER("ShowSpeedSlider", true, "ShowSpeedSlider"),
37 | BP_START_MOUSE("StartOnLeft", true, "StartOnLeft"),
38 | BP_START_SPACE("StartOnSpace", false, "StartOnSpace"),
39 | BP_STOP_IDLE("StopOnIdle", false, "StopOnIdle"),
40 | BP_KEY_CONTROL("KeyControl", false, "KeyControl"),
41 | BP_CONTROL_MODE("ControlMode", false, "ControlMode"),
42 | BP_COLOUR_MODE("ColourMode", true, "ColourMode"),
43 | BP_MOUSEPOS_MODE("StartOnMousePosition", false, "StartOnMousePosition"),
44 | BP_OUTLINE_MODE("OutlineBoxes", true, "OutlineBoxes"),
45 | BP_AUTOCALIBRATE("AutoAdjust", false, "Auto-adjust offset for eyetracker miscalibration"),
46 | BP_LM_DICTIONARY("Dictionary", true, "Whether the word-based language model uses a dictionary"),
47 | BP_AUTO_SPEEDCONTROL("AutoSpeedControl", true, "AutoSpeedControl"),
48 | BP_LM_ADAPTIVE("LMAdaptive", true, "Whether language model should learn as you enter text"),
49 | BP_CIRCLE_START("CircleStart", false, "Start on circle mode"),
50 | BP_LM_REMOTE("RemoteLM", false, "Language model is remote and responds asynchronously."),
51 | BP_ONE_DIMENSIONAL_MODE("OneDimensionalMode", false, "Remap x/y to radius / curve all around origin"),
52 | BP_ONE_BUTTON_RELEASE_TIME("OneButtonReleaseTime", false, "Use length of single push, not gap, for 1B-dynamic mode"),
53 | BP_CONTROL_MODE_REBUILD("ControlModeRebuild",true,"Replace control nodes that have happened with characters to left of cursor"),
54 | BP_CONTROL_MODE_HAS_MOVE("ControlModeHasMove",true,"Include nodes to move cursor"),
55 | BP_MOVE_REBUILD_IMMED("ControlMoveRebuildImmed",false,"Rebuild move nodes immediately rather than on commit"),
56 | BP_CONTROL_MODE_ALPH_SWITCH("ControlModeHasAlphSwitch",true,"Include nodes to switch to previous four alphabets"),
57 | BP_CONTROL_MODE_HAS_SPEED("ControlModeHasSpeed",true,"Include nodes to change speed up/down")
58 | ;
59 |
60 |
61 | private Ebp_parameters(String rName, boolean def, String hr) {
62 | humanReadable = hr;
63 | defaultVal = def;
64 | regName = rName;
65 | BY_NAME.put(regName,this);
66 | }
67 |
68 | public int key() {return ordinal();}
69 | public String regName() {return regName;}
70 | public void reset(CSettingsStore ss) {ss.SetBoolParameter(this, defaultVal);}
71 | private final String regName;
72 | final boolean defaultVal;
73 | final String humanReadable;
74 | }
--------------------------------------------------------------------------------
/src/dasher/EditableDocument.java:
--------------------------------------------------------------------------------
1 | package dasher;
2 |
3 | public interface EditableDocument extends Document {
4 |
5 | /** Call to output/write text at a given position
6 | * (when a symbol node is entered).
7 | * @param ch String representation of a single symbol (i.e. one unicode character point)
8 | * @param offset index where character should be afterwards. (e.g. 0=this is first character)
9 | */
10 | public abstract void outputText(String ch, int offset);
11 |
12 | /** Call to delete text at a given position
13 | * In other words, this performs a single backspace operation - when the user leaves a symbol node.
14 | * @param ch String representation of a single symbol (i.e. one unicode character point)
15 | * @param offset index where character should previously have been (e.g. 0=delete first character)
16 | */
17 | public abstract void deleteText(String ch, int offset);
18 |
19 | public abstract void moveCursor(int iNewOffset);
20 | }
21 |
--------------------------------------------------------------------------------
/src/dasher/Elp_parameters.java:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of JDasher.
3 |
4 | JDasher is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | JDasher is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with JDasher; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | Copyright (C) 2006 Christopher Smowton
19 |
20 | JDasher is a port derived from the Dasher project; for information on
21 | the project see www.dasher.org.uk; for information on JDasher itself
22 | and related projects see www.smowton.net/chris
23 |
24 | */
25 |
26 | package dasher;
27 |
28 | /**
29 | * Enumeration of possible integer parameter references. See
30 | * CParamTables for a list and definitions.
31 | */
32 | public enum Elp_parameters implements EParameters {
33 | LP_MAX_BITRATE("MaxBitRateTimes100", 80, "Max Bit Rate Times 100"),
34 | LP_FRAMERATE("FrameRate", 3200, "Decaying average of last known frame rates, *100"),
35 | LP_VIEW_ID("ViewID", 1, "ViewID"),
36 | LP_LANGUAGE_MODEL_ID("LanguageModelID", 0, "LanguageModelID"),
37 | LP_DASHER_FONTSIZE("DasherFontSize", 1, "DasherFontSize"),
38 | LP_UNIFORM("UniformTimes1000", 50, "UniformTimes1000"),
39 | LP_MOUSEPOSDIST("MousePositionBoxDistance", 50, "MousePositionBoxDistance"),
40 | //LP_STOP_IDLETIME("StopIdleTime", 1000, "StopIdleTime" ),
41 | LP_LM_MAX_ORDER("LMMaxOrder", 5, "LMMaxOrder"),
42 | LP_LM_UPDATE_EXCLUSION("LMUpdateExclusion", 1, "LMUpdateExclusion"),
43 | LP_LM_ALPHA("LMAlpha", 49, "LMAlpha"),
44 | LP_LM_BETA("LMBeta", 77, "LMBeta"),
45 | //LP_LM_MIXTURE("LMMixture", 50, "LMMixture"),
46 | LP_LINE_WIDTH("LineWidth", 1, "Width to draw crosshair and mouse line"),
47 | //LP_LM_WORD_ALPHA("WordAlpha", 50, "Alpha value for word-based model"),
48 | LP_USER_LOG_LEVEL_MASK("UserLogLevelMask", 0, "Controls level of user logging, 0 = none, 1 = short, 2 = detailed, 3 = both"),
49 | LP_ZOOMSTEPS("Zoomsteps", 32, "Frames for zoom"),
50 | LP_B("ButtonMenuBoxes", 4, "Number of boxes for button menu mode"),
51 | LP_S("ButtonMenuSafety", 25, "Safety parameter for button mode, in percent."),
52 | LP_R("ButtonModeNonuniformity", 0, "Button mode box non-uniformity"),
53 | //LP_Z("ButtonMenuBackwardsBox", 1, "Number of back-up boxes for button menu mode"),
54 | LP_RIGHTZOOM("ButtonCompassModeRightZoom", 5120, "Zoomfactor (*1024) for compass mode"),
55 | LP_AUTOSPEED_SENSITIVITY("AutospeedSensitivity", 100, "Sensitivity of automatic speed control (percent)"),
56 | /*LP_SOCKET_PORT("SocketPort", 20320, "UDP/TCP socket to use for network socket input"),
57 | LP_SOCKET_INPUT_X_MIN("SocketInputXMinTimes1000", 0, "Bottom of range of X values expected from network input"),
58 | LP_SOCKET_INPUT_X_MAX("SocketInputXMaxTimes1000", 1000, "Top of range of X values expected from network input"),
59 | LP_SOCKET_INPUT_Y_MIN("SocketInputYMinTimes1000", 0, "Bottom of range of Y values expected from network input"),
60 | LP_SOCKET_INPUT_Y_MAX("SocketInputYMaxTimes1000", 1000, "Top of range of Y values expected from network input"),*/
61 | //LP_INPUT_FILTER("InputFilterID", 3, "Module ID of input filter"),
62 | LP_CIRCLE_PERCENT("CirclePercent", 10, "Percentage of nominal vertical range to use for radius of start circle"),
63 | LP_TWO_BUTTON_OFFSET("TwoButtonOffset", 1024, "Offset for two button dynamic mode"),
64 | LP_TAP_TIME("TapTime", 100, "Max time for tap in Stylus Mode"),
65 | LP_NON_LINEAR_X("NonLinearX", 8, "Nonlinear compression of X-axis (0 = none, higher = more extreme)"),
66 | LP_DASHER_MARGIN("MarginWidth", 400, "Width of RHS margin (in Dasher co-ords)"),
67 | LP_NODE_BUDGET("NodeBudget", 1200, "Target number of node objects"),
68 | LP_BUTTON_SCAN_TIME("ButtonScanTime", 0, "Scanning interval in button mode (0 = don't scan)"),
69 | LP_MIN_NODE_SIZE_TEXT("MinNodeSizeForText",40, "Minimum size for box to have text (4096=whole screen)"),
70 | LP_SLOW_START_TIME("SlowStartTime", 1000, "Time in ms over which slow start is applied"),
71 | LP_SWEEP_TIME("SweepTime", 3000, "Time in ms to sweep top-to-bottom"),
72 | LP_X_LIMIT_SPEED("XLimitSpeed", 800, "X Co-ordinate at which maximum speed is reached (<2048=xhair)"),
73 | LP_MAX_ZOOM("MaxZoom", 20, "Max factor to zoom by in stylus/click mode"),
74 | LP_TARGET_OFFSET("TargetOffset", 0, "Offset target from actual mouse/touch/gaze position"),
75 | /** Can we combine this with LP_TAP_TIME? Think we want this to be much longer...?*/
76 | LP_HOLD_TIME("LongPressTime", 800,"Time/ms for long press (=reverse) in dynamic button mode"),
77 | LP_DOUBLE_CLICK_TIME("DoublePressTime", 150,"Time/ms for double click (=reverse) in 2B-dynamic mode"),
78 | LP_ONE_BUTTON_SHORT_GAP("OneButtonShortGap", 40, "Distance between up markers as % of long gap in 1B-dynamic mode"),
79 | LP_ONE_BUTTON_LONG_GAP("OneButtonLongGap", 512, "Distance between down markers (long gap) in 1B-dynamic mode"),
80 | LP_ONE_BUTTON_OUTER("OneButtonOuter", 1920, "Distance to up&down outer markers in 1B-dynamic mode");
81 |
82 | private Elp_parameters(String rName, long def, String hr) {
83 | humanReadable = hr;
84 | defaultVal = def;
85 | regName = rName;
86 | BY_NAME.put(regName,this);
87 | }
88 |
89 | private static final int LP_OFFSET = Ebp_parameters.values().length;
90 | public int key() {return ordinal()+LP_OFFSET;}
91 | public String regName() {return regName;}
92 | public void reset(CSettingsStore ss) {ss.SetLongParameter(this, defaultVal);}
93 |
94 | private final String regName;
95 |
96 | public final long defaultVal;
97 | final String humanReadable;
98 | }
--------------------------------------------------------------------------------
/src/dasher/Esp_parameters.java:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of JDasher.
3 |
4 | JDasher is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | JDasher is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with JDasher; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | Copyright (C) 2006 Christopher Smowton
19 |
20 | JDasher is a port derived from the Dasher project; for information on
21 | the project see www.dasher.org.uk; for information on JDasher itself
22 | and related projects see www.smowton.net/chris
23 |
24 | */
25 |
26 | package dasher;
27 |
28 | /**
29 | * Enumeration of possible String parameter references. See
30 | * CParamTables for a list and definitions.
31 | */
32 | public enum Esp_parameters implements EParameters {
33 | SP_ORIENTATION("Orientation", "", "Orientation (TB/BT/LR/RL) - anything else = use alphabet"),
34 | SP_ALPHABET_ID("AlphabetID", "", "AlphabetID"),
35 | SP_ALPHABET_1("Alphabet1", "", "Alphabet History 1"),
36 | SP_ALPHABET_2("Alphabet2", "", "Alphabet History 2"),
37 | SP_ALPHABET_3("Alphabet3", "", "Alphabet History 3"),
38 | SP_ALPHABET_4("Alphabet4", "", "Alphabet History 4"),
39 | SP_COLOUR_ID("ColourID", "", "ColourID"),
40 | SP_DASHER_FONT("DasherFont", "", "DasherFont"),
41 | SP_SOCKET_INPUT_X_LABEL("SocketInputXLabel", "x", "Label preceding X values for network input"),
42 | SP_SOCKET_INPUT_Y_LABEL("SocketInputYLabel", "y", "Label preceding Y values for network input"),
43 | SP_INPUT_FILTER("InputFilter", "Stylus Control", "Input filter used to provide the current control mode"),
44 | SP_INPUT_DEVICE("InputDevice", "Mouse Input", "Driver for the input device"),
45 | SP_LM_HOST("LMHost", "", "Language Model Host");
46 |
47 | private Esp_parameters(String rName, String def, String hr) {
48 | humanReadable = hr;
49 | defaultVal = def;
50 | regName = rName;
51 | BY_NAME.put(regName,this);
52 | }
53 |
54 | private static final int SP_OFFSET = Ebp_parameters.values().length + Elp_parameters.values().length;
55 | public int key() {return ordinal()+SP_OFFSET;}
56 | public String regName() {return regName;}
57 | public void reset(CSettingsStore ss) {ss.SetStringParameter(this, defaultVal);}
58 |
59 | private final String regName;
60 | final String defaultVal;
61 | final String humanReadable;
62 | }
63 |
--------------------------------------------------------------------------------
/src/dasher/Observer.java:
--------------------------------------------------------------------------------
1 | package dasher;
2 |
3 | public interface Observer {
4 | public void HandleEvent(T t);
5 | }
6 |
--------------------------------------------------------------------------------
/src/dasher/OneButtonDynamicFilter.java:
--------------------------------------------------------------------------------
1 | package dasher;
2 |
3 | import static dasher.CDasherModel.CROSS_Y;
4 |
5 | public class OneButtonDynamicFilter extends CDynamicButtons {
6 |
7 | private BounceMarker upInner, downInner, upOuter, downOuter;
8 |
9 | private boolean m_bDecorationChanged;
10 | private double m_dNatsAtLastApply;
11 | private int m_iKeyHeldId=-1;
12 | /** Time at which button was first pressed (/pressed down, if we're using the release time),
13 | * or Long.MAX_VALUE if no such first press has occurred.
14 | */
15 | private long m_iFirstPressTime = Long.MAX_VALUE;
16 | private double m_dNatsAtFirstPress;
17 |
18 | /** locations of up/down guidelines (DasherY) - computed in Timer */
19 | private int guideUp, guideDown;
20 | private double m_dMulBoundary;
21 | private boolean m_bUseUpGuide;
22 |
23 | public OneButtonDynamicFilter(CDasherComponent creator, CDasherInterfaceBase iface) {
24 | super(creator, iface, "One-button Dynamic Mode");
25 | createMarkers();
26 | }
27 |
28 | @Override
29 | public boolean DecorateView(CDasherView pView, CDasherInput pInput) {
30 | int y= (int)(downInner.m_iLocn*m_dMulBoundary);
31 | pView.Dasherline(-100, 2048-y, -1000, 2048-y, 1, 62);
32 | y=(int)(upInner.m_iLocn * m_dMulBoundary);
33 | pView.Dasherline(-100, 2048-y, -1000, 2048-y, 1, 62);
34 |
35 | //Moving markers...
36 | if (m_iFirstPressTime!=Long.MAX_VALUE) {
37 | int upCol=m_bUseUpGuide ? 240 : 61, downCol=240+61-upCol; //240 = green = active, 61 = orange/yellow = inactive
38 | pView.Dasherline(-100, 2048-guideUp, -1000, 2048-guideUp, 3, upCol);
39 | pView.Dasherline(-100, 2048-guideDown, -1000, 2048-guideDown, 3, downCol);
40 | }
41 | //Fixed markers - draw last so they go on top...
42 | upInner.Draw(pView);
43 | upOuter.Draw(pView);
44 | downInner.Draw(pView);
45 | downOuter.Draw(pView);
46 |
47 | if (m_bDecorationChanged) {
48 | m_bDecorationChanged=false;
49 | return true;
50 | }
51 | return false;
52 | }
53 |
54 | @Override protected void TimerImpl(long iTime, CDasherView pView, CDasherModel pModel) {
55 | if (m_iFirstPressTime!=Long.MAX_VALUE) {
56 | double dGrowth = Math.exp(pModel.GetNats()-m_dNatsAtFirstPress);
57 | guideUp = (int)(dGrowth*upInner.m_iLocn);
58 | guideDown = (int)(dGrowth*downInner.m_iLocn);
59 | m_bUseUpGuide = dGrowth < m_dMulBoundary;
60 | CDasherView.DRect visReg = pView.VisibleRegion();
61 | if (2048-guideUp < visReg.minY && 2048-guideDown>visReg.maxY) {
62 | //both markers outside y-axis (well, in compressed region)
63 | // => waited too long for second press(/release)
64 | reverse(iTime, pModel);
65 | return; //hmmm. without scheduling anything?
66 | }
67 | }
68 | pModel.ScheduleOneStep(0, CROSS_Y, iTime, getSpeedMul(pModel, iTime));
69 | }
70 |
71 | @Override
72 | public void HandleEvent(EParameters eParam) {
73 | if (eParam==Elp_parameters.LP_ONE_BUTTON_OUTER
74 | || eParam==Elp_parameters.LP_ONE_BUTTON_LONG_GAP
75 | || eParam==Elp_parameters.LP_ONE_BUTTON_SHORT_GAP)
76 | createMarkers();
77 | super.HandleEvent(eParam);
78 | }
79 |
80 | private void createMarkers() {
81 | final int outer = (int)GetLongParameter(Elp_parameters.LP_ONE_BUTTON_OUTER),
82 | biggap = (int)GetLongParameter(Elp_parameters.LP_ONE_BUTTON_LONG_GAP),
83 | down = outer - biggap,
84 | up = outer - (int)(biggap * GetLongParameter(Elp_parameters.LP_ONE_BUTTON_SHORT_GAP))/100;
85 |
86 | upInner = new BounceMarker(up);
87 | upOuter = new BounceMarker(outer);
88 | downInner = new BounceMarker(-down);
89 | downOuter = new BounceMarker(-outer);
90 | m_dMulBoundary = outer/Math.sqrt(up*down);
91 | }
92 |
93 | @Override public void KeyDown(long iTime, int iId, CDasherView pView, CDasherInput pInput, CDasherModel pModel) {
94 | if (m_iKeyHeldId!=-1 && iId != m_iKeyHeldId) return; //ignore subsequent presses whilst button down
95 | m_iKeyHeldId=iId;
96 | if (isReversing())
97 | pause();
98 | else if (isPaused())
99 | run(iTime, pModel);
100 | else if (m_iFirstPressTime==Long.MAX_VALUE) {
101 | m_iFirstPressTime = iTime;
102 | m_dNatsAtFirstPress = pModel.GetNats();
103 | } else
104 | secondPress(iTime,pModel);
105 | }
106 |
107 | @Override public void KeyUp(long iTime, int iId, CDasherView pView, CDasherInput pInput, CDasherModel pModel) {
108 | if (iId == m_iKeyHeldId) {
109 | m_iKeyHeldId=-1;
110 | if (m_iFirstPressTime!=Long.MAX_VALUE && GetBoolParameter(Ebp_parameters.BP_ONE_BUTTON_RELEASE_TIME))
111 | secondPress(iTime,pModel);
112 | }
113 | }
114 |
115 | protected void secondPress(long iTime, CDasherModel pModel) {
116 | BounceMarker inner,outer;
117 | if (m_bUseUpGuide) {
118 | inner = upInner; outer=upOuter;
119 | } else {
120 | inner = downInner; outer = downOuter;
121 | }
122 | double dCurBitrate = GetLongParameter(Elp_parameters.LP_MAX_BITRATE) /100.0;
123 | int iOffset = inner.GetTargetOffset(dCurBitrate*getSpeedMul(pModel, iTime), outer, iTime - m_iFirstPressTime);
124 | if (pModel.m_iDisplayOffset!=0) {
125 | iOffset -= pModel.m_iDisplayOffset;
126 | System.err.println("Display Offset "+pModel.m_iDisplayOffset+" reducing to "+iOffset);
127 | }
128 | double dNewNats = pModel.GetNats() - m_dNatsAtLastApply;
129 | upInner.NotifyOffset(iOffset, dNewNats); upOuter.NotifyOffset(iOffset, dNewNats);
130 | downInner.NotifyOffset(iOffset, dNewNats); downOuter.NotifyOffset(iOffset, dNewNats);
131 | inner.RecordPush(iOffset, pModel.GetNats() - m_dNatsAtFirstPress, dCurBitrate);
132 | outer.RecordPush(iOffset, 0.0, dCurBitrate);
133 | ApplyOffset(pModel, iOffset);
134 | m_dNatsAtLastApply = pModel.GetNats();
135 | m_iFirstPressTime = Long.MAX_VALUE;
136 | }
137 |
138 | @Override public void reverse(long iTime, CDasherModel pModel) {
139 | upInner.clearPushes(); upOuter.clearPushes(); downInner.clearPushes(); downOuter.clearPushes();
140 | m_iFirstPressTime = Long.MAX_VALUE;
141 | super.reverse(iTime, pModel);
142 | }
143 |
144 | }
145 |
--------------------------------------------------------------------------------
/src/dasher/Opts.java:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of JDasher.
3 |
4 | JDasher is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | JDasher is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with JDasher; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | Copyright (C) 2006 Christopher Smowton
19 |
20 | JDasher is a port derived from the Dasher project; for information on
21 | the project see www.dasher.org.uk; for information on JDasher itself
22 | and related projects see www.smowton.net/chris
23 |
24 | */
25 |
26 | package dasher;
27 |
28 | import java.util.Map;
29 | import java.util.HashMap;
30 | /**
31 | * List of miscellaneous constants, some of which are probably
32 | * now redundant, inclduing those describing encodings, as Java
33 | * will always use UTF16 internally.
34 | */
35 | public class Opts {
36 |
37 | // Encodings
38 |
39 | public static final int UserDefault = -1;
40 | public static final int AlphabetDefault = -2;
41 | public static final int UTF8 = 65001;
42 | public static final int UTF16LE = 1200;
43 | public static final int UTF16BE = 1201;
44 |
45 | /**
46 | * List of available screen orientations. The "Alphabet"
47 | * option means that the Alphabet's preferred orientation
48 | * is used.
49 | */
50 | public static enum ScreenOrientations {
51 | LEFT_TO_RIGHT(true),RIGHT_TO_LEFT(true),TOP_TO_BOTTOM(false),BOTTOM_TO_TOP(false);
52 |
53 | private ScreenOrientations(boolean bHoriz) {this.isHorizontal=bHoriz;}
54 | public final boolean isHorizontal;
55 | }
56 |
57 | public static ScreenOrientations orientationFromString(String s) {
58 | return abbrevOrientations.get(s.trim().toUpperCase());
59 | }
60 |
61 | private static final Map abbrevOrientations = new HashMap();
62 | static {
63 | abbrevOrientations.put("RL", ScreenOrientations.RIGHT_TO_LEFT);
64 | abbrevOrientations.put("LR", ScreenOrientations.LEFT_TO_RIGHT);
65 | abbrevOrientations.put("TB", ScreenOrientations.TOP_TO_BOTTOM);
66 | abbrevOrientations.put("BT", ScreenOrientations.BOTTOM_TO_TOP);
67 | }
68 | /**
69 | * This appears to enumerate codepages, which is also very
70 | * much useless in Java.
71 | */
72 | class AlphabetTypes {
73 | public static final int MyNone = 0;
74 | public static final int Arabic = 1256;
75 | public static final int Baltic = 1257;
76 | public static final int CentralEurope = 1250;
77 | public static final int ChineseSimplified = 936;
78 | public static final int ChineseTraditional = 950;
79 | public static final int Cyrillic = 1251;
80 | public static final int Greek = 1253;
81 | public static final int Hebrew = 1255;
82 | public static final int Japanese = 932;
83 | public static final int Korean = 949;
84 | public static final int Thai = 874;
85 | public static final int Turkish = 1254;
86 | public static final int VietNam = 1258;
87 | public static final int Western = 1252; }
88 | }
89 |
--------------------------------------------------------------------------------
/src/dasher/SGroupInfo.java:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of JDasher.
3 |
4 | JDasher is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | JDasher is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with JDasher; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | Copyright (C) 2006 Christopher Smowton
19 |
20 | JDasher is a port derived from the Dasher project; for information on
21 | the project see www.dasher.org.uk; for information on JDasher itself
22 | and related projects see www.smowton.net/chris
23 |
24 | */
25 |
26 | package dasher;
27 |
28 | /**
29 | * Small struct representing a group of Nodes, as used to draw
30 | * coloured grouping boxes which surround a family of nodes, such
31 | * as punctuation.
32 | */
33 | public class SGroupInfo {
34 |
35 | public SGroupInfo(String label, int col, boolean visible) {
36 | this.strLabel = label;
37 | this.iColour = col;
38 | this.bVisible = visible;
39 | }
40 |
41 | /**
42 | * First child group
43 | */
44 | SGroupInfo Child;
45 |
46 | /**
47 | * Next sibling group
48 | */
49 | SGroupInfo Next;
50 |
51 | /**
52 | * Label for this group
53 | */
54 | final String strLabel;
55 |
56 | /**
57 | * Index of the first node contained in this group
58 | */
59 | int iStart;
60 |
61 | /**
62 | * Index of the last node contained in this group
63 | */
64 | int iEnd;
65 |
66 | /**
67 | * Colour index used to draw this group
68 | */
69 | final int iColour;
70 |
71 | /**
72 | * Should this group be drawn?
73 | */
74 | final boolean bVisible;
75 |
76 | /** Number of child nodes = immediate subgroups + symbols contained directly (not in a subgroup) */
77 | int iNumChildNodes;
78 | }
--------------------------------------------------------------------------------
/src/dasher/TwoButtonDynamicFilter.java:
--------------------------------------------------------------------------------
1 | package dasher;
2 |
3 | import static dasher.CDasherModel.CROSS_Y;
4 | import dasher.CDasherView.MutablePoint;
5 |
6 | public class TwoButtonDynamicFilter extends CDynamicPresses {
7 |
8 | private BounceMarker up,down;
9 | private boolean m_bDecorationChanged;
10 | private double m_dNatsAtLastApply;
11 |
12 | public TwoButtonDynamicFilter(CDasherComponent creator, CDasherInterfaceBase iface) {
13 | super(creator, iface, "Two-button Dynamic Mode");
14 | createMarkers();
15 | }
16 |
17 | @Override
18 | public boolean DecorateView(CDasherView pView, CDasherInput pInput) {
19 | up.Draw(pView);
20 | down.Draw(pView);
21 | if (m_bDecorationChanged) {
22 | m_bDecorationChanged=false;
23 | return true;
24 | }
25 | return false;
26 | }
27 |
28 | @Override
29 | public void TimerImpl(long iTime, CDasherView pView,CDasherModel pModel) {
30 | super.TimerImpl(iTime, pView, pModel);
31 | pModel.ScheduleOneStep(0, CROSS_Y, iTime, getSpeedMul(pModel, iTime));
32 | }
33 |
34 | @Override
35 | public void HandleEvent(EParameters eParam) {
36 | if (eParam==Elp_parameters.LP_TWO_BUTTON_OFFSET)
37 | createMarkers();
38 | super.HandleEvent(eParam);
39 | }
40 |
41 | private void createMarkers() {
42 | up = new BounceMarker((int)GetLongParameter(Elp_parameters.LP_TWO_BUTTON_OFFSET));
43 | down = new BounceMarker((int)-GetLongParameter(Elp_parameters.LP_TWO_BUTTON_OFFSET));
44 | m_bDecorationChanged=true;
45 | }
46 |
47 | private final MutablePoint coords=new MutablePoint();
48 |
49 | @Override public void KeyDown(long iTime, int iId, CDasherView pView, CDasherInput pInput, CDasherModel pModel) {
50 | if (iId==100 && pInput.GetDasherCoords(pView, coords))
51 | iId = (coords.y < CROSS_Y) ? 0 : 1;
52 | super.KeyDown(iTime, iId, pView, pInput, pModel);
53 | }
54 |
55 | @Override public void KeyUp(long iTime, int iId, CDasherView pView, CDasherInput pInput, CDasherModel pModel) {
56 | if (iId==100 && pInput.GetDasherCoords(pView, coords))
57 | iId = (coords.y < CROSS_Y) ? 0 : 1;
58 | super.KeyUp(iTime, iId, pView, pInput, pModel);
59 | }
60 |
61 | @Override public void Event(long iTime, int iId, int pressType, CDasherModel pModel) {
62 | marker: if (pressType==SINGLE_PRESS && isRunning()) {
63 | BounceMarker pMarker;
64 | if (iId==0 || iId==4) pMarker=up; else if (iId==1 || iId==2) pMarker=down; else break marker;
65 | //apply offset
66 | double dCurBitrate = GetLongParameter(Elp_parameters.LP_MAX_BITRATE) / 100.0;
67 | int iOffset = pMarker.GetTargetOffset(dCurBitrate*getSpeedMul(pModel, iTime));
68 | if (pModel.m_iDisplayOffset!=0) System.err.println("Display Offset "+pModel.m_iDisplayOffset+" reducing to "+(iOffset -= pModel.m_iDisplayOffset));
69 | double dNewNats = pModel.GetNats() - m_dNatsAtLastApply;
70 | up.NotifyOffset(iOffset, dNewNats);
71 | down.NotifyOffset(iOffset, dNewNats);
72 | pMarker.RecordPush(iOffset, 0.0, dCurBitrate);
73 | ApplyOffset(pModel,iOffset);
74 | m_dNatsAtLastApply = pModel.GetNats();
75 | }
76 | super.Event(iTime, iId, pressType, pModel);
77 | }
78 |
79 | @Override protected void reverse(long iTime, CDasherModel pModel) {
80 | up.clearPushes(); down.clearPushes();
81 | super.reverse(iTime, pModel);
82 | }
83 |
84 | }
85 |
--------------------------------------------------------------------------------
/src/dasher/XMLFileParser.java:
--------------------------------------------------------------------------------
1 | package dasher;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.util.List;
6 | import java.util.ArrayList;
7 |
8 | import javax.xml.parsers.ParserConfigurationException;
9 | import javax.xml.parsers.SAXParser;
10 | import javax.xml.parsers.SAXParserFactory;
11 |
12 | import org.xml.sax.Attributes;
13 | import org.xml.sax.InputSource;
14 | import org.xml.sax.SAXException;
15 | import org.xml.sax.helpers.DefaultHandler;
16 |
17 | /**
18 | * Abstract superclass for XML file parsing (colours, alphabets).
19 | * Exists for two reasons:
20 | *
21 | * - To provide a common (abstract) entry point for parsing files
22 | * found by implementations of {@link CDasherInterfaceBase#ScanXMLFiles(XMLFileParser, String)}
23 | *
- Provides a common implementation of {@link #getStream(String)}, used
24 | * to try to locate DTDs (differently by subclasses).
25 | * @author acl33
26 | */
27 | public abstract class XMLFileParser extends DefaultHandler {
28 | protected final CDasherInterfaceBase m_Interface;
29 | private final SAXParser parser;
30 | public XMLFileParser(CDasherInterfaceBase intf) {
31 | this.m_Interface = intf;
32 | SAXParserFactory factory = SAXParserFactory.newInstance();
33 | SAXParser p;
34 | try {
35 | p = factory.newSAXParser();
36 | } catch(Exception e) {
37 | //Report error, but continue - and don't parse files -
38 | // so user gets something minimal rather than nothing
39 | System.out.printf("Exception creating XML parser: %s%n", e);
40 | p=null;
41 | }
42 | parser=p;
43 | }
44 |
45 | /**
46 | * Process the provided XML file!
47 | * @param in InputStream allowing the file to be read
48 | * @param bLoadMutable True if the file should be allowed to be edited (e.g.
49 | * per-user files), false if not (e.g. for system files). TODO, editing is
50 | * not actually implemented at this point; so either implement it, or remove
51 | * the API...
52 | * @throws SAXException If there was an error during parsing - XML malformed?
53 | * @throws IOException If the file/stream could not be properly read
54 | */
55 | public void ParseFile(InputStream in, boolean bLoadMutable) throws SAXException, IOException {
56 | if (parser!=null)
57 | parser.parse(new InputSource(in),this);
58 | }
59 |
60 | /**
61 | * Method to lookup resources e.g. DTD files. Provided to ease
62 | * implementation of DefaultHandler#resolveEntity(String,String).
63 | * Looks up the filename using {@link CDasherInterfaceBase#GetStreams(String, java.util.Collection)},
64 | * and returns an InputSource constructed from the first stream found, or else null.
65 | *
66 | * @param name Filename needed (e.g. "alphabet.dtd")
67 | * @return InputSource for the resource/entity, if possible, else null.
68 | */
69 | protected final InputSource getStream(String name) {
70 | List streams = new ArrayList();
71 | m_Interface.GetStreams(name, streams);
72 | if (!streams.isEmpty()) return new InputSource(streams.get(0));
73 | return null;
74 | }
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/src/dasher/android/AndroidKeyMap.java:
--------------------------------------------------------------------------------
1 | package dasher.android;
2 |
3 | import android.view.KeyEvent;
4 | import dasher.CButtonMode;
5 | import dasher.CCompassMode;
6 | import dasher.CDasherComponent;
7 | import dasher.CDasherInterfaceBase;
8 | import dasher.CMenuMode;
9 | import dasher.CSettingsStore;
10 | import dasher.OneButtonDynamicFilter;
11 | import dasher.TwoButtonDynamicFilter;
12 |
13 | interface AndroidKeyMap {
14 | /**
15 | * Converts an Android key code (KEYCODE_* in class android.KeyEvent)
16 | * into a Dasher key id (int) used by this input filter
17 | * @param keyCode Android keycode as passed to e.g. {@link DasherInputMethod#onKeyUp}/onKeyDown
18 | * @return Dasher key id to pass to {@link ADasherInterface#KeyDown(long, int)}, or
19 | * return -1 to ignore the KeyEvent.
20 | */
21 | public int ConvertAndroidKeycode(int keyCode);
22 | }
23 |
24 | /*interface TeklaSwitchListener {
25 | public static final int TEKLA_SWITCH_RIGHT=80;
26 | public static final int TEKLA_SWITCH_LEFT=40;
27 | public static final int TEKLA_SWITCH_DOWN=20;
28 | public static final int TEKLA_SWITCH_UP=10;
29 | /** Called to handle presses of external switches connected via tekla (bluetooth) shield.
30 | * @param Time timestamp, as per System.currentTimeMillis()
31 | * @param iId Tekla switch event code (as per Tekla Switch Event Flow wiki page)
32 | * @param pView current view rendering to the screen
33 | * @param pInput current input device for obtaining coordinates, if appropriate
34 | * @param Model current dasher model, i.e. state of nodes
35 | */
36 | /*public void TeklaSwitchEvent(long Time, int iId, CDasherView pView, CDasherInput pInput, CDasherModel model);
37 | }*/
38 |
39 | class Android2BDynamic extends TwoButtonDynamicFilter implements AndroidKeyMap {
40 |
41 | public Android2BDynamic(CDasherComponent creator, CDasherInterfaceBase iface) {
42 | super(creator, iface);
43 | }
44 |
45 | public int ConvertAndroidKeycode(int iId) {
46 | if (iId==KeyEvent.KEYCODE_VOLUME_UP) return 0;
47 | if (iId==KeyEvent.KEYCODE_VOLUME_DOWN) return 1;
48 | return -1;
49 | }
50 | }
51 |
52 | class AndroidCompass extends CCompassMode implements AndroidKeyMap {
53 |
54 | public AndroidCompass(CDasherComponent creator, CDasherInterfaceBase iface) {
55 | super(creator, iface);
56 | }
57 |
58 | public int ConvertAndroidKeycode(int keyCode) {
59 | //Trackball movement
60 | if (keyCode>=19 && keyCode<=22) {
61 | //yields 2,4,1,3
62 | return ((keyCode-18)*2) % 5;
63 | }
64 | return -1;
65 | }
66 |
67 | }
68 |
69 | class Android1BDynamic extends OneButtonDynamicFilter implements AndroidKeyMap {
70 |
71 | public Android1BDynamic(CDasherComponent creator, CDasherInterfaceBase iface) {
72 | super(creator, iface);
73 | }
74 |
75 | public int ConvertAndroidKeycode(int keyCode) {
76 | if (keyCode==KeyEvent.KEYCODE_MENU || keyCode==KeyEvent.KEYCODE_BACK || (keyCode>=19 && keyCode<=22))
77 | return -1; //don't intercept menu, back, or trackball movement (cursor) - too useful!
78 | return 1; //but anything else, treat the same!
79 | }
80 |
81 | }
82 |
83 | class AndroidMenuMode extends CMenuMode implements AndroidKeyMap {
84 |
85 | public AndroidMenuMode(CDasherComponent creator, CDasherInterfaceBase iface, String szName) {
86 | super(creator, iface, szName);
87 | }
88 |
89 | /** TODO need some preferences here for user to specify what keys to use...*/
90 | public int ConvertAndroidKeycode(int keyCode) {
91 | switch (keyCode) {
92 | //case KeyEvent.KEYCODE_DPAD_DOWN:
93 | case KeyEvent.KEYCODE_VOLUME_UP:
94 | case KeyEvent.KEYCODE_SPACE:
95 | return 1; //scan
96 | //case KeyEvent.KEYCODE_DPAD_RIGHT:
97 | case KeyEvent.KEYCODE_VOLUME_DOWN:
98 | case KeyEvent.KEYCODE_ENTER:
99 | return 2; //select
100 | }
101 | return -1;
102 | }
103 |
104 | }
105 |
106 | class AndroidDirectMode extends CButtonMode implements AndroidKeyMap {
107 |
108 | public AndroidDirectMode(CDasherComponent creator, CDasherInterfaceBase iface, String szName) {
109 | super(creator, iface, szName);
110 | }
111 |
112 | public int ConvertAndroidKeycode(int keyCode) {
113 | if (keyCode==KeyEvent.KEYCODE_0) return 1; //back i.e. zoom out
114 | if (keyCode>=KeyEvent.KEYCODE_1 && keyCode<=KeyEvent.KEYCODE_9) return keyCode-KeyEvent.KEYCODE_1+2; //2+ = select that box
115 | return -1;
116 | }
117 |
118 | }
--------------------------------------------------------------------------------
/src/dasher/android/CalibPreference.java:
--------------------------------------------------------------------------------
1 | package dasher.android;
2 |
3 | import java.util.List;
4 | import java.util.NoSuchElementException;
5 | import java.util.WeakHashMap;
6 |
7 | import android.content.Context;
8 | import android.content.DialogInterface;
9 | import android.content.SharedPreferences;
10 | import android.hardware.Sensor;
11 | import android.hardware.SensorEvent;
12 | import android.hardware.SensorEventListener;
13 | import android.hardware.SensorManager;
14 | import android.preference.DialogPreference;
15 | import android.util.AttributeSet;
16 | import android.view.View;
17 | import android.view.WindowManager;
18 | import android.view.View.OnClickListener;
19 | import android.widget.Button;
20 | import android.widget.CheckBox;
21 | import android.widget.CompoundButton;
22 | import android.widget.TextView;
23 | import android.widget.CompoundButton.OnCheckedChangeListener;
24 |
25 | public class CalibPreference extends DialogPreference implements SensorEventListener, OnClickListener {
26 | private static final String ANDROID_TILT_MAX_Y = "AndroidTiltMaxY";
27 | private static final String ANDROID_TILT_MIN_Y = "AndroidTiltMinY";
28 | private static final String ANDROID_TILT_MAX_X = "AndroidTiltMaxX";
29 | private static final String ANDROID_TILT_MIN_X = "AndroidTiltMinX";
30 |
31 | private static final WeakHashMap TILT_DEVICES = new WeakHashMap();
32 | public static void addTiltDevice(TiltInput ti) {TILT_DEVICES.put(ti,TILT_DEVICES);}
33 |
34 | private final SensorManager sm;
35 | private final WindowManager wm;
36 | private final Sensor s;
37 |
38 | private float minX,maxX,minY,maxY;
39 |
40 | private TextView calibX,calibY;
41 | private CheckBox chkInvert;
42 | private Button btnChange;
43 |
44 | public CalibPreference(Context context, AttributeSet attrs) {
45 | super(context, attrs);
46 | sm = (SensorManager)getContext().getSystemService(Context.SENSOR_SERVICE);
47 | List ss = sm.getSensorList(Sensor.TYPE_ACCELEROMETER);
48 | if (ss.isEmpty()) throw new NoSuchElementException("No sensors!");
49 | s=ss.get(0);
50 | wm = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
51 | }
52 |
53 | @Override
54 | public void onBindDialogView(View v) {
55 | btnChange = (Button)v.findViewById(R.id.calibChange);
56 | chkInvert = (CheckBox)v.findViewById(R.id.invert);
57 | btnChange.setOnClickListener(this);
58 | calibX = (TextView)v.findViewById(R.id.calibX);
59 | calibY = (TextView)v.findViewById(R.id.calibY);
60 | loadParams(getSharedPreferences());
61 | setLabels();
62 | }
63 |
64 | @Override public void onClick(DialogInterface dialog, int which) {
65 | if (which==DialogInterface.BUTTON1) {
66 | //ok clicked. Store current vals!
67 | SharedPreferences.Editor e = getEditor();
68 | e.putFloat(ANDROID_TILT_MIN_X, minX);
69 | e.putFloat(ANDROID_TILT_MAX_X, maxX);
70 | e.putFloat(ANDROID_TILT_MIN_Y, chkInvert.isChecked() ? maxY : minY);
71 | e.putFloat(ANDROID_TILT_MAX_Y, chkInvert.isChecked() ? minY : maxY);
72 | e.commit();
73 | //labels already set
74 | }
75 | if (!btnChange.isEnabled()) {
76 | //we started listening to sensor values...
77 | sm.unregisterListener(CalibPreference.this);
78 | if (which == DialogInterface.BUTTON2) {
79 | btnChange.setEnabled(true);
80 | loadParams(getSharedPreferences());
81 | setLabels();
82 | return; //don't dismiss
83 | }
84 | }
85 | super.onClick(dialog, which);
86 | }
87 |
88 | /** Update/reset cached minX/maxX/minY/maxY to reflect currently-stored preferences. */
89 | public void loadParams(SharedPreferences sp) {
90 | minX = sp.getFloat(ANDROID_TILT_MIN_X, -1.0f);
91 | maxX = sp.getFloat(ANDROID_TILT_MAX_X, 1.0f);
92 | minY = sp.getFloat(ANDROID_TILT_MIN_Y, 1.0f);
93 | maxY = sp.getFloat(ANDROID_TILT_MAX_Y, 9.0f);
94 | for (TiltInput ti : TILT_DEVICES.keySet())
95 | ti.setAxes(minX,maxX,minY,maxY);
96 | }
97 |
98 | /** Set captions of labels to reflect cached minX/maxX/minY/maxY */
99 | private void setLabels() {
100 | boolean invert;
101 | if (minY > maxY) {
102 | float temp = minY;
103 | minY = maxY;
104 | maxY = temp;
105 | invert = true;
106 | } else invert = false;
107 | calibX.setText( minX + " - " + maxX);
108 | calibY.setText(minY + " - " + maxY);
109 | chkInvert.setChecked(invert);
110 | }
111 |
112 | public void onSensorChanged(SensorEvent se) {
113 | float[] vals = se.values;
114 | if ((wm.getDefaultDisplay().getOrientation()&1)==1) {
115 | minX = Math.min(minX, vals[1]);
116 | maxX = Math.max(maxX, vals[1]);
117 | minY = Math.min(minY, vals[0]);
118 | maxY = Math.max(maxY, vals[0]);
119 | } else {
120 | minX = Math.min(minX,vals[0]);
121 | maxX = Math.max(maxX,vals[0]);
122 | minY = Math.min(minY, vals[1]);
123 | maxY = Math.max(maxY, vals[1]);
124 | }
125 | calibX.setText(minX+" - "+maxX);
126 | calibY.setText(minY+" - "+maxY);
127 | //no, don't update SharedPreferences
128 | }
129 |
130 | @Override public void onDismiss(DialogInterface v) {
131 | calibX = calibY = null;
132 | btnChange=null;
133 | chkInvert=null;
134 | }
135 |
136 | public void onAccuracyChanged(Sensor arg0, int arg1) {
137 | // TODO Auto-generated method stub
138 | }
139 |
140 | public void onClick(View v) {
141 | if (v!=btnChange) throw new AssertionError();
142 | btnChange.setEnabled(false);
143 | minX = minY = Float.MAX_VALUE;
144 | maxX = maxY = Float.MIN_VALUE;
145 | sm.registerListener(CalibPreference.this, s, SensorManager.SENSOR_DELAY_UI);
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/src/dasher/android/CheckBoxPreference.java:
--------------------------------------------------------------------------------
1 | package dasher.android;
2 |
3 | //import java.lang.ref.WeakReference;
4 |
5 | import android.content.Context;
6 | import android.content.SharedPreferences;
7 | import android.preference.PreferenceManager;
8 | import android.util.AttributeSet;
9 |
10 | /** Extend Android's default CheckBoxPreference to listen to changes
11 | * (to the value stored in SharedPreferences) that might come from
12 | * other sources. Hopefully this'll let us have multiple CheckBoxPreferences,
13 | * with the same key, at different points in the Preference screen hierarchy,
14 | * and keep them in sync...
15 | * @author Alan Lawrence
16 | */
17 | public class CheckBoxPreference extends android.preference.CheckBoxPreference implements SharedPreferences.OnSharedPreferenceChangeListener {
18 |
19 | public CheckBoxPreference(Context context, AttributeSet attrs) {
20 | super(context, attrs);
21 | //Handily, SharedPreferences already keeps its listeners in a WeakHashMap,
22 | // so registering as such does not prevent this from being GC'd; and when this
23 | // is GC'd, the WeakHashMap'll automatically deregister us.
24 | PreferenceManager.getDefaultSharedPreferences(context)
25 | .registerOnSharedPreferenceChangeListener(this);
26 | }
27 |
28 | public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
29 | if (key.equals(getKey())) {
30 | onSetInitialValue(true, null); //true = "get from sharedpreferences"
31 | }
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/dasher/android/DasherActivity.java:
--------------------------------------------------------------------------------
1 | package dasher.android;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.os.Handler;
7 | import android.provider.Settings;
8 | import android.view.View;
9 | import android.view.View.OnClickListener;
10 | import android.view.inputmethod.InputMethodInfo;
11 | import android.view.inputmethod.InputMethodManager;
12 | import android.widget.Button;
13 | import android.widget.EditText;
14 | import android.widget.TextView;
15 |
16 | public class DasherActivity extends Activity implements OnClickListener, Runnable {
17 |
18 | private TextView enabledLbl;
19 | private Button imeSettingsBtn;
20 | private TextView selectedLbl;
21 | private EditText longPress;
22 | private Button dasherSettingsButton;
23 |
24 | private String m_sID;
25 | private boolean bShownDasherSets;
26 | private Handler handler;
27 |
28 | @Override public void onCreate(Bundle savedInstanceState) {
29 | super.onCreate(savedInstanceState);
30 | setContentView(R.layout.install);
31 | enabledLbl = (TextView)findViewById(R.id.enable);
32 | imeSettingsBtn = (Button)findViewById(R.id.sys_sets_btn);
33 | imeSettingsBtn.setOnClickListener(this);
34 |
35 | selectedLbl = (TextView)findViewById(R.id.select);
36 | longPress = (EditText)findViewById(R.id.long_press);
37 | dasherSettingsButton = (Button)findViewById(R.id.dasher_sets_btn);
38 | dasherSettingsButton.setOnClickListener(this);
39 |
40 | handler = new Handler();
41 | }
42 |
43 | @Override public void onResume() {
44 | super.onResume();
45 | //1. is Dasher enabled?
46 | m_sID = null;
47 | InputMethodManager imm = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
48 | for (InputMethodInfo inf : imm.getEnabledInputMethodList()) {
49 | if (inf.getPackageName().equals(this.getPackageName())
50 | && inf.getServiceName().equals(DasherInputMethod.class.getName())) {
51 | m_sID=inf.getId(); break;
52 | }
53 | }
54 |
55 | if (m_sID==null) {
56 | enabledLbl.setText(R.string.DasherNeedsEnable);
57 | imeSettingsBtn.setEnabled(true);
58 | } else {
59 | enabledLbl.setText(R.string.DasherEnabledOk);
60 | imeSettingsBtn.setEnabled(false);
61 | }
62 | run();
63 | }
64 |
65 | /** Executed on UI Thread, either directly from onResume()
66 | or as a callback via handler.postDelayed(). */
67 | public void run() {
68 | //2. is Dasher the active input method?
69 | if (m_sID!=null &&
70 | Settings.Secure.getString(getContentResolver(),
71 | Settings.Secure.DEFAULT_INPUT_METHOD).equals(m_sID)) {
72 |
73 | selectedLbl.setText(R.string.DasherSelectedOk);
74 | longPress.setEnabled(false);
75 | //go straight to settings, once
76 | if (!bShownDasherSets) {
77 | bShownDasherSets=true;
78 | onClick(dasherSettingsButton);
79 | }
80 | } else {
81 | selectedLbl.setText(R.string.DasherNeedsSelect);
82 | longPress.setEnabled(true);
83 | }
84 | handler.postDelayed(this,500);
85 | }
86 |
87 | @Override public void onPause() {
88 | handler.removeCallbacks(this);
89 | super.onPause();
90 | }
91 |
92 | public void onClick(View v) {
93 | if (v == imeSettingsBtn)
94 | startActivity(new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS));
95 | else if (v==dasherSettingsButton)
96 | startActivity(new Intent(this,SettingsActivity.class));
97 | }
98 |
99 | }
--------------------------------------------------------------------------------
/src/dasher/android/DualIMCheckBox.java:
--------------------------------------------------------------------------------
1 | package dasher.android;
2 |
3 | import dasher.Esp_parameters;
4 | import android.content.Context;
5 | import android.content.SharedPreferences;
6 | import android.preference.CheckBoxPreference;
7 | import android.preference.Preference;
8 | import android.preference.PreferenceManager;
9 | import android.preference.PreferenceScreen;
10 | import android.util.AttributeSet;
11 |
12 | public class DualIMCheckBox extends IMCheckBox {
13 | private final String inputDevOn,inputDevOff;
14 | private final String inputFilOn,inputFilOff;
15 | private final String childKey;
16 |
17 | public DualIMCheckBox(Context ctx, AttributeSet attrs) {
18 | super(ctx, attrs);
19 | childKey = attrs.getAttributeValue(null, "childKey");
20 | inputDevOn = getAttribute(attrs,"inputDeviceOn","inputDevice");
21 | inputDevOff= getAttribute(attrs,"inputDeviceOff","inputDevice");
22 | inputFilOn= getAttribute(attrs,"inputFilterOn","inputFilter");
23 | inputFilOff = getAttribute(attrs,"inputFilterOff","inputFilter");
24 | CheckBoxPreference cb = (CheckBoxPreference)ps.findPreference(childKey);
25 | cb.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
26 |
27 | public boolean onPreferenceChange(Preference preference, Object newValue) {
28 | DualIMCheckBox.this.setInputsForChildChecked(((Boolean)newValue).booleanValue());
29 | return true; //allow
30 | }
31 | });
32 | }
33 |
34 | private static String getAttribute(AttributeSet attrs, String fst, String snd) {
35 | String res = attrs.getAttributeValue(null,fst);
36 | if (res!=null) return res;
37 | return attrs.getAttributeValue(null, snd);
38 | }
39 |
40 | @Override protected void hasBecomeChecked() {
41 | super.hasBecomeChecked();
42 | setInputsForChildChecked(PreferenceManager.getDefaultSharedPreferences(getContext()).getBoolean(childKey, false));
43 | }
44 |
45 | public void setInputsForChildChecked(boolean b) {
46 | String d,f;
47 | if (b) {
48 | d=inputDevOn; f=inputFilOn;
49 | } else {
50 | d=inputDevOff; f=inputFilOff;
51 | }
52 | //writing to the persistent settings store will trigger an
53 | // OnSharedPreferencesChanged listener in the main/IME service
54 | // (if its active) which will update the in-memory parameters
55 | // there. (Using an AndroidSettings might be more modular, but
56 | // would entail reading all settings into memory every time!)
57 | SharedPreferences.Editor edit = PreferenceManager.getDefaultSharedPreferences(getContext()).edit();
58 | edit.putString(Esp_parameters.SP_INPUT_DEVICE.regName(), d);
59 | edit.putString(Esp_parameters.SP_INPUT_FILTER.regName(), f);
60 | edit.commit();
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/src/dasher/android/IMCheckBox.java:
--------------------------------------------------------------------------------
1 | package dasher.android;
2 |
3 | import java.lang.ref.WeakReference;
4 | import java.util.HashSet;
5 | import java.util.Iterator;
6 | import java.util.Set;
7 |
8 | import android.content.Context;
9 | import android.content.SharedPreferences;
10 | import android.preference.Preference;
11 | import android.preference.PreferenceManager;
12 | import android.preference.PreferenceScreen;
13 | import android.util.AttributeSet;
14 | import android.widget.CheckBox;
15 |
16 | public abstract class IMCheckBox extends CheckBox {
17 |
18 | protected static final String androidns = "http://schemas.android.com/apk/res/android";
19 | public static final String SETTING = "AndroidInputMethod";
20 | private static final Set> BOXES = new HashSet>();
21 | private final String key;
22 |
23 | protected IMCheckBox(Context ctx, AttributeSet attrs) {
24 | super(ctx,attrs);
25 | key = attrs.getAttributeValue(androidns, "key");
26 | BOXES.add(new WeakReference(this));
27 | ((PreferenceScreen)ps.findPreference(key)).setOnPreferenceClickListener(lstnr);
28 | }
29 |
30 | @Override public void onFinishInflate() {
31 | super.onFinishInflate();
32 | setChecked(PreferenceManager.getDefaultSharedPreferences(getContext()).getString(SETTING,"_"+key).equals(key));
33 | }
34 |
35 | @Override public final void setChecked(boolean b) {
36 | if (isChecked()==b) return;
37 | super.setChecked(b);
38 | if (b) hasBecomeChecked();
39 | }
40 |
41 | public static void set(String key) {
42 | for (Iterator> it=BOXES.iterator(); it.hasNext();) {
43 | WeakReference wr = it.next();
44 | IMCheckBox r = wr.get();
45 | if (r==null)
46 | it.remove();
47 | else
48 | r.setChecked(r.key.equals(key));
49 | }
50 | }
51 |
52 | public static void setPrefScreen(PreferenceScreen _ps) {ps=_ps;}
53 | protected static PreferenceScreen ps;
54 |
55 | protected void hasBecomeChecked() {
56 | SharedPreferences.Editor edit = PreferenceManager.getDefaultSharedPreferences(getContext()).edit();
57 | edit.putString(SETTING, key);
58 | edit.commit();
59 | }
60 |
61 | public String toString() {return getClass().getName()+" w/ key "+key;}
62 |
63 | private static final Preference.OnPreferenceClickListener lstnr = new Preference.OnPreferenceClickListener() {
64 | public boolean onPreferenceClick(Preference pref) {
65 | IMCheckBox.set(pref.getKey());
66 | return false; //allow normal click action to occur too
67 | }
68 | };
69 |
70 | }
--------------------------------------------------------------------------------
/src/dasher/android/InputTypes.java:
--------------------------------------------------------------------------------
1 | package dasher.android;
2 |
3 | import java.lang.reflect.Field;
4 |
5 | import android.text.InputType;
6 | import android.view.inputmethod.EditorInfo;
7 |
8 | /** Utility class for interpreting the inputType field of an EditorInfo */
9 | public class InputTypes {
10 | /** The class names are the fields TYPE_CLASS_XYZ of
11 | * android.text,InputType; among thosefields, this routine
12 | * identifies that with the value corresponding to the inputType
13 | * parameter (masked with TYPE_MASK_CLASS)
14 | * @param inputType value of field of same name of EditorInfo
15 | * @return the XYZ part of the name of the identified field
16 | * @throws IllegalArgumentException if no appropriately-named field
17 | * with the correct value could be found.
18 | */
19 | public static String getClassName(EditorInfo info) {
20 | if (info.inputType==InputType.TYPE_NULL) return "NULL"; //inputType==0 is a common case...
21 | int i = info.inputType & InputType.TYPE_MASK_CLASS;
22 | for (Field f : InputType.class.getFields())
23 | try {
24 | if (f.getName().startsWith("TYPE_CLASS_")
25 | && f.getInt(null)==i)
26 | return f.getName().substring("TYPE_CLASS_".length());
27 | } catch (IllegalAccessException e) {
28 | //Shouldn't happen, but hope some other field matches!
29 | android.util.Log.d("DasherIME","Couldn't read field "+f.getName()+", skipping...", e);
30 | }
31 | throw new IllegalArgumentException("InputType class "+info.inputType+" not found");
32 | }
33 |
34 | /**
35 | * The variations of classname ABC (see {@link #getClassName(int)}
36 | * are stored in the fields TYPE_ABC_VARIATION_XYZ of android.text.InputType;
37 | * this routine identifies the field with value corresponding to the
38 | * inputType parameter (masked with TYPE_MASK_VARIATION)
39 | * @param inputType the value of the inputType field of the EditorInfo object
40 | * (both classname and variation parts are used)
41 | * @return the XYZ part of the name of the identified field
42 | * @throws IllegalArgumentException if no appropriately-named field
43 | * with the correct value could be found, or similarly, if the
44 | * classname of the provided inputType could not be identified.
45 | */
46 | public static String getVariationName(EditorInfo info) {
47 | if (info.inputType == InputType.TYPE_NULL) return "NULL";
48 | String s = getDesc(info);
49 | return s.substring(s.indexOf(".")+1);
50 | }
51 |
52 | public static String getDesc(EditorInfo info) {
53 | String className = getClassName(info);
54 | String varPrefix = "TYPE_"+className+"_VARIATION_";
55 | if (info.inputType==InputType.TYPE_NULL) return "NULL";
56 | int i = info.inputType & InputType.TYPE_MASK_VARIATION;
57 | for (Field f : InputType.class.getFields())
58 | try {
59 | if (f.getName().startsWith(varPrefix)
60 | && f.getInt(null)==i)
61 | return className+"."+f.getName().substring(varPrefix.length());
62 | } catch (IllegalAccessException e) {
63 | //Shouldn't happen, but hope some other field matches!
64 | android.util.Log.d("DasherIME","Couldn't read field "+f.getName()+", skipping...", e);
65 | }
66 | return className+".NORMAL";
67 | }
68 |
69 | /** Determines whether the specified inputType indicates a hidden
70 | * (password) field. Checks against known values (at present only
71 | * TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_PASSWORD, as only these are
72 | * present in earlier versions of Android - we could hardcode in others,
73 | * but then would no longer compile for Android 1.6), and then also
74 | * looks for any variation of any class whose name (obtained by
75 | * {@link #getVariationName(int)}) contains the string "PASSWORD".
76 | * @param inputType value of the inputType field of the EditorInfo object
77 | * @return true if this indicates a password.
78 | */
79 | public static boolean isPassword(EditorInfo info) {
80 | final int inputType = info.inputType;
81 | if ((inputType & InputType.TYPE_MASK_CLASS) == InputType.TYPE_CLASS_TEXT
82 | && (inputType & InputType.TYPE_MASK_VARIATION) == InputType.TYPE_TEXT_VARIATION_PASSWORD)
83 | return true;
84 | return getVariationName(info).contains("PASSWORD");
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/dasher/android/IntQueue.java:
--------------------------------------------------------------------------------
1 | package dasher.android;
2 |
3 | public class IntQueue {
4 | private int[] data=new int[4];
5 | private int front; //next idx to push
6 | private int back; //next idx to pop
7 |
8 | public void push(int i) {
9 | if ((front+1) % data.length == back) {
10 | int[] ndata = new int[data.length*2];
11 | if (front>back) {
12 | System.arraycopy(data, back, ndata, 0, front-back);
13 | front-=back;
14 | } else {
15 | System.arraycopy(data, back, ndata, 0, data.length-back);
16 | System.arraycopy(data, 0, ndata, data.length-back, front);
17 | front += data.length-back;
18 | }
19 | data=ndata;
20 | back=0;
21 | }
22 | data[front++]=i;
23 | if (front==data.length) front=0;
24 | }
25 |
26 | public int pop() {
27 | if (front==back) throw new IndexOutOfBoundsException("Empty");
28 | int res = data[back++];
29 | if (back==data.length) back=0;
30 | return res;
31 | }
32 |
33 | public int size() {
34 | return (front+data.length-back) % data.length;
35 | }
36 |
37 | /*public static void main(String[] args) {
38 | IntQueue q=new IntQueue();
39 | for (int i=0; i<50; i++) {
40 | q.push(i);
41 | if ((i&1)==1) System.out.print("Pop "+q.pop());
42 | System.out.println(" now "+q.size()+" items");
43 | }
44 | while (q.size()>0) System.out.println("Pop "+q.pop()+" now "+q.size()+" items");
45 | q=new IntQueue();
46 | for (int i=0; i<100; i++) {
47 | q.push(i);
48 | if (i>2) System.out.print("Pop "+q.pop());
49 | System.out.println(" now "+q.size()+" items");
50 | }
51 | }*/
52 | }
53 |
--------------------------------------------------------------------------------
/src/dasher/android/SeekBarPreference.java:
--------------------------------------------------------------------------------
1 | /* The following code was written by Matthew Wiggins
2 | * and is released under the APACHE 2.0 license
3 | *
4 | * http://www.apache.org/licenses/LICENSE-2.0
5 | */
6 | package dasher.android;
7 |
8 | import dasher.EParameters;
9 | import dasher.Elp_parameters;
10 | import android.content.Context;
11 | import android.content.DialogInterface;
12 | import android.content.SharedPreferences;
13 | import android.util.AttributeSet;
14 | import android.view.Gravity;
15 | import android.view.View;
16 | import android.preference.DialogPreference;
17 | import android.preference.PreferenceManager;
18 | import android.widget.Button;
19 | import android.widget.SeekBar;
20 | import android.widget.TextView;
21 | import android.widget.LinearLayout;
22 |
23 |
24 | public class SeekBarPreference extends DialogPreference implements SeekBar.OnSeekBarChangeListener, View.OnClickListener, SharedPreferences.OnSharedPreferenceChangeListener
25 | {
26 | private static final String androidns="http://schemas.android.com/apk/res/android";
27 |
28 | private SeekBar mSeekBar;
29 | private TextView mValueText;
30 |
31 | private final String mSuffix, mTitle;
32 | private final long lDef;
33 | private int lMin, lMax, lDiv;
34 | private long lValue;
35 |
36 | public SeekBarPreference(Context context, AttributeSet attrs) {
37 | super(context,attrs);
38 | String temp=attrs.getAttributeValue(androidns, "title");
39 | if (temp.startsWith("@")) {
40 | try {
41 | temp = getContext().getResources().getString(Integer.parseInt(temp.substring(1)));
42 | } catch (NumberFormatException e) {
43 | //hmm. any ideas?
44 | }
45 | }
46 | mTitle=temp;
47 | if (!isPersistent() || !hasKey()) throw new IllegalArgumentException("Non-persistent attribute "+mTitle);
48 | mSuffix = attrs.getAttributeValue(androidns,"text");
49 | Elp_parameters param = (Elp_parameters)EParameters.BY_NAME.get(getKey());
50 | lDef = (param==null) ? attrs.getAttributeIntValue(androidns,"defaultValue", 0) : param.defaultVal;
51 | lMax = attrs.getAttributeIntValue(androidns,"max", 100);
52 | lMin = attrs.getAttributeIntValue(null, "min", 0);
53 | lDiv = attrs.getAttributeIntValue(null, "divisor", 1);
54 | //Handily, SharedPreferences already keeps its listeners in a WeakHashMap,
55 | // so registering as such does not prevent this from being GC'd; and when this
56 | // is GC'd, the WeakHashMap'll automatically deregister us.
57 | PreferenceManager.getDefaultSharedPreferences(context)
58 | .registerOnSharedPreferenceChangeListener(this);
59 | }
60 |
61 | public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
62 | if (key.equals(getKey())) {
63 | onSetInitialValue(true, null); //true = "get from sharedpreferences"
64 | updateTitle();
65 | }
66 | }
67 |
68 | @Override public void onAttachedToHierarchy(PreferenceManager pm) {
69 | super.onAttachedToHierarchy(pm);
70 | lValue = getPersistedLong(lDef);
71 | updateTitle();
72 | }
73 |
74 | @Override
75 | protected View onCreateDialogView() {
76 | LinearLayout layout = new LinearLayout(getContext());
77 | layout.setOrientation(LinearLayout.VERTICAL);
78 | layout.setPadding(6,6,6,6);
79 |
80 | mValueText = new TextView(getContext());
81 | mValueText.setGravity(Gravity.CENTER_HORIZONTAL);
82 | mValueText.setTextSize(32);
83 |
84 | mSeekBar = new SeekBar(getContext());
85 | mSeekBar.setOnSeekBarChangeListener(this);
86 | layout.addView(mSeekBar, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
87 |
88 | mSeekBar.setMax(lMax-lMin);
89 | //onBindDialogView sets current value (=>calls onProgressChanged =>sets mValueText)
90 |
91 | layout.addView(mValueText, new LinearLayout.LayoutParams(
92 | LinearLayout.LayoutParams.FILL_PARENT,
93 | LinearLayout.LayoutParams.WRAP_CONTENT));
94 | Button b = new Button(getContext());
95 | b.setText(R.string.Reset);
96 | b.setOnClickListener(this);
97 | //hope a click on b comes through to onClick(DialogInterface, int) - but with what int?!
98 | layout.addView(b);
99 | return layout;
100 | }
101 |
102 | @Override
103 | protected void onBindDialogView(View v) {
104 | super.onBindDialogView(v);
105 | mSeekBar.setProgress((int)(lValue-lMin));
106 | }
107 |
108 | @Override protected void onSetInitialValue(boolean restore, Object defaultValue) {
109 | super.onSetInitialValue(restore, defaultValue);
110 | if (restore) //"use settings store" - defaultValue==null !
111 | lValue = getPersistedLong(lDef);
112 | else //"don't use settings store" - there's a default here instead
113 | lValue = ((Number)defaultValue).longValue();
114 | }
115 |
116 | public void onProgressChanged(SeekBar seek, int value, boolean fromTouch) {
117 | if (fromTouch) {
118 | lValue = value+lMin;
119 | callChangeListener(new Integer(value));
120 | }
121 | String t=valueText();
122 | mValueText.setText(mSuffix==null ? t : t.concat(mSuffix));
123 | }
124 |
125 | private String valueText() {
126 | return (lDiv==1) ? String.valueOf(lValue) : String.valueOf(lValue/(double)lDiv);
127 | }
128 |
129 | private void updateTitle() {
130 | setTitle(mTitle+": "+valueText());
131 | }
132 | @Override public void onClick(DialogInterface dialog, int button) {
133 | if (button==DialogInterface.BUTTON_POSITIVE) {
134 | //ok button. Store result of sliding, and set the title text
135 | persistLong(lValue);
136 | updateTitle();
137 | } else if (button==DialogInterface.BUTTON_NEGATIVE){
138 | //cancel button. Restore old value, leave title text alone.
139 | lValue = getPersistedLong(lDef);
140 | } else {
141 | android.util.Log.d("DasherPrefs","Unknown button "+button+" pressed for "+getKey());
142 | }
143 | }
144 |
145 | public void onClick(View v) {
146 | //reset button
147 | lValue = ((Elp_parameters)EParameters.BY_NAME.get(getKey())).defaultVal;
148 | mSeekBar.setProgress((int)(lValue-lMin));
149 | }
150 |
151 | public void onStartTrackingTouch(SeekBar seekBar) {}
152 |
153 | public void onStopTrackingTouch(SeekBar seekBar) {}
154 |
155 | }
--------------------------------------------------------------------------------
/src/dasher/android/SettingsActivity.java:
--------------------------------------------------------------------------------
1 | package dasher.android;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 | import java.util.Collections;
6 | import java.util.ListIterator;
7 |
8 | import android.os.Bundle;
9 | import android.preference.ListPreference;
10 | import android.preference.PreferenceActivity;
11 | import android.util.Log;
12 | import dasher.CDasherInterfaceBase;
13 | import dasher.Esp_parameters;
14 |
15 | public class SettingsActivity extends PreferenceActivity {
16 | /** Called when the activity is first created. */
17 | @Override
18 | public void onCreate(Bundle savedInstanceState) {
19 | super.onCreate(savedInstanceState);
20 |
21 | //We need a DasherInterface to parse alphabet/colour files and find the
22 | //available schemes (in future perhaps also input filters, although
23 | // atm the available options there are hardcoded into prefs.xml).
24 | //However our Interface doesn't need to implement display, editing, etc.
25 | // functions, so we stub those methods. (Also it will never load a
26 | // training text.)
27 | CDasherInterfaceBase intf = new ADasherInterface(this,false);
28 |
29 | addPreferencesFromResource(R.layout.prefs);
30 |
31 | IMCheckBox.setPrefScreen(getPreferenceScreen());
32 |
33 | addPermittedValues(intf, Esp_parameters.SP_ALPHABET_ID);
34 | addPermittedValues(intf, Esp_parameters.SP_COLOUR_ID);
35 | }
36 |
37 | private void addPermittedValues(CDasherInterfaceBase intf, Esp_parameters param) {
38 | List values = new ArrayList();
39 | ListPreference lp = (ListPreference)getPreferenceScreen().findPreference(param.regName());
40 | intf.GetPermittedValues(param,values);
41 | Collections.sort(values);
42 | CharSequence[] vals = new CharSequence[values.size()];
43 | int i=0;
44 | for (String s : values) {
45 | vals[i++] = s;
46 | }
47 | lp.setEntries(vals);
48 | lp.setEntryValues(vals);
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/src/dasher/android/SingleIMCheckBox.java:
--------------------------------------------------------------------------------
1 | package dasher.android;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 | import android.preference.PreferenceManager;
6 | import android.util.AttributeSet;
7 |
8 | import dasher.Esp_parameters;
9 |
10 | public class SingleIMCheckBox extends IMCheckBox {
11 |
12 | private final String inputDevice;
13 | private final String inputFilter;
14 |
15 | public SingleIMCheckBox(Context ctx, AttributeSet attrs) {
16 | super(ctx,attrs);
17 | inputDevice = attrs.getAttributeValue(null,"inputDevice");
18 | inputFilter = attrs.getAttributeValue(null,"inputFilter");
19 | }
20 |
21 | @Override protected void hasBecomeChecked() {
22 | super.hasBecomeChecked();
23 | //writing to the persistent settings store will trigger an
24 | // OnSharedPreferencesChanged listener in the main/IME service
25 | // (if its active) which will update the in-memory parameters
26 | // there. (Using an AndroidSettings might be more modular, but
27 | // would entail reading all settings into memory every time!)
28 | SharedPreferences.Editor edit = PreferenceManager.getDefaultSharedPreferences(getContext()).edit();
29 | edit.putString(Esp_parameters.SP_INPUT_DEVICE.regName(), inputDevice);
30 | edit.putString(Esp_parameters.SP_INPUT_FILTER.regName(), inputFilter);
31 | edit.commit();
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/dasher/android/TiltInput.java:
--------------------------------------------------------------------------------
1 | package dasher.android;
2 |
3 | import java.util.List;
4 |
5 | import android.content.Context;
6 | import android.content.SharedPreferences;
7 | import android.hardware.Sensor;
8 | import android.hardware.SensorEvent;
9 | import android.hardware.SensorEventListener;
10 | import android.hardware.SensorManager;
11 | import android.preference.PreferenceManager;
12 | import android.util.Log;
13 | import android.view.WindowManager;
14 | import dasher.CDasherInput;
15 | import dasher.CDasherView;
16 |
17 | public class TiltInput extends CDasherInput implements SensorEventListener {
18 | private final SensorManager sm;
19 | private final WindowManager wm;
20 |
21 | /** Last (/current) values of tilt position, as floats in (0,1) */
22 | private float fx,fy;
23 | /** X & Y values from h/w tilt sensor are multiplied by these scales, then offsets added */
24 | private float y_mul, y_off, x_mul, x_off;
25 |
26 | public void setAxes(float minX, float maxX, float minY, float maxY) {
27 | y_mul = 1.0f/(maxY-minY); this.y_off = minY/(maxY-minY); //these may be inverted (min > max)
28 | x_mul = 1.0f/(minX-maxX); this.x_off = maxX/(minX-maxX); //these we definitely expect to be inverted!
29 | }
30 |
31 | private boolean bActive;
32 | private final Sensor s;
33 |
34 | public static TiltInput MAKE(Context androidCtx) {
35 | SensorManager sm=(SensorManager)androidCtx.getSystemService(Context.SENSOR_SERVICE);
36 | WindowManager wm = (WindowManager)androidCtx.getSystemService(Context.WINDOW_SERVICE);
37 | List ss = sm.getSensorList(Sensor.TYPE_ACCELEROMETER);
38 | if (ss.isEmpty()) return null;
39 | TiltInput ti = new TiltInput(sm, ss.get(0),wm);
40 | CalibPreference.addTiltDevice(ti);
41 | return ti;
42 | }
43 |
44 | private TiltInput(SensorManager sm, Sensor s, WindowManager wm) {
45 | super("Tilt Input");
46 | this.sm=sm;
47 | this.s=s;
48 | this.wm=wm;
49 | }
50 |
51 | @Override public void Activate() {
52 | if (bActive) return;
53 | bActive=true;
54 | sm.registerListener(this, s, SensorManager.SENSOR_DELAY_UI);
55 | }
56 |
57 | @Override public void Deactivate() {
58 | if (!bActive) return;
59 | bActive=false;
60 | sm.unregisterListener(this,s);
61 | }
62 |
63 | public void onAccuracyChanged(Sensor sensor, int accuracy) {}
64 | private int m_iLastOrient;
65 | public void onSensorChanged(SensorEvent event) {
66 | float[] vals=event.values;
67 | /*StringBuilder sb=new StringBuilder();
68 | for (int i=0; i
19 |
20 | JDasher is a port derived from the Dasher project; for information on
21 | the project see www.dasher.org.uk; for information on JDasher itself
22 | and related projects see www.smowton.net/chris
23 |
24 | */
25 |
26 | package dasher.applet;
27 |
28 | import java.util.ListIterator;
29 | import java.util.NoSuchElementException;
30 |
31 | import javax.swing.event.CaretEvent;
32 | import javax.swing.event.CaretListener;
33 | import javax.swing.text.BadLocationException;
34 | import javax.swing.JTextArea;
35 |
36 | import dasher.CDasherInterfaceBase;
37 | import dasher.EditableDocument;
38 |
39 | /**
40 | * JDasherEdit is essentially an ordinary JTextArea with methods to deal with
41 | * outputting/deleting text for Dasher and which listens to caret updates
42 | * from Swing to rebuild the Dasher tree accordingly.
43 | */
44 | public class JDasherEdit extends JTextArea implements CaretListener, EditableDocument {
45 |
46 | /**
47 | * Interface which this EditBox will control when text is
48 | * entered, typically by calling InvalidateContext if the
49 | * user manually edits the text.
50 | */
51 | private dasher.CDasherInterfaceBase m_Interface;
52 |
53 | /**
54 | * Creates a new EditBox with a given width and height in characters,
55 | * which will inform the given interface if the cursor is moved.
56 | *
57 | * @param rows EditBox width in characters
58 | * @param cols EditBox height in characters
59 | * @param intf Interface to control; must not be null
60 | * @throws IllegalArgumentException if
intf
is null.
61 | */
62 | public JDasherEdit(int rows, int cols, dasher.CDasherInterfaceBase intf) {
63 | super(rows, cols);
64 | m_Interface = intf;
65 |
66 | this.addCaretListener(this);
67 | }
68 |
69 | /* Handle output of text by the using entering a new DasherNode.
70 | * If text is added whilst there is a selection, we delete it
71 | * just as if the user had typed over the selection.
72 | */
73 | public void outputText(String ch, int offset) {
74 | if(this.getSelectedText()!=null) {
75 | this.replaceSelection("");
76 | }
77 | int oldCaret = this.getCaretPosition();
78 | this.insert(ch, oldCaret);
79 | this.setCaretPosition(oldCaret + 1);
80 | }
81 |
82 | /** Handle deletion of text (from reversing) by removing a character.
83 | * Deleting whilst something is selected removes both the selection and its
84 | * preceding character.
85 | */
86 | public void deleteText(String ch, int offset) {
87 | if(!this.getText().equals("")) {
88 |
89 | if(this.getSelectedText()!=null) {
90 | this.replaceSelection("");
91 | }
92 | int oldCaret = this.getCaretPosition();
93 | this.replaceRange("", oldCaret - ch.length(), oldCaret);
94 | setCaretPosition(oldCaret - ch.length());
95 | }
96 | }
97 |
98 | @Override
99 | public void moveCursor(int pos) {
100 | setCaretPosition(pos+1);
101 | }
102 |
103 | /** Gets the context, i.e. characters in the editbox,
104 | * starting at the specified position
105 | * @param StartPosition 0-based index of the character AFTER which the cursor is placed
106 | * @return
107 | */
108 | ListIterator getContext(final int StartPosition) {
109 | return new ListIterator() {
110 | /**0-based index of the character after which the cursor is*/
111 | int idx=StartPosition;
112 | /** The character after the cursor*/
113 | public Character next() {
114 | //if cursor is after char 0 (the first char), we should return char 1
115 | try {return getText(++idx,1).charAt(0);}
116 | catch (BadLocationException e) {idx--;
117 | throw new NoSuchElementException();
118 | }
119 | }
120 | public boolean hasNext() {return idx=0;}
130 | public int previousIndex() {return idx;}
131 | public void add(Character o) {throw new UnsupportedOperationException();}
132 | public void remove() {throw new UnsupportedOperationException();}
133 | public void set(Character o) {throw new UnsupportedOperationException();}
134 | };
135 | }
136 |
137 |
138 | /**
139 | * Called by Java's event handling subsystem when the user moves
140 | * the caret, either by typing or clicking.
141 | *
142 | * We call through to {@link CDasherInterfaceBase#setOffset} to update the model
143 | * if the new cursor location is different from where the model thinks it should be.
144 | * (This is the case if the user has moved the cursor, but if the call to caretUpdate
145 | * is in response to Dasher entering text itself, the model will already be in the
146 | * right position.)
147 | */
148 | public void caretUpdate(CaretEvent e) {
149 |
150 | m_Interface.setOffset(getSelectionStart()-1, false);
151 |
152 | }
153 |
154 | @Override
155 | public Character getCharAt(int pos) {
156 | String s = getText();
157 | if (pos>=s.length()) return null;
158 | return s.charAt(pos);
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/src/dasher/applet/JDasherMenuBarListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of JDasher.
3 |
4 | JDasher is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | JDasher is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with JDasher; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | Copyright (C) 2006 Christopher Smowton
19 |
20 | JDasher is a port derived from the Dasher project; for information on
21 | the project see www.dasher.org.uk; for information on JDasher itself
22 | and related projects see www.smowton.net/chris
23 |
24 | */
25 |
26 | package dasher.applet;
27 |
28 | import java.util.Collection;
29 |
30 | import dasher.Ebp_parameters;
31 | import dasher.Elp_parameters;
32 | import dasher.Esp_parameters;
33 |
34 | /**
35 | * Interface which must be implemented by all classes that wish
36 | * to hear about events spawned by the JDasherMenuBar.
37 | *
38 | * The functions will each be called when the menu item corresponding
39 | * to their name is invoked.
40 | */
41 | public interface JDasherMenuBarListener {
42 |
43 | public void menuNew();
44 |
45 | public void menuCut();
46 |
47 | public void menuCopy();
48 |
49 | public void menuPaste();
50 |
51 | public void menuExit();
52 |
53 | public void menuSelFont();
54 |
55 | public void menuHelpAbout();
56 |
57 | // For clipboard control
58 | public boolean isDataFlavorAvailable(java.awt.datatransfer.DataFlavor flavour);
59 |
60 | public void menuSetString(Esp_parameters param, String val);
61 | public void menuSetLong(Elp_parameters param, long val);
62 | public void menuSetBool(Ebp_parameters param, boolean val);
63 | }
64 |
--------------------------------------------------------------------------------
/src/dasher/applet/JMouseInput.java:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of JDasher.
3 |
4 | JDasher is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | JDasher is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with JDasher; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | Copyright (C) 2006 Christopher Smowton
19 |
20 | JDasher is a port derived from the Dasher project; for information on
21 | the project see www.dasher.org.uk; for information on JDasher itself
22 | and related projects see www.smowton.net/chris
23 |
24 | */
25 |
26 | package dasher.applet;
27 |
28 | import java.awt.event.*;
29 |
30 | import dasher.CDasherView;
31 | import dasher.CDasherView.MutablePoint;
32 |
33 | /**
34 | * Simple mouse input device which uses a mouse motion listener to
35 | * track the mouse position and reports the latest reading when
36 | * GetCoordinates is called.
37 | *
38 | * Only methods which differ significantly from their abstract meanings
39 | * documented in CDasherInput are documented here; for further details
40 | * see CDasherInput.
41 | */
42 | public class JMouseInput extends dasher.CDasherInput implements MouseMotionListener {
43 |
44 | /**
45 | * Last seen mouse X co-ordinate
46 | */
47 | private int mouseX;
48 |
49 | /**
50 | * Last seen mouse Y co-ordinate
51 | */
52 | private int mouseY;
53 |
54 | public JMouseInput() {
55 | super("Mouse Input");
56 | }
57 |
58 | /**
59 | * Calls through to mouseMoved - as this gets called in place of the former, if a button is being held down...
60 | */
61 | public void mouseDragged(MouseEvent e) {
62 | mouseMoved(e);
63 | }
64 |
65 | /**
66 | * Stores the last seen mouse coordinates.
67 | */
68 | public void mouseMoved(MouseEvent e) {
69 | mouseX = e.getX();
70 | mouseY = e.getY();
71 | }
72 |
73 | @Override
74 | public boolean GetScreenCoords(CDasherView pView, MutablePoint into) {
75 | into.init(mouseX, mouseY);
76 | return true;
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/src/dasher/applet/JSettings.java:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of JDasher.
3 |
4 | JDasher is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | JDasher is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with JDasher; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | Copyright (C) 2006 Christopher Smowton
19 |
20 | JDasher is a port derived from the Dasher project; for information on
21 | the project see www.dasher.org.uk; for information on JDasher itself
22 | and related projects see www.smowton.net/chris
23 |
24 | */
25 |
26 | package dasher.applet;
27 |
28 | import java.security.AccessControlException;
29 | import java.util.prefs.Preferences;
30 |
31 | import dasher.CParameterNotFoundException;
32 | import dasher.CSettingsStore;
33 |
34 | /**
35 | * Extension of CSettingsStore which uses a Java Preferences
36 | * object to store settings between sessions.
37 | *
38 | * This boils down to using the registry in Windows, and a hidden
39 | * file in the user's profile on Unix-style systems including
40 | * MacOSX.
41 | *
42 | * In the current unsigned applet setup this will not get used,
43 | * as a security exception is thrown on trying to instantiate
44 | * Preferences and a plain old CSettingsStore will be used in lieu.
45 | *
46 | * Should JDasher ever get converted to a standalone Java application
47 | * or signed applet, however, this will spring into life and provide
48 | * persistent settings.
49 | *
50 | * I have not documented these functions, as they all implement
51 | * precisely the behaviour specified in CSettingsStore.
52 | *
53 | * The only noteworthy feature is that the Constructor will throw
54 | * a StoreUnavailableException if unable to open the registry
55 | * and/or user profile.
56 | */
57 | public class JSettings extends CSettingsStore {
58 |
59 | private Preferences appSettings;
60 |
61 | public JSettings() throws StoreUnavailableException {
62 | try {
63 | appSettings = Preferences.userRoot();
64 | }
65 | catch(AccessControlException e) {
66 | throw new StoreUnavailableException();
67 | }
68 | LoadPersistent();
69 | }
70 |
71 |
72 | protected boolean LoadBoolSetting(String Key) throws CParameterNotFoundException {
73 |
74 | /* CSFS: This annoying hack is to work around the fact that any
75 | * failure to return a value is responded to by returning the default!
76 | */
77 |
78 | try {
79 | int retval = appSettings.getInt("JDasher/B_" + Key, 2);
80 | if(retval == 0) return false;
81 | else if(retval == 1) return true;
82 | else throw new CParameterNotFoundException(Key);
83 | }
84 | catch (AccessControlException e) {
85 | throw new CParameterNotFoundException(Key);
86 | }
87 |
88 | }
89 |
90 |
91 | protected long LoadLongSetting(String Key) throws CParameterNotFoundException {
92 |
93 | try {
94 | long retval = appSettings.getLong("JDasher/L_" + Key, -999);
95 | if (retval == -999 && appSettings.getLong("JDasher/L_"+Key,-998)==-998)
96 | throw new CParameterNotFoundException(Key);
97 | else return retval;
98 | }
99 | catch (AccessControlException e) {
100 | throw new CParameterNotFoundException(Key);
101 | }
102 | }
103 |
104 |
105 | protected String LoadStringSetting(String Key) throws CParameterNotFoundException {
106 |
107 | try {
108 | String retval = appSettings.get("JDasher/S_" + Key, "Parameter Error");
109 | if(retval.equals("Parameter Error")) throw new CParameterNotFoundException("Key");
110 | else return retval;
111 | }
112 | catch (AccessControlException e) {
113 | throw new CParameterNotFoundException(Key);
114 | }
115 | }
116 |
117 |
118 | protected void SaveSetting(String Key, boolean Value) {
119 | int val = Value ? 1 : 0;
120 | try {
121 | appSettings.putInt("JDasher/B_" + Key, val);
122 | }
123 | catch (AccessControlException e) {
124 | return; // Fail silently; we will use the default next time
125 | }
126 | }
127 |
128 |
129 | protected void SaveSetting(String Key, long Value) {
130 | try {
131 | appSettings.putLong("JDasher/L_" + Key, Value);
132 | }
133 | catch (AccessControlException e) {
134 | return; // Fail silently; we will use the default next time
135 | }
136 | }
137 |
138 |
139 | protected void SaveSetting(String Key, String Value) {
140 | try {
141 | appSettings.put("JDasher/S_" + Key, Value);
142 | }
143 | catch (AccessControlException e) {
144 | return; // Fail silently; we will use the default next time
145 | }
146 | }
147 |
148 | }
149 |
150 | /**
151 | * Exception indicating that JSettings was unable to initialise
152 | * due to the Preferences object's backing store being unavailable,
153 | * probably due to security limitations.
154 | */
155 | class StoreUnavailableException extends Exception {
156 | // No properties
157 | }
158 |
--------------------------------------------------------------------------------
/src/dasher/applet/ScreenOverlay.java:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of JDasher.
3 |
4 | JDasher is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | JDasher is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with JDasher; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | Copyright (C) 2006 Christopher Smowton
19 |
20 | JDasher is a port derived from the Dasher project; for information on
21 | the project see www.dasher.org.uk; for information on JDasher itself
22 | and related projects see www.smowton.net/chris
23 |
24 | */
25 |
26 | package dasher.applet;
27 |
28 | import javax.swing.JFrame;
29 | import javax.swing.JProgressBar;
30 | import javax.swing.JLabel;
31 | import javax.swing.BoxLayout;
32 | import javax.swing.JTextArea;
33 |
34 | /**
35 | * Small JFrame containing a label and progress bar which is shown
36 | * by Dasher when training or otherwise Locked.
37 | *
38 | * At present this doesn't fully work because the Frame's screen
39 | * is not redrawn whilst another event is in progress -- and most
40 | * time consuming work in Dasher takes place in response to menu
41 | * events.
42 | *
43 | * This could potentially be fixed by using marking events triggered
44 | * by menu clicks as to be done by the redraw thread.
45 | */
46 | public class ScreenOverlay extends JFrame {
47 |
48 | /**
49 | * Our progress bar
50 | */
51 | private JProgressBar m_ProgressBar;
52 |
53 | /**
54 | * Our label
55 | */
56 | private JTextArea m_Label;
57 |
58 | /**
59 | * Creates the frame with a size of 200x100 and currently invisible.
60 | *
61 | */
62 | public ScreenOverlay() {
63 |
64 | this.setLayout(new BoxLayout(this.getContentPane(), BoxLayout.Y_AXIS));
65 |
66 | m_Label = new JTextArea("JDasher");
67 | m_Label.setLineWrap(true); m_Label.setWrapStyleWord(true);
68 | m_Label.setEditable(false);
69 |
70 | m_ProgressBar = new JProgressBar();
71 |
72 | m_ProgressBar.setVisible(false);
73 |
74 | this.setSize(200, 100);
75 |
76 | this.add(m_Label);
77 | this.add(m_ProgressBar);
78 | }
79 |
80 | /**
81 | * Sets the text in the central label (not the titlebar)
82 | *
83 | * @param newMessage Message to show the user
84 | */
85 | public void setText(String newMessage) {
86 | m_Label.setText(newMessage);
87 | }
88 |
89 | public String getText() {
90 | return m_Label.getText();
91 | }
92 |
93 | public void setCenter(int x, int y) {
94 | setLocation(x - getWidth()/2, y - getHeight()/2);
95 | }
96 |
97 | /**
98 | * Sets the current progress
99 | *
100 | * @param done Amount done
101 | * @param max Maximum amount
102 | */
103 | public void setProgress(int done, int max) {
104 | m_ProgressBar.setMaximum(max);
105 | m_ProgressBar.setValue(done);
106 | }
107 |
108 | /**
109 | * Shows or hides the progress bar
110 | *
111 | * @param visible Should the bar be visible?
112 | */
113 | public void setProgressBarVisible(boolean visible) {
114 | m_ProgressBar.setVisible(visible);
115 | }
116 |
117 | }
118 |
--------------------------------------------------------------------------------
/src/dasher/applet/alphabet.dtd:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
9 |
10 |
11 |
13 |
14 |
15 |
16 |
24 |
25 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
49 |
50 |
51 |
52 |
53 |
54 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
85 |
86 |
87 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/src/dasher/applet/colour.dtd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/dasher/applet/files.txt:
--------------------------------------------------------------------------------
1 | alphabet.dtd
2 | alphabet.english.xml
3 | colour.dtd
4 | colour.euroasian.xml
5 | training_english_GB.txt
6 |
--------------------------------------------------------------------------------
/src/dasher/applet/font/FontListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of JDasher.
3 |
4 | JDasher is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | JDasher is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with JDasher; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | Copyright (C) 2006 Christopher Smowton
19 |
20 | JDasher is a port derived from the Dasher project; for information on
21 | the project see www.dasher.org.uk; for information on JDasher itself
22 | and related projects see www.smowton.net/chris
23 |
24 | */
25 |
26 | package dasher.applet.font;
27 |
28 | public interface FontListener {
29 |
30 | public void setNewFont(java.awt.Font f);
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/xml.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | import sys
4 | import re
5 |
6 | if len(sys.argv)!=2:
7 | print "Usage: python xml.py /path/to/dasher_strings.csv"
8 | print " Expects a two-column csv file, i.e. internal names and one language's worth"
9 | print " of translations. Outputs bulk of XML, but some changes needed by hand"
10 | sys.exit(1)
11 |
12 | def dequote(s):
13 | s=s.strip()
14 | if (s==""): return s
15 | if (s[0]=='"' and s[-1]=='"'): return s[1:-1]
16 | raise Error("Couldn't dequote "+s)
17 |
18 | with open(sys.argv[1],'r') as file:
19 | for line in file:
20 | i = line.find(',')
21 | if i==-1:
22 | raise Error("No comma in "+line)
23 | key=line[:i]
24 | s=dequote(line[i+1:])
25 | if (s==""):
26 | print ""
27 | elif (key==""):
28 | print "- "+s+"
"
29 | else:
30 | print ""+s+""
31 |
--------------------------------------------------------------------------------