diff options
Diffstat (limited to 'src/jp/co/omronsoft/openwnn/JAJP/TutorialJAJP.java')
-rw-r--r-- | src/jp/co/omronsoft/openwnn/JAJP/TutorialJAJP.java | 390 |
1 files changed, 390 insertions, 0 deletions
diff --git a/src/jp/co/omronsoft/openwnn/JAJP/TutorialJAJP.java b/src/jp/co/omronsoft/openwnn/JAJP/TutorialJAJP.java new file mode 100644 index 0000000..edf5ddd --- /dev/null +++ b/src/jp/co/omronsoft/openwnn/JAJP/TutorialJAJP.java @@ -0,0 +1,390 @@ +/* + * Copyright (C) 2008,2009 OMRON SOFTWARE Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Copyright (C) 2008-2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package jp.co.omronsoft.openwnn.JAJP; + +import jp.co.omronsoft.openwnn.*; +import android.content.Context; +import android.content.res.Resources; +import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.os.Message; +import android.text.Layout; +import android.text.SpannableStringBuilder; +import android.text.StaticLayout; +import android.text.Spanned; +import android.text.style.ImageSpan; +import android.text.style.DynamicDrawableSpan; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.View.OnTouchListener; +import android.widget.PopupWindow; +import android.widget.TextView; + +import java.util.ArrayList; +import java.util.List; + +public class TutorialJAJP implements OnTouchListener { + + private List<Bubble> mBubbles = new ArrayList<Bubble>(); + private static final int LONG_PRESS_INDEX = 8; + private View mInputView; + private OpenWnnJAJP mIme; + private int[] mLocation = new int[2]; + private static final int MSG_SHOW_BUBBLE = 0; + + private int mBubbleIndex; + private DefaultSoftKeyboardJAJP mInputManager; + private boolean mEnableKeyTouch = false; + + Handler mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_SHOW_BUBBLE: + Bubble bubba = (Bubble) msg.obj; + bubba.show(mLocation[0], mLocation[1]); + break; + } + } + }; + + class Bubble { + Drawable bubbleBackground; + int x; + int y; + int width; + int gravity; + CharSequence text; + boolean dismissOnTouch; + boolean dismissOnClose; + PopupWindow window; + TextView textView; + View inputView; + + Bubble(Context context, View inputView, + int backgroundResource, int bx, int by, int description, int guide) { + + CharSequence text = context.getResources().getText(description); + init(context, inputView, backgroundResource, bx, by, text, guide, false); + } + + Bubble(Context context, View inputView, int backgroundResource, int bx, int by, + CharSequence description, int guide, boolean leftAlign) { + init(context, inputView, backgroundResource, bx, by, description, guide, leftAlign); + } + + void init(Context context, View inputView, int backgroundResource, + int bx, int by, CharSequence description, int guide, boolean leftAlign) { + bubbleBackground = context.getResources().getDrawable(backgroundResource); + x = bx; + y = by; + width = (int) (inputView.getWidth() * 0.9); + this.gravity = Gravity.TOP | Gravity.LEFT; + text = new SpannableStringBuilder() + .append(description) + .append("\n") + .append(context.getResources().getText(guide)); + this.dismissOnTouch = true; + this.dismissOnClose = false; + this.inputView = inputView; + window = new PopupWindow(context); + window.setBackgroundDrawable(null); + LayoutInflater inflate = + (LayoutInflater) context + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + textView = (TextView) inflate.inflate(R.layout.bubble_text, null); + textView.setBackgroundDrawable(bubbleBackground); + textView.setText(text); + if (leftAlign) { + textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT); + } + window.setContentView(textView); + window.setFocusable(false); + window.setTouchable(true); + window.setOutsideTouchable(false); + } + + private int chooseSize(PopupWindow pop, View parentView, CharSequence text, TextView tv) { + int wid = tv.getPaddingLeft() + tv.getPaddingRight(); + int ht = tv.getPaddingTop() + tv.getPaddingBottom(); + + /* + * Figure out how big the text would be if we laid it out to the + * full width of this view minus the border. + */ + int cap = width - wid; + + Layout l = new StaticLayout(text, tv.getPaint(), cap, + Layout.Alignment.ALIGN_NORMAL, 1, 0, true); + float max = 0; + for (int i = 0; i < l.getLineCount(); i++) { + max = Math.max(max, l.getLineWidth(i)); + } + + /* + * Now set the popup size to be big enough for the text plus the border. + */ + pop.setWidth(width); + pop.setHeight(ht + l.getHeight()); + return l.getHeight(); + } + + void show(int offx, int offy) { + int textHeight = chooseSize(window, inputView, text, textView); + offy -= textView.getPaddingTop() + textHeight; + if (inputView.getVisibility() == View.VISIBLE + && inputView.getWindowVisibility() == View.VISIBLE) { + try { + if ((gravity & Gravity.BOTTOM) == Gravity.BOTTOM) offy -= window.getHeight(); + if ((gravity & Gravity.RIGHT) == Gravity.RIGHT) offx -= window.getWidth(); + textView.setOnTouchListener(new View.OnTouchListener() { + public boolean onTouch(View view, MotionEvent me) { + + boolean ret = !mEnableKeyTouch; + switch (me.getAction()) { + case MotionEvent.ACTION_UP: + if (mBubbleIndex >= mBubbles.size()) { + mInputView.setOnTouchListener(null); + } else { + TutorialJAJP.this.next(); + } + break; + default: + break; + } + return ret; + } + }); + window.showAtLocation(inputView, Gravity.NO_GRAVITY, x + offx, y + offy); + } catch (Exception e) { + } + } + } + + void hide() { + if (window.isShowing()) { + textView.setOnTouchListener(null); + window.dismiss(); + } + } + + boolean isShowing() { + return window.isShowing(); + } + } + + /** Constructor */ + public TutorialJAJP(OpenWnnJAJP ime, View inputView, DefaultSoftKeyboardJAJP inputManager) { + mInputManager = inputManager; + mInputView = inputView; + mIme = ime; + + Context context = inputView.getContext(); + int inputWidth = inputView.getWidth(); + Resources r = inputView.getContext().getResources(); + final int x = inputWidth / 20; + r.getDimensionPixelOffset(R.dimen.bubble_pointer_offset); + + SpannableStringBuilder spannable = new SpannableStringBuilder(); + Bubble button; + + spannable.clear(); + spannable.append(r.getText(R.string.tip_to_step1)); + + setSpan(spannable, "\u25cb", R.drawable.tutorial_12key_key); + button = new Bubble(context, inputView, + R.drawable.dialog_bubble, x, 0, + spannable, R.string.touch_to_continue, false); + mBubbles.add(button); + + spannable.clear(); + spannable.append(r.getText(R.string.tip_to_step2_a)); + + setSpan(spannable, "\u25cb", R.drawable.tutorial_12key_toggle); + button = new Bubble(context, inputView, + R.drawable.dialog_bubble, x, 0, + spannable, R.string.touch_to_continue, true); + mBubbles.add(button); + + spannable.append(r.getText(R.string.tip_to_step2_b)); + + setSpan(spannable, "\u2192", R.drawable.tutorial_12key_right); + + button = new Bubble(context, inputView, + R.drawable.dialog_bubble, x, 0, + spannable, R.string.touch_to_continue, true); + mBubbles.add(button); + + spannable.append(r.getText(R.string.tip_to_step2_c)); + + setSpan(spannable, "\u25cb", R.drawable.tutorial_12key_toggle); + + button = new Bubble(context, inputView, + R.drawable.dialog_bubble, x, 0, + spannable, R.string.touch_to_continue, true); + mBubbles.add(button); + + spannable.append(r.getText(R.string.tip_to_step2_d)); + + setSpan(spannable, "\u25a0", R.drawable.tutorial_12key_space_jp); + + setSpan(spannable, "\u2193", R.drawable.tutorial_12key_enter); + + button = new Bubble(context, inputView, + R.drawable.dialog_bubble, x, 0, + spannable, R.string.touch_to_continue, true); + mBubbles.add(button); + + spannable.clear(); + spannable.append(r.getText(R.string.tip_to_step3_a)); + + setSpan(spannable, "\u25a0", R.drawable.tutorial_12key_mode); + button = new Bubble(context, inputView, + R.drawable.dialog_bubble_moji, x, 0, + spannable, R.string.touch_to_continue, false); + mBubbles.add(button); + + button = new Bubble(context, inputView, + R.drawable.dialog_bubble_moji, x, 0, + R.string.tip_to_step3_b, R.string.touch_to_continue); + mBubbles.add(button); + + button = new Bubble(context, inputView, + R.drawable.dialog_bubble_moji, x, 0, + R.string.tip_to_step3_c, R.string.touch_to_continue); + mBubbles.add(button); + + spannable.clear(); + spannable.append(r.getText(R.string.tip_to_step4)); + + setSpan(spannable, "\u25a0", R.drawable.tutorial_12key_mode); + button = new Bubble(context, inputView, + R.drawable.dialog_bubble_moji, x, 0, + spannable, R.string.touch_to_try, false); + mBubbles.add(button); + + spannable.clear(); + spannable.append(r.getText(R.string.tip_to_step5)); + + setSpan(spannable, "\u2190", R.drawable.tutorial_back); + + button = new Bubble(context, inputView, + R.drawable.dialog_bubble, x, 0, + spannable, R.string.touch_to_continue, false); + mBubbles.add(button); + + button = new Bubble(context, inputView, + R.drawable.dialog_bubble, x, 0, + R.string.tip_to_step6, R.string.touch_to_finish); + mBubbles.add(button); + } + + private void setSpan(SpannableStringBuilder spannable, String marker, int imageResourceId) { + String text = spannable.toString(); + int target = text.indexOf(marker); + while (0 <= target) { + ImageSpan span = new ImageSpan(mIme, imageResourceId, + DynamicDrawableSpan.ALIGN_BOTTOM); + spannable.setSpan(span, target, target + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + target = text.indexOf(marker, target + 1); + } + } + + public void start() { + mInputView.getLocationInWindow(mLocation); + mBubbleIndex = -1; + mInputView.setOnTouchListener(this); + next(); + } + + boolean next() { + if (mBubbleIndex >= 0) { + if (!mBubbles.get(mBubbleIndex).isShowing()) { + return true; + } + for (int i = 0; i <= mBubbleIndex; i++) { + mBubbles.get(i).hide(); + } + } + mBubbleIndex++; + if (mBubbleIndex >= mBubbles.size()) { + mEnableKeyTouch = true; + mIme.sendDownUpKeyEvents(-1); + mIme.tutorialDone(); + return false; + } + + if ((6 <= mBubbleIndex) && (mBubbleIndex <= 8)) { + mInputManager.nextKeyMode(); + } + + if (mBubbleIndex == LONG_PRESS_INDEX) { + mEnableKeyTouch = true; + } else if (LONG_PRESS_INDEX < mBubbleIndex) { + mEnableKeyTouch = false; + } + + mHandler.sendMessageDelayed( + mHandler.obtainMessage(MSG_SHOW_BUBBLE, mBubbles.get(mBubbleIndex)), 500); + return true; + } + + void hide() { + for (int i = 0; i < mBubbles.size(); i++) { + mBubbles.get(i).hide(); + } + mInputView.setOnTouchListener(null); + } + + public boolean close() { + mHandler.removeMessages(MSG_SHOW_BUBBLE); + hide(); + return true; + } + + public boolean onTouch(View v, MotionEvent event) { + boolean ret = !mEnableKeyTouch; + if (event.getAction() == MotionEvent.ACTION_UP) { + if (mBubbleIndex >= mBubbles.size()) { + mInputView.setOnTouchListener(null); + } else { + if (mBubbleIndex != LONG_PRESS_INDEX) { + next(); + } + } + } + return ret; + } +} |