summaryrefslogtreecommitdiffstats
path: root/mobile/android/base/java/org/mozilla/gecko/home/SearchEngineBar.java
blob: 6a6509bcbe2e9bc07013fe5ca2c7f38edb7955cd (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
136
137
138
139
140
141
142
143
144
145
146
147
148
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
/* 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.home;

import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.View;

import org.mozilla.gecko.annotation.RobocopTarget;
import org.mozilla.gecko.R;
import org.mozilla.gecko.Telemetry;
import org.mozilla.gecko.TelemetryContract;
import org.mozilla.gecko.preferences.GeckoPreferences;
import org.mozilla.gecko.widget.RecyclerViewClickSupport;

import java.util.List;

public class SearchEngineBar extends RecyclerView
        implements RecyclerViewClickSupport.OnItemClickListener {
    private static final String LOGTAG = SearchEngineBar.class.getSimpleName();

    private static final float ICON_CONTAINER_MIN_WIDTH_DP = 72;
    private static final float LABEL_CONTAINER_WIDTH_DP = 48;

    public interface OnSearchBarClickListener {
        void onSearchBarClickListener(SearchEngine searchEngine);
    }

    private final SearchEngineAdapter mAdapter;
    private final LinearLayoutManager mLayoutManager;
    private final Paint mDividerPaint;
    private final float mMinIconContainerWidth;
    private final float mDividerHeight;
    private final int mLabelContainerWidth;

    private int mIconContainerWidth;
    private OnSearchBarClickListener mOnSearchBarClickListener;

    public SearchEngineBar(final Context context, final AttributeSet attrs) {
        super(context, attrs);

        mDividerPaint = new Paint();
        mDividerPaint.setColor(ContextCompat.getColor(context, R.color.toolbar_divider_grey));
        mDividerPaint.setStyle(Paint.Style.FILL_AND_STROKE);

        final DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
        mMinIconContainerWidth = TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP, ICON_CONTAINER_MIN_WIDTH_DP, displayMetrics);
        mDividerHeight = context.getResources().getDimension(R.dimen.page_row_divider_height);
        mLabelContainerWidth = Math.round(TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP, LABEL_CONTAINER_WIDTH_DP, displayMetrics));

        mIconContainerWidth = Math.round(mMinIconContainerWidth);

        mAdapter = new SearchEngineAdapter(context);
        mAdapter.setIconContainerWidth(mIconContainerWidth);
        mLayoutManager = new LinearLayoutManager(context);
        mLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);

        setAdapter(mAdapter);
        setLayoutManager(mLayoutManager);

        RecyclerViewClickSupport.addTo(this)
            .setOnItemClickListener(this);
    }

    public void setSearchEngines(List<SearchEngine> searchEngines) {
        mAdapter.setSearchEngines(searchEngines);
    }

    public void setOnSearchBarClickListener(OnSearchBarClickListener listener) {
        mOnSearchBarClickListener = listener;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        final int searchEngineCount = mAdapter.getItemCount() - 1;

        if (searchEngineCount > 0) {
            final int availableWidth = getMeasuredWidth() - mLabelContainerWidth;

            if (searchEngineCount * mMinIconContainerWidth <= availableWidth) {
                // All search engines fit int: So let's just display all.
                mIconContainerWidth = (int) mMinIconContainerWidth;
            } else {
                // If only (n) search engines fit into the available space then display only (x)
                // search engines with (x) picked so that the last search engine will be cut-off
                // (we only display half of it) to show the ability to scroll this view.

                final double searchEnginesToDisplay = Math.floor((availableWidth / mMinIconContainerWidth) - 0.5) + 0.5;
                // Use all available width and spread search engine icons
                mIconContainerWidth = (int) (availableWidth / searchEnginesToDisplay);
            }

            mAdapter.setIconContainerWidth(mIconContainerWidth);
        }
    }

    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.drawRect(0, 0, getWidth(), mDividerHeight, mDividerPaint);
    }

    @Override
    public void onItemClicked(RecyclerView recyclerView, int position, View v) {
        if (mOnSearchBarClickListener == null) {
            throw new IllegalStateException(
                    OnSearchBarClickListener.class.getSimpleName() + " is not initializer."
            );
        }

        if (position == 0) {
            final Intent settingsIntent = new Intent(getContext(), GeckoPreferences.class);
            GeckoPreferences.setResourceToOpen(settingsIntent, "preferences_search");
            getContext().startActivity(settingsIntent);
            Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, TelemetryContract.Method.BUTTON, "searchenginebar-settings");
            return;
        }

        final SearchEngine searchEngine = mAdapter.getItem(position);
        mOnSearchBarClickListener.onSearchBarClickListener(searchEngine);
    }

    /**
     * We manually add the override for getAdapter because we see this method getting stripped
     * out during compile time by aggressive proguard rules.
     */
    @RobocopTarget
    @Override
    public SearchEngineAdapter getAdapter() {
        return mAdapter;
    }
}