1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mobile/android/base/FindInPageBar.java Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,173 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.6 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +package org.mozilla.gecko; 1.9 + 1.10 +import org.mozilla.gecko.util.GeckoEventListener; 1.11 +import org.mozilla.gecko.util.ThreadUtils; 1.12 + 1.13 +import org.json.JSONObject; 1.14 + 1.15 +import android.content.Context; 1.16 +import android.text.Editable; 1.17 +import android.text.TextUtils; 1.18 +import android.text.TextWatcher; 1.19 +import android.util.AttributeSet; 1.20 +import android.view.KeyEvent; 1.21 +import android.view.LayoutInflater; 1.22 +import android.view.View; 1.23 +import android.view.inputmethod.InputMethodManager; 1.24 +import android.widget.LinearLayout; 1.25 + 1.26 +public class FindInPageBar extends LinearLayout implements TextWatcher, View.OnClickListener, GeckoEventListener { 1.27 + private static final String REQUEST_ID = "FindInPageBar"; 1.28 + 1.29 + private final Context mContext; 1.30 + private CustomEditText mFindText; 1.31 + private boolean mInflated = false; 1.32 + 1.33 + public FindInPageBar(Context context, AttributeSet attrs) { 1.34 + super(context, attrs); 1.35 + mContext = context; 1.36 + setFocusable(true); 1.37 + } 1.38 + 1.39 + public void inflateContent() { 1.40 + LayoutInflater inflater = LayoutInflater.from(mContext); 1.41 + View content = inflater.inflate(R.layout.find_in_page_content, this); 1.42 + 1.43 + content.findViewById(R.id.find_prev).setOnClickListener(this); 1.44 + content.findViewById(R.id.find_next).setOnClickListener(this); 1.45 + content.findViewById(R.id.find_close).setOnClickListener(this); 1.46 + 1.47 + // Capture clicks on the rest of the view to prevent them from 1.48 + // leaking into other views positioned below. 1.49 + content.setOnClickListener(this); 1.50 + 1.51 + mFindText = (CustomEditText) content.findViewById(R.id.find_text); 1.52 + mFindText.addTextChangedListener(this); 1.53 + mFindText.setOnKeyPreImeListener(new CustomEditText.OnKeyPreImeListener() { 1.54 + @Override 1.55 + public boolean onKeyPreIme(View v, int keyCode, KeyEvent event) { 1.56 + if (keyCode == KeyEvent.KEYCODE_BACK) { 1.57 + hide(); 1.58 + return true; 1.59 + } 1.60 + return false; 1.61 + } 1.62 + }); 1.63 + 1.64 + mInflated = true; 1.65 + GeckoAppShell.getEventDispatcher().registerEventListener("TextSelection:Data", this); 1.66 + } 1.67 + 1.68 + public void show() { 1.69 + if (!mInflated) 1.70 + inflateContent(); 1.71 + 1.72 + setVisibility(VISIBLE); 1.73 + mFindText.requestFocus(); 1.74 + 1.75 + // handleMessage() receives response message and determines initial state of softInput 1.76 + GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("TextSelection:Get", REQUEST_ID)); 1.77 + } 1.78 + 1.79 + public void hide() { 1.80 + setVisibility(GONE); 1.81 + getInputMethodManager(mFindText).hideSoftInputFromWindow(mFindText.getWindowToken(), 0); 1.82 + GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("FindInPage:Closed", null)); 1.83 + } 1.84 + 1.85 + private InputMethodManager getInputMethodManager(View view) { 1.86 + Context context = view.getContext(); 1.87 + return (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); 1.88 + } 1.89 + 1.90 + public void onDestroy() { 1.91 + if (!mInflated) { 1.92 + return; 1.93 + } 1.94 + GeckoAppShell.getEventDispatcher().unregisterEventListener("TextSelection:Data", this); 1.95 + } 1.96 + 1.97 + // TextWatcher implementation 1.98 + 1.99 + @Override 1.100 + public void afterTextChanged(Editable s) { 1.101 + GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("FindInPage:Find", s.toString())); 1.102 + } 1.103 + 1.104 + @Override 1.105 + public void beforeTextChanged(CharSequence s, int start, int count, int after) { 1.106 + // ignore 1.107 + } 1.108 + 1.109 + @Override 1.110 + public void onTextChanged(CharSequence s, int start, int before, int count) { 1.111 + // ignore 1.112 + } 1.113 + 1.114 + // View.OnClickListener implementation 1.115 + 1.116 + @Override 1.117 + public void onClick(View v) { 1.118 + final int viewId = v.getId(); 1.119 + 1.120 + if (viewId == R.id.find_prev) { 1.121 + GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("FindInPage:Prev", mFindText.getText().toString())); 1.122 + getInputMethodManager(mFindText).hideSoftInputFromWindow(mFindText.getWindowToken(), 0); 1.123 + return; 1.124 + } 1.125 + 1.126 + if (viewId == R.id.find_next) { 1.127 + GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("FindInPage:Next", mFindText.getText().toString())); 1.128 + getInputMethodManager(mFindText).hideSoftInputFromWindow(mFindText.getWindowToken(), 0); 1.129 + return; 1.130 + } 1.131 + 1.132 + if (viewId == R.id.find_close) { 1.133 + hide(); 1.134 + } 1.135 + } 1.136 + 1.137 + // GeckoEventListener implementation 1.138 + 1.139 + @Override 1.140 + public void handleMessage(String event, JSONObject message) { 1.141 + if (!event.equals("TextSelection:Data") || !REQUEST_ID.equals(message.optString("requestId"))) { 1.142 + return; 1.143 + } 1.144 + 1.145 + final String text = message.optString("text"); 1.146 + 1.147 + // Populate an initial find string, virtual keyboard not required. 1.148 + if (!TextUtils.isEmpty(text)) { 1.149 + // Populate initial selection 1.150 + ThreadUtils.postToUiThread(new Runnable() { 1.151 + @Override 1.152 + public void run() { 1.153 + mFindText.setText(text); 1.154 + } 1.155 + }); 1.156 + return; 1.157 + } 1.158 + 1.159 + // Show the virtual keyboard. 1.160 + if (mFindText.hasWindowFocus()) { 1.161 + getInputMethodManager(mFindText).showSoftInput(mFindText, 0); 1.162 + } else { 1.163 + // showSoftInput won't work until after the window is focused. 1.164 + mFindText.setOnWindowFocusChangeListener(new CustomEditText.OnWindowFocusChangeListener() { 1.165 + @Override 1.166 + public void onWindowFocusChanged(boolean hasFocus) { 1.167 + if (!hasFocus) 1.168 + return; 1.169 + 1.170 + mFindText.setOnWindowFocusChangeListener(null); 1.171 + getInputMethodManager(mFindText).showSoftInput(mFindText, 0); 1.172 + } 1.173 + }); 1.174 + } 1.175 + } 1.176 +}