summaryrefslogtreecommitdiffstats
path: root/mobile/android/base/java/org/mozilla/gecko/ActionModeCompat.java
blob: 709c0056fd18a2171535ecd55d3571dc497972b4 (plain)
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
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

package org.mozilla.gecko;

import org.mozilla.gecko.menu.GeckoMenu;
import org.mozilla.gecko.menu.GeckoMenuItem;
import org.mozilla.gecko.widget.GeckoPopupMenu;

import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;

class ActionModeCompat implements GeckoPopupMenu.OnMenuItemClickListener,
                                  GeckoPopupMenu.OnMenuItemLongClickListener,
                                  View.OnClickListener {
    private final String LOGTAG = "GeckoActionModeCompat";

    private final Callback mCallback;
    private final ActionModeCompatView mView;
    private final Presenter mPresenter;

    /* A set of callbacks to be called during this ActionMode's lifecycle. These will control the
     * creation, interaction with, and destruction of menuitems for the view */
    public static interface Callback {
        /* Called when action mode is first created. Implementors should use this to inflate menu resources. */
        public boolean onCreateActionMode(ActionModeCompat mode, GeckoMenu menu);

        /* Called to refresh an action mode's action menu. Called whenever the mode is invalidated. Implementors
         * should use this to enable/disable/show/hide menu items. */
        public boolean onPrepareActionMode(ActionModeCompat mode, GeckoMenu menu);

        /* Called to report a user click on an action button. */
        public boolean onActionItemClicked(ActionModeCompat mode, MenuItem item);

        /* Called when an action mode is about to be exited and destroyed. */
        public void onDestroyActionMode(ActionModeCompat mode);
    }

    /* Presenters handle the actual showing/hiding of the action mode UI in the app. Its their responsibility
     * to create an action mode, and assign it Callbacks and ActionModeCompatView's. */
    public static interface Presenter {
        /* Called when an action mode should be shown */
        public void startActionModeCompat(final Callback callback);

        /* Called when whatever action mode is showing should be hidden */
        public void endActionModeCompat();
    }

    public ActionModeCompat(Presenter presenter, Callback callback, ActionModeCompatView view) {
        mPresenter = presenter;
        mCallback = callback;

        mView = view;
        mView.initForMode(this);
    }

    public void finish() {
        // Clearing the menu will also clear the ActionItemBar
        final GeckoMenu menu = mView.getMenu();
        menu.clear();
        menu.close();

        if (mCallback != null) {
            mCallback.onDestroyActionMode(this);
        }
    }

    public CharSequence getTitle() {
        return mView.getTitle();
    }

    public void setTitle(CharSequence title) {
        mView.setTitle(title);
    }

    public void setTitle(int resId) {
        mView.setTitle(resId);
    }

    public GeckoMenu getMenu() {
        return mView.getMenu();
    }

    public void invalidate() {
        if (mCallback != null) {
            mCallback.onPrepareActionMode(this, mView.getMenu());
        }
        mView.invalidate();
    }

    public void animateIn() {
        mView.animateIn();
    }

    /* GeckoPopupMenu.OnMenuItemClickListener */
    @Override
    public boolean onMenuItemClick(MenuItem item) {
        if (mCallback != null) {
            return mCallback.onActionItemClicked(this, item);
        }
        return false;
    }

    /* GeckoPopupMenu.onMenuItemLongClickListener */
    @Override
    public boolean onMenuItemLongClick(MenuItem item) {
        showTooltip((GeckoMenuItem) item);
        return true;
    }

    /* View.OnClickListener*/
    @Override
    public void onClick(View v) {
        mPresenter.endActionModeCompat();
    }

    private void showTooltip(GeckoMenuItem item) {
        // Computes the tooltip toast screen position (shown when long-tapping the menu item) with regards to the
        // menu item's position (i.e below the item and slightly to the left)
        int[] location = new int[2];
        final View view = item.getActionView();
        view.getLocationOnScreen(location);

        int xOffset = location[0] - view.getWidth();
        int yOffset = location[1] + view.getHeight() / 2;

        Toast toast = Toast.makeText(view.getContext(), item.getTitle(), Toast.LENGTH_SHORT);
        toast.setGravity(Gravity.TOP | Gravity.LEFT, xOffset, yOffset);
        toast.show();
    }
}