mobile/android/base/FindInPageBar.java

branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
equal deleted inserted replaced
-1:000000000000 0:9faa42ce64cf
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 package org.mozilla.gecko;
6
7 import org.mozilla.gecko.util.GeckoEventListener;
8 import org.mozilla.gecko.util.ThreadUtils;
9
10 import org.json.JSONObject;
11
12 import android.content.Context;
13 import android.text.Editable;
14 import android.text.TextUtils;
15 import android.text.TextWatcher;
16 import android.util.AttributeSet;
17 import android.view.KeyEvent;
18 import android.view.LayoutInflater;
19 import android.view.View;
20 import android.view.inputmethod.InputMethodManager;
21 import android.widget.LinearLayout;
22
23 public class FindInPageBar extends LinearLayout implements TextWatcher, View.OnClickListener, GeckoEventListener {
24 private static final String REQUEST_ID = "FindInPageBar";
25
26 private final Context mContext;
27 private CustomEditText mFindText;
28 private boolean mInflated = false;
29
30 public FindInPageBar(Context context, AttributeSet attrs) {
31 super(context, attrs);
32 mContext = context;
33 setFocusable(true);
34 }
35
36 public void inflateContent() {
37 LayoutInflater inflater = LayoutInflater.from(mContext);
38 View content = inflater.inflate(R.layout.find_in_page_content, this);
39
40 content.findViewById(R.id.find_prev).setOnClickListener(this);
41 content.findViewById(R.id.find_next).setOnClickListener(this);
42 content.findViewById(R.id.find_close).setOnClickListener(this);
43
44 // Capture clicks on the rest of the view to prevent them from
45 // leaking into other views positioned below.
46 content.setOnClickListener(this);
47
48 mFindText = (CustomEditText) content.findViewById(R.id.find_text);
49 mFindText.addTextChangedListener(this);
50 mFindText.setOnKeyPreImeListener(new CustomEditText.OnKeyPreImeListener() {
51 @Override
52 public boolean onKeyPreIme(View v, int keyCode, KeyEvent event) {
53 if (keyCode == KeyEvent.KEYCODE_BACK) {
54 hide();
55 return true;
56 }
57 return false;
58 }
59 });
60
61 mInflated = true;
62 GeckoAppShell.getEventDispatcher().registerEventListener("TextSelection:Data", this);
63 }
64
65 public void show() {
66 if (!mInflated)
67 inflateContent();
68
69 setVisibility(VISIBLE);
70 mFindText.requestFocus();
71
72 // handleMessage() receives response message and determines initial state of softInput
73 GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("TextSelection:Get", REQUEST_ID));
74 }
75
76 public void hide() {
77 setVisibility(GONE);
78 getInputMethodManager(mFindText).hideSoftInputFromWindow(mFindText.getWindowToken(), 0);
79 GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("FindInPage:Closed", null));
80 }
81
82 private InputMethodManager getInputMethodManager(View view) {
83 Context context = view.getContext();
84 return (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
85 }
86
87 public void onDestroy() {
88 if (!mInflated) {
89 return;
90 }
91 GeckoAppShell.getEventDispatcher().unregisterEventListener("TextSelection:Data", this);
92 }
93
94 // TextWatcher implementation
95
96 @Override
97 public void afterTextChanged(Editable s) {
98 GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("FindInPage:Find", s.toString()));
99 }
100
101 @Override
102 public void beforeTextChanged(CharSequence s, int start, int count, int after) {
103 // ignore
104 }
105
106 @Override
107 public void onTextChanged(CharSequence s, int start, int before, int count) {
108 // ignore
109 }
110
111 // View.OnClickListener implementation
112
113 @Override
114 public void onClick(View v) {
115 final int viewId = v.getId();
116
117 if (viewId == R.id.find_prev) {
118 GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("FindInPage:Prev", mFindText.getText().toString()));
119 getInputMethodManager(mFindText).hideSoftInputFromWindow(mFindText.getWindowToken(), 0);
120 return;
121 }
122
123 if (viewId == R.id.find_next) {
124 GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("FindInPage:Next", mFindText.getText().toString()));
125 getInputMethodManager(mFindText).hideSoftInputFromWindow(mFindText.getWindowToken(), 0);
126 return;
127 }
128
129 if (viewId == R.id.find_close) {
130 hide();
131 }
132 }
133
134 // GeckoEventListener implementation
135
136 @Override
137 public void handleMessage(String event, JSONObject message) {
138 if (!event.equals("TextSelection:Data") || !REQUEST_ID.equals(message.optString("requestId"))) {
139 return;
140 }
141
142 final String text = message.optString("text");
143
144 // Populate an initial find string, virtual keyboard not required.
145 if (!TextUtils.isEmpty(text)) {
146 // Populate initial selection
147 ThreadUtils.postToUiThread(new Runnable() {
148 @Override
149 public void run() {
150 mFindText.setText(text);
151 }
152 });
153 return;
154 }
155
156 // Show the virtual keyboard.
157 if (mFindText.hasWindowFocus()) {
158 getInputMethodManager(mFindText).showSoftInput(mFindText, 0);
159 } else {
160 // showSoftInput won't work until after the window is focused.
161 mFindText.setOnWindowFocusChangeListener(new CustomEditText.OnWindowFocusChangeListener() {
162 @Override
163 public void onWindowFocusChanged(boolean hasFocus) {
164 if (!hasFocus)
165 return;
166
167 mFindText.setOnWindowFocusChangeListener(null);
168 getInputMethodManager(mFindText).showSoftInput(mFindText, 0);
169 }
170 });
171 }
172 }
173 }

mercurial