-
Notifications
You must be signed in to change notification settings - Fork 0
/
SoftWingInput.cs
191 lines (171 loc) · 6.95 KB
/
SoftWingInput.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
using Android.App;
using Android.Content;
using Android.InputMethodServices;
using Android.OS;
using Android.Util;
using Android.Views;
using Android.Views.InputMethods;
using System;
using SoftWing.SwSystem.Messages;
using SoftWing.SwSystem;
using Android.Widget;
namespace SoftWing
{
[Service(Label = "SoftWingInput", Permission = "android.permission.BIND_INPUT_METHOD", Exported = true)]
[IntentFilter(new[] { "android.view.InputMethod" })]
[MetaData("android.view.im", Resource = "@xml/input_method_config")]
public class SoftWingInput : InputMethodService, MessageSubscriber
{
private const String TAG = "SoftWingInput";
private const int MULTI_DISPLAY_HEIGHT_PX = 1240;
private MessageDispatcher dispatcher;
public static IBinder InputSessionToken;
public static bool ImeIsOpen = false;
public class SwInputMethodImpl : InputMethodImpl
{
public SwInputMethodImpl(SoftWingInput _owner)
: base(_owner)
{
}
public override void AttachToken(IBinder token)
{
Log.Info(TAG, "attachToken " + token);
base.AttachToken(token);
InputSessionToken = token;
}
}
public override void OnCreate()
{
Log.Debug(TAG, "onCreate()");
base.OnCreate();
}
public override View OnCreateInputView()
{
Log.Debug(TAG, "onCreateInputView()");
SwDisplayManager.StartSwDisplayManager();
var keyboardView = LayoutInflater.Inflate(Resource.Layout.input_base, null);
// Force the controller to hide navigation buttons
var uiOptions = SystemUiFlags.HideNavigation |
SystemUiFlags.LayoutHideNavigation |
SystemUiFlags.LayoutFullscreen |
SystemUiFlags.Fullscreen |
SystemUiFlags.LayoutStable |
SystemUiFlags.ImmersiveSticky;
keyboardView.SystemUiVisibility = (StatusBarVisibility)uiOptions;
keyboardView.SetMinimumHeight(MULTI_DISPLAY_HEIGHT_PX);
return keyboardView;
}
public override bool OnEvaluateFullscreenMode()
{
return false;
}
private void SetJoystickListener(View joystick, ControlId cid)
{
Log.Debug(TAG, "SetJoystickListener()");
var joystick_frame = (FrameLayout)joystick;
joystick_frame.RemoveAllViews();
SurfaceView joystickSurface = new SurfaceView(this.BaseContext);
joystick_frame.AddView(joystickSurface);
var listener = new SwJoystickListener(joystickSurface, cid);
joystickSurface.SetOnTouchListener(listener);
}
private void SetInputListener(View vin, ControlId cid)
{
Log.Debug(TAG, "SetInputListener()");
var listener = new SwButtonListener(vin, cid);
vin.SetOnTouchListener(listener);
}
private void SetInputListeners(ViewGroup keyboard_view_group)
{
Log.Debug(TAG, "SetInputListeners");
foreach (var key in SwSettings.RESOURCE_TO_CONTROL_MAP.Keys)
{
View control = keyboard_view_group.FindViewById<View>(key);
var control_id = SwSettings.RESOURCE_TO_CONTROL_MAP[key];
switch (key)
{
case (Resource.Id.left_joyStick):
case (Resource.Id.right_joyStick):
SetJoystickListener(control, control_id);
break;
default:
SetInputListener(control, control_id);
break;
}
}
}
private void UpdateLayoutVisibility()
{
var inputViewA = this.Window.FindViewById<ViewGroup>(Resource.Id.imeKeyViewA);
var inputViewB = this.Window.FindViewById<ViewGroup>(Resource.Id.imeKeyViewB);
var inputViewC = this.Window.FindViewById<ViewGroup>(Resource.Id.imeKeyViewC);
inputViewA.Visibility = ViewStates.Gone;
inputViewB.Visibility = ViewStates.Gone;
inputViewC.Visibility = ViewStates.Gone;
switch (SwSettings.GetSelectedLayout())
{
case (Resource.Layout.input_b):
inputViewB.Visibility = ViewStates.Visible;
SetInputListeners(inputViewB);
break;
case (Resource.Layout.input_c):
inputViewC.Visibility = ViewStates.Visible;
SetInputListeners(inputViewC);
break;
default:
inputViewA.Visibility = ViewStates.Visible;
SetInputListeners(inputViewA);
break;
}
}
public override void OnStartInputView(EditorInfo info, bool restarting)
{
Log.Debug(TAG, "OnStartInputView()");
base.OnStartInputView(info, restarting);
dispatcher = MessageDispatcher.GetInstance();
dispatcher.Subscribe(SwSystem.MessageType.ControlUpdate, this);
UpdateLayoutVisibility();
ImeIsOpen = true;
}
public override void OnFinishInputView(bool finishingInput)
{
Log.Debug(TAG, "OnFinishInputView()");
base.OnFinishInputView(finishingInput);
dispatcher.Unsubscribe(SwSystem.MessageType.ControlUpdate, this);
ImeIsOpen = false;
}
public override AbstractInputMethodImpl OnCreateInputMethodInterface()
{
Log.Debug(TAG, "OnCreateInputMethodInterface()");
return new SwInputMethodImpl(this);
}
public void Accept(SystemMessage message)
{
if (message.getMessageType() != MessageType.ControlUpdate)
{
return;
}
if (CurrentInputConnection == null)
{
Log.Debug(TAG, "Connection is null, ignoring key update");
return;
}
var control_message = (ControlUpdateMessage)message;
if (control_message.Key == null) { return; }
var key_code = (Android.Views.Keycode) control_message.Key;
switch (control_message.Update)
{
case ControlUpdateMessage.UpdateType.Pressed:
Log.Debug(TAG, "Accept(UpdateType.Pressed)");
CurrentInputConnection.SendKeyEvent(new KeyEvent(KeyEventActions.Down, key_code));
break;
case ControlUpdateMessage.UpdateType.Released:
Log.Debug(TAG, "Accept(UpdateType.Released)");
CurrentInputConnection.SendKeyEvent(new KeyEvent(KeyEventActions.Up, key_code));
break;
default:
break;
}
}
}
}