Merge mozilla-central to mozilla-inbound
@ -21,4 +21,7 @@ browser.jar:
|
||||
content/branding/metro-about.css (metro-about.css)
|
||||
content/branding/metro-about-footer.png (metro-about-footer.png)
|
||||
content/branding/metro-about-wordmark.png (metro-about-wordmark.png)
|
||||
content/branding/metro_firstrun_logo.png (metro_firstrun_logo.png)
|
||||
content/branding/metro_firstrun_logo@1.4x.png (metro_firstrun_logo@1.4x.png)
|
||||
content/branding/metro_firstrun_logo@1.8x.png (metro_firstrun_logo@1.8x.png)
|
||||
#endif
|
||||
|
BIN
browser/branding/aurora/content/metro_firstrun_logo.png
Normal file
After Width: | Height: | Size: 57 KiB |
BIN
browser/branding/aurora/content/metro_firstrun_logo@1.4x.png
Normal file
After Width: | Height: | Size: 98 KiB |
BIN
browser/branding/aurora/content/metro_firstrun_logo@1.8x.png
Normal file
After Width: | Height: | Size: 146 KiB |
@ -21,4 +21,7 @@ browser.jar:
|
||||
content/branding/metro-about.css (metro-about.css)
|
||||
content/branding/metro-about-footer.png (metro-about-footer.png)
|
||||
content/branding/metro-about-wordmark.png (metro-about-wordmark.png)
|
||||
content/branding/metro_firstrun_logo.png (metro_firstrun_logo.png)
|
||||
content/branding/metro_firstrun_logo@1.4x.png (metro_firstrun_logo@1.4x.png)
|
||||
content/branding/metro_firstrun_logo@1.8x.png (metro_firstrun_logo@1.8x.png)
|
||||
#endif
|
||||
|
BIN
browser/branding/nightly/content/metro_firstrun_logo.png
Normal file
After Width: | Height: | Size: 51 KiB |
BIN
browser/branding/nightly/content/metro_firstrun_logo@1.4x.png
Normal file
After Width: | Height: | Size: 88 KiB |
BIN
browser/branding/nightly/content/metro_firstrun_logo@1.8x.png
Normal file
After Width: | Height: | Size: 132 KiB |
@ -20,4 +20,7 @@ browser.jar:
|
||||
content/branding/metro-about.css (metro-about.css)
|
||||
content/branding/metro-about-footer.png (metro-about-footer.png)
|
||||
content/branding/metro-about-wordmark.png (metro-about-wordmark.png)
|
||||
content/branding/metro_firstrun_logo.png (metro_firstrun_logo.png)
|
||||
content/branding/metro_firstrun_logo@1.4x.png (metro_firstrun_logo@1.4x.png)
|
||||
content/branding/metro_firstrun_logo@1.8x.png (metro_firstrun_logo@1.8x.png)
|
||||
#endif
|
||||
|
BIN
browser/branding/official/content/metro_firstrun_logo.png
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
browser/branding/official/content/metro_firstrun_logo@1.4x.png
Normal file
After Width: | Height: | Size: 78 KiB |
BIN
browser/branding/official/content/metro_firstrun_logo@1.8x.png
Normal file
After Width: | Height: | Size: 113 KiB |
@ -21,4 +21,7 @@ browser.jar:
|
||||
content/branding/metro-about.css (metro-about.css)
|
||||
content/branding/metro-about-footer.png (metro-about-footer.png)
|
||||
content/branding/metro-about-wordmark.png (metro-about-wordmark.png)
|
||||
content/branding/metro_firstrun_logo.png (metro_firstrun_logo.png)
|
||||
content/branding/metro_firstrun_logo@1.4x.png (metro_firstrun_logo@1.4x.png)
|
||||
content/branding/metro_firstrun_logo@1.8x.png (metro_firstrun_logo@1.8x.png)
|
||||
#endif
|
||||
|
BIN
browser/branding/unofficial/content/metro_firstrun_logo.png
Normal file
After Width: | Height: | Size: 51 KiB |
BIN
browser/branding/unofficial/content/metro_firstrun_logo@1.4x.png
Normal file
After Width: | Height: | Size: 88 KiB |
BIN
browser/branding/unofficial/content/metro_firstrun_logo@1.8x.png
Normal file
After Width: | Height: | Size: 132 KiB |
@ -396,10 +396,6 @@
|
||||
align="center"
|
||||
pack="center">
|
||||
<description value="&debuggerUI.tracingNotStarted.label;" />
|
||||
<button id="start-tracing"
|
||||
class="devtools-toolbarbutton"
|
||||
command="startTracing"
|
||||
label="&debuggerUI.startTracing;"/>
|
||||
</vbox>
|
||||
</deck>
|
||||
</tabpanel>
|
||||
|
@ -213,7 +213,7 @@ let Util = {
|
||||
aURL == "about:empty" ||
|
||||
aURL == "about:home" ||
|
||||
aURL == "about:newtab" ||
|
||||
aURL == "about:start");
|
||||
aURL.startsWith("about:newtab"));
|
||||
},
|
||||
|
||||
// Title to use for emptyURL tabs.
|
||||
|
@ -308,7 +308,7 @@ var BrowserUI = {
|
||||
|
||||
isStartURI: function isStartURI(aURI) {
|
||||
aURI = aURI || Browser.selectedBrowser.currentURI.spec;
|
||||
return aURI == kStartURI || aURI == "about:start" || aURI == "about:home";
|
||||
return aURI.startsWith(kStartURI) || aURI == "about:start" || aURI == "about:home";
|
||||
},
|
||||
|
||||
updateStartURIAttributes: function (aURI) {
|
||||
|
69
browser/metro/base/content/startui/FirstRunOverlay.xul
Normal file
@ -0,0 +1,69 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<?xml-stylesheet href="chrome://browser/skin/firstrun.css" type="text/css"?>
|
||||
|
||||
<!-- 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/. -->
|
||||
|
||||
<!DOCTYPE window [
|
||||
<!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd">
|
||||
%browserDTD;
|
||||
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
|
||||
%brandDTD;
|
||||
]>
|
||||
|
||||
<overlay id="firstrun"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<hbox id="start-container">
|
||||
<box id="instruction-topsites-box" insertafter="start-topsites" class="firstrun">
|
||||
<box id="instruction-topsites">
|
||||
<vbox align="center">
|
||||
<image class="instruction-arrow arrow-left" />
|
||||
<label class="instruction-label" value="&firstRunTopSites.label;"/>
|
||||
</vbox>
|
||||
</box>
|
||||
</box>
|
||||
|
||||
<vbox id="firstrun-welcome" insertafter="instruction-topsites-box" class="firstrun" align="center" pack="center">
|
||||
<image class="welcome-image" />
|
||||
<label class="welcome-title" value="&firstRunWelcome.label;"/>
|
||||
<label class="welcome-subtitle" value="&firstRunDifferent.label;"/>
|
||||
</vbox>
|
||||
|
||||
<box insertafter="start-bookmarks" class="firstrun">
|
||||
<box id="instruction-bookmarks">
|
||||
<vbox align="center">
|
||||
<image class="instruction-arrow arrow-right" />
|
||||
<label class="instruction-label" value="&firstRunBookmarks.label;"/>
|
||||
</vbox>
|
||||
</box>
|
||||
</box>
|
||||
|
||||
<box id="instruction-history-container" insertafter="start-history" class="firstrun">
|
||||
<box id="instruction-history">
|
||||
<vbox align="center">
|
||||
<image class="instruction-arrow arrow-right" />
|
||||
<label class="instruction-label" value="&firstRunHistory.label;"/>
|
||||
</vbox>
|
||||
</box>
|
||||
</box>
|
||||
|
||||
<box id="instruction-tabs" class="firstrun">
|
||||
<vbox align="center">
|
||||
<image class="instruction-arrow arrow-top" />
|
||||
<label class="instruction-label" value="&firstRunTabs.label;"/>
|
||||
</vbox>
|
||||
</box>
|
||||
|
||||
<box id="instruction-menu" class="firstrun">
|
||||
<hbox>
|
||||
<label class="instruction-label" value="&firstRunMenu.label;"/>
|
||||
<image class="instruction-arrow arrow-down" />
|
||||
</hbox>
|
||||
</box>
|
||||
|
||||
</hbox>
|
||||
</overlay>
|
@ -26,6 +26,11 @@ var StartUI = {
|
||||
document.getElementById("bcast_preciseInput").setAttribute("input",
|
||||
this.chromeWin.InputSourceHelper.isPrecise ? "precise" : "imprecise");
|
||||
|
||||
// NOTE: location.search doesn't work for about: pages
|
||||
if (location.href.indexOf("?firstrun") > 0) {
|
||||
document.loadOverlay("chrome://browser/content/FirstRunOverlay.xul", null);
|
||||
}
|
||||
|
||||
this._adjustDOMforViewState(this.chromeWin.ContentAreaObserver.viewstate);
|
||||
|
||||
TopSitesStartView.init();
|
||||
|
@ -99,6 +99,7 @@ chrome.jar:
|
||||
content/BookmarksView.js (content/startui/BookmarksView.js)
|
||||
content/HistoryView.js (content/startui/HistoryView.js)
|
||||
content/TopSitesView.js (content/startui/TopSitesView.js)
|
||||
content/FirstRunOverlay.xul (content/startui/FirstRunOverlay.xul)
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
content/RemoteTabsView.js (content/startui/RemoteTabsView.js)
|
||||
#endif
|
||||
|
@ -61,7 +61,7 @@ function needHomepageOverride() {
|
||||
if (savedmstone == "ignore")
|
||||
return "none";
|
||||
|
||||
#expand let ourmstone = "__MOZ_APP_VERSION__";
|
||||
let ourmstone = Services.appinfo.platformVersion;
|
||||
|
||||
if (ourmstone != savedmstone) {
|
||||
Services.prefs.setCharPref("browser.startup.homepage_override.mstone", ourmstone);
|
||||
@ -222,6 +222,11 @@ BrowserCLH.prototype = {
|
||||
// Default to the saved homepage
|
||||
let defaultURL = getHomePage();
|
||||
|
||||
// Show page for first run or upgrade.
|
||||
if (needHomepageOverride() == "new profile") {
|
||||
defaultURL = 'about:newtab?firstrun';
|
||||
}
|
||||
|
||||
// Override the default if we have a URL passed on command line
|
||||
if (uris.length > 0) {
|
||||
defaultURL = uris[0].spec;
|
||||
|
188
browser/metro/theme/firstrun.css
Normal file
@ -0,0 +1,188 @@
|
||||
/* 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/. */
|
||||
|
||||
/* Rearrange about:start ---------------------- */
|
||||
|
||||
/* Disable all instructions in snapped mode */
|
||||
#start-container[viewstate="snapped"] .firstrun {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Keep only first column of tiles */
|
||||
#start-container[viewstate="landscape"] #start-topsites-grid .richgrid-grid,
|
||||
#start-container:not([viewstate="snapped"]) #start-bookmarks-grid .richgrid-grid,
|
||||
#start-container:not([viewstate="snapped"]) #start-history-grid .richgrid-grid {
|
||||
-moz-column-count: 1 !important;
|
||||
}
|
||||
|
||||
/* Add some bottom padding to make sure bottom tile will not be
|
||||
below instruction */
|
||||
#start-container[viewstate="landscape"] #start-topsites-grid .richgrid-grid {
|
||||
padding-bottom: 30px;
|
||||
}
|
||||
|
||||
/* Keep only first few items */
|
||||
#start-container:not([viewstate="snapped"]) #start-history-grid richgriditem:nth-child(n+3),
|
||||
#start-container:not([viewstate="snapped"]) #start-bookmarks-grid richgriditem:nth-child(n+3),
|
||||
#start-container[viewstate="portrait"] #start-topsites-grid richgriditem:nth-child(n+4) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Add some space for the instructions */
|
||||
#start-container[viewstate="portrait"] {
|
||||
padding-top: 120px;
|
||||
padding-bottom: 120px;
|
||||
}
|
||||
|
||||
/* Remove watermark */
|
||||
.meta {
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
|
||||
/* Welcome pane ---------------------- */
|
||||
|
||||
/* Logo and welcome message */
|
||||
#firstrun-welcome {
|
||||
width: 550px;
|
||||
font-family: "Segoe UI", sans-serif;
|
||||
padding: 30px 0;
|
||||
}
|
||||
|
||||
.welcome-image {
|
||||
background-image: url("chrome://branding/content/metro_firstrun_logo.png");
|
||||
|
||||
width: 220px;
|
||||
height: 220px;
|
||||
}
|
||||
|
||||
#firstrun-welcome .welcome-title {
|
||||
font-size: 25px;
|
||||
color: #4d4e53;
|
||||
line-height: 30px;
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
#firstrun-welcome .welcome-subtitle {
|
||||
font-size: 16px;
|
||||
color: #808080;
|
||||
line-height: 22px;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
/* Instructions ---------------------- */
|
||||
|
||||
.instruction-label {
|
||||
font-size: 16px;
|
||||
color: #808080;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.instruction-arrow {
|
||||
width: 76px;
|
||||
height: 76px;
|
||||
}
|
||||
|
||||
.instruction-arrow.arrow-top,
|
||||
.instruction-arrow.arrow-down {
|
||||
background-image: url("chrome://browser/skin/images/arrow-top.png");
|
||||
}
|
||||
|
||||
.instruction-arrow.arrow-down {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.instruction-arrow.arrow-left,
|
||||
.instruction-arrow.arrow-right {
|
||||
background-image: url("chrome://browser/skin/images/arrow-left.png");
|
||||
}
|
||||
|
||||
.instruction-arrow.arrow-right {
|
||||
transform: rotate(180deg) scaleY(-1);
|
||||
}
|
||||
|
||||
#instruction-tabs {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
transform: translateX(calc(630px - 50%));
|
||||
}
|
||||
|
||||
#start-container[viewstate="portrait"] #instruction-tabs {
|
||||
transform: translateX(calc(50vw - 50%));
|
||||
}
|
||||
|
||||
#start-container[viewstate="landscape"] #instruction-topsites {
|
||||
position: absolute;
|
||||
bottom: 20px;
|
||||
transform: translateX(-50%);
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
#start-container[viewstate="portrait"] #instruction-topsites {
|
||||
transform: translateX(calc(150px + 50%)) translateY(-60px);
|
||||
}
|
||||
|
||||
#start-container[viewstate="landscape"] #instruction-history,
|
||||
#start-container[viewstate="landscape"] #instruction-bookmarks {
|
||||
position: absolute;
|
||||
top: 310px;
|
||||
transform: translateX(calc(-300px - 50%));
|
||||
}
|
||||
|
||||
#start-container[viewstate="portrait"] #instruction-history,
|
||||
#start-container[viewstate="portrait"] #instruction-bookmarks {
|
||||
transform: translateX(-55px);
|
||||
}
|
||||
|
||||
#start-container[viewstate="landscape"] #instruction-menu {
|
||||
position: fixed;
|
||||
bottom: 16px;
|
||||
right: 37px;
|
||||
}
|
||||
|
||||
#start-container[viewstate="portrait"] #instruction-menu {
|
||||
position: absolute;
|
||||
right: 37px;
|
||||
transform: translateY(40px);
|
||||
}
|
||||
|
||||
#start-container[viewstate="landscape"] #start-history {
|
||||
padding-left: 50px;
|
||||
}
|
||||
|
||||
/* Higher resolution images ---------------------- */
|
||||
|
||||
@media (min-resolution: @min_res_140pc@) {
|
||||
/* Load 140% image when scaled by 140% */
|
||||
.instruction-arrow.arrow-top,
|
||||
.instruction-arrow.arrow-down {
|
||||
background-image: url("chrome://browser/skin/images/arrow-top@1.4x.png");
|
||||
}
|
||||
|
||||
.instruction-arrow.arrow-left,
|
||||
.instruction-arrow.arrow-right {
|
||||
background-image: url("chrome://browser/skin/images/arrow-left@1.4x.png");
|
||||
}
|
||||
|
||||
.welcome-image {
|
||||
background-image: url("chrome://branding/content/metro_firstrun_logo@1.4x.png");
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-resolution: @min_res_180pc@) {
|
||||
/* Load 180% image when scaled by 180% */
|
||||
.instruction-arrow.arrow-top,
|
||||
.instruction-arrow.arrow-down {
|
||||
background-image: url("chrome://browser/skin/images/arrow-top@1.8x.png");
|
||||
}
|
||||
|
||||
.instruction-arrow.arrow-left,
|
||||
.instruction-arrow.arrow-right {
|
||||
background-image: url("chrome://browser/skin/images/arrow-left@1.8x.png");
|
||||
}
|
||||
|
||||
.welcome-image {
|
||||
background-image: url("chrome://branding/content/metro_firstrun_logo@1.8x.png");
|
||||
}
|
||||
}
|
BIN
browser/metro/theme/images/arrow-left.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
browser/metro/theme/images/arrow-left@1.4x.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
browser/metro/theme/images/arrow-left@1.8x.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
browser/metro/theme/images/arrow-top.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
browser/metro/theme/images/arrow-top@1.4x.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
browser/metro/theme/images/arrow-top@1.8x.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
@ -22,6 +22,7 @@ chrome.jar:
|
||||
* skin/tiles.css (tiles.css)
|
||||
skin/touchcontrols.css (touchcontrols.css)
|
||||
skin/netError.css (netError.css)
|
||||
skin/firstrun.css (firstrun.css)
|
||||
% override chrome://global/skin/about.css chrome://browser/skin/about.css
|
||||
% override chrome://global/skin/media/videocontrols.css chrome://browser/skin/touchcontrols.css
|
||||
% override chrome://global/skin/netError.css chrome://browser/skin/netError.css
|
||||
@ -135,3 +136,10 @@ chrome.jar:
|
||||
skin/images/overlay-back.png (images/overlay-back.png)
|
||||
skin/images/overlay-plus.png (images/overlay-plus.png)
|
||||
skin/images/autoscroll.png (images/autoscroll.png)
|
||||
|
||||
skin/images/arrow-top.png (images/arrow-top.png)
|
||||
skin/images/arrow-top@1.4x.png (images/arrow-top@1.4x.png)
|
||||
skin/images/arrow-top@1.8x.png (images/arrow-top@1.8x.png)
|
||||
skin/images/arrow-left.png (images/arrow-left.png)
|
||||
skin/images/arrow-left@1.4x.png (images/arrow-left@1.4x.png)
|
||||
skin/images/arrow-left@1.8x.png (images/arrow-left@1.8x.png)
|
||||
|
@ -333,23 +333,23 @@ richgriditem[bending] > .tile-content {
|
||||
transform-origin: center center;
|
||||
}
|
||||
|
||||
/* Empty/unused tiles */
|
||||
richgriditem:not([value]) {
|
||||
visibility: hidden;
|
||||
}
|
||||
richgriditem[tiletype="thumbnail"]:not([value]) {
|
||||
visibility: visible;
|
||||
}
|
||||
richgriditem:not([value]) > .tile-content {
|
||||
padding: 10px 14px;
|
||||
}
|
||||
richgriditem[tiletype="thumbnail"]:not([value]) > .tile-content {
|
||||
/* Empty/unused tiles */
|
||||
richgriditem:not([value]) > .tile-content {
|
||||
box-shadow: 0px 0px 0px 1px rgba(0, 0, 0, 0.05);
|
||||
background-image: url("chrome://browser/skin/images/firefox-watermark.png");
|
||||
background-origin: content-box;
|
||||
background-repeat: no-repeat;
|
||||
background-color: rgba(255,255,255, 0.2);
|
||||
background-position: center center;
|
||||
background-size: @compactgrid_row_height@;
|
||||
}
|
||||
richgriditem[tiletype="thumbnail"]:not([value]) > .tile-content {
|
||||
background-size: @grid_row_height@;
|
||||
}
|
||||
|
||||
|
@ -1408,7 +1408,15 @@ abstract public class BrowserApp extends GeckoApp
|
||||
|
||||
int flags = (tab.isPrivate() || tab.getErrorType() != Tab.ErrorType.NONE) ? 0 : LoadFaviconTask.FLAG_PERSIST;
|
||||
int id = Favicons.getFaviconForSize(tab.getURL(), tab.getFaviconURL(), tabFaviconSize, flags, sFaviconLoadedListener);
|
||||
|
||||
tab.setFaviconLoadId(id);
|
||||
if (id != Favicons.LOADED &&
|
||||
Tabs.getInstance().isSelectedTab(tab)) {
|
||||
// We're loading the current tab's favicon from somewhere
|
||||
// other than the cache.
|
||||
// Display the globe favicon until then.
|
||||
mBrowserToolbar.showDefaultFavicon();
|
||||
}
|
||||
}
|
||||
|
||||
private void maybeCancelFaviconLoad(Tab tab) {
|
||||
@ -2053,6 +2061,7 @@ abstract public class BrowserApp extends GeckoApp
|
||||
|
||||
Tab tab = Tabs.getInstance().getSelectedTab();
|
||||
MenuItem bookmark = aMenu.findItem(R.id.bookmark);
|
||||
MenuItem back = aMenu.findItem(R.id.back);
|
||||
MenuItem forward = aMenu.findItem(R.id.forward);
|
||||
MenuItem share = aMenu.findItem(R.id.share);
|
||||
MenuItem saveAsPDF = aMenu.findItem(R.id.save_as_pdf);
|
||||
@ -2068,6 +2077,7 @@ abstract public class BrowserApp extends GeckoApp
|
||||
|
||||
if (tab == null || tab.getURL() == null) {
|
||||
bookmark.setEnabled(false);
|
||||
back.setEnabled(false);
|
||||
forward.setEnabled(false);
|
||||
share.setEnabled(false);
|
||||
saveAsPDF.setEnabled(false);
|
||||
@ -2080,6 +2090,7 @@ abstract public class BrowserApp extends GeckoApp
|
||||
bookmark.setChecked(tab.isBookmark());
|
||||
bookmark.setIcon(tab.isBookmark() ? R.drawable.ic_menu_bookmark_remove : R.drawable.ic_menu_bookmark_add);
|
||||
|
||||
back.setEnabled(tab.canDoBack());
|
||||
forward.setEnabled(tab.canDoForward());
|
||||
desktopMode.setChecked(tab.getDesktopMode());
|
||||
desktopMode.setIcon(tab.getDesktopMode() ? R.drawable.ic_menu_desktop_mode_on : R.drawable.ic_menu_desktop_mode_off);
|
||||
@ -2209,6 +2220,13 @@ abstract public class BrowserApp extends GeckoApp
|
||||
return true;
|
||||
}
|
||||
|
||||
if (itemId == R.id.back) {
|
||||
tab = Tabs.getInstance().getSelectedTab();
|
||||
if (tab != null)
|
||||
tab.doBack();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (itemId == R.id.forward) {
|
||||
tab = Tabs.getInstance().getSelectedTab();
|
||||
if (tab != null)
|
||||
|
@ -246,7 +246,8 @@ class TextSelection extends Layer implements GeckoEventListener {
|
||||
try {
|
||||
final JSONObject obj = mItems.getJSONObject(i);
|
||||
final GeckoMenuItem menuitem = (GeckoMenuItem) menu.add(0, i, 0, obj.optString("label"));
|
||||
menuitem.setShowAsAction(obj.optBoolean("showAsAction") ? 1 : 0, R.attr.menuItemActionModeStyle);
|
||||
final int actionEnum = obj.optBoolean("showAsAction") ? GeckoMenuItem.SHOW_AS_ACTION_ALWAYS : GeckoMenuItem.SHOW_AS_ACTION_NEVER;
|
||||
menuitem.setShowAsAction(actionEnum, R.attr.menuItemActionModeStyle);
|
||||
|
||||
BitmapUtils.getDrawable(mStartHandle.getContext(), obj.optString("icon"), new BitmapLoader() {
|
||||
public void onBitmapFound(Drawable d) {
|
||||
|
@ -78,8 +78,11 @@ public class GeckoMenu extends ListView
|
||||
// List of all menu items.
|
||||
private List<GeckoMenuItem> mItems;
|
||||
|
||||
// Map of items in action-bar and their views.
|
||||
private Map<GeckoMenuItem, View> mActionItems;
|
||||
// Map of "always" action-items in action-bar and their views.
|
||||
private Map<GeckoMenuItem, View> mPrimaryActionItems;
|
||||
|
||||
// Map of "ifRoom" action-items in action-bar and their views.
|
||||
private Map<GeckoMenuItem, View> mSecondaryActionItems;
|
||||
|
||||
// Reference to a callback for menu events.
|
||||
private Callback mCallback;
|
||||
@ -87,18 +90,24 @@ public class GeckoMenu extends ListView
|
||||
// Reference to menu presenter.
|
||||
private MenuPresenter mMenuPresenter;
|
||||
|
||||
// Reference to action-items bar in action-bar.
|
||||
private ActionItemBarPresenter mActionItemBarPresenter;
|
||||
// Reference to "always" action-items bar in action-bar.
|
||||
private ActionItemBarPresenter mPrimaryActionItemBar;
|
||||
|
||||
// Reference to "ifRoom" action-items bar in action-bar.
|
||||
private final ActionItemBarPresenter mSecondaryActionItemBar;
|
||||
|
||||
// Adapter to hold the list of menu items.
|
||||
private MenuItemsAdapter mAdapter;
|
||||
|
||||
// Show/hide icons in the list.
|
||||
private boolean mShowIcons;
|
||||
|
||||
public GeckoMenu(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public GeckoMenu(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, android.R.attr.listViewStyle);
|
||||
this(context, attrs, R.attr.geckoMenuListViewStyle);
|
||||
}
|
||||
|
||||
public GeckoMenu(Context context, AttributeSet attrs, int defStyle) {
|
||||
@ -112,10 +121,13 @@ public class GeckoMenu extends ListView
|
||||
setAdapter(mAdapter);
|
||||
setOnItemClickListener(this);
|
||||
|
||||
mShowIcons = false;
|
||||
mItems = new ArrayList<GeckoMenuItem>();
|
||||
mActionItems = new HashMap<GeckoMenuItem, View>();
|
||||
mPrimaryActionItems = new HashMap<GeckoMenuItem, View>();
|
||||
mSecondaryActionItems = new HashMap<GeckoMenuItem, View>();
|
||||
|
||||
mActionItemBarPresenter = (DefaultActionItemBar) LayoutInflater.from(context).inflate(R.layout.menu_action_bar, null);
|
||||
mPrimaryActionItemBar = (DefaultActionItemBar) LayoutInflater.from(context).inflate(R.layout.menu_action_bar, null);
|
||||
mSecondaryActionItemBar = (DefaultActionItemBar) LayoutInflater.from(context).inflate(R.layout.menu_secondary_action_bar, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -155,28 +167,55 @@ public class GeckoMenu extends ListView
|
||||
private boolean addActionItem(final GeckoMenuItem menuItem) {
|
||||
menuItem.setOnShowAsActionChangedListener(this);
|
||||
|
||||
if (mActionItems.size() == 0 &&
|
||||
mActionItemBarPresenter instanceof DefaultActionItemBar) {
|
||||
// Reset the adapter before adding the header view to a list.
|
||||
setAdapter(null);
|
||||
addHeaderView((DefaultActionItemBar) mActionItemBarPresenter);
|
||||
setAdapter(mAdapter);
|
||||
}
|
||||
final View actionView = menuItem.getActionView();
|
||||
final int actionEnum = menuItem.getActionEnum();
|
||||
boolean added = false;
|
||||
|
||||
View actionView = menuItem.getActionView();
|
||||
actionView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
handleMenuItemClick(menuItem);
|
||||
if (actionEnum == GeckoMenuItem.SHOW_AS_ACTION_ALWAYS) {
|
||||
if (mPrimaryActionItems.size() == 0 &&
|
||||
mPrimaryActionItemBar instanceof DefaultActionItemBar) {
|
||||
// Reset the adapter before adding the header view to a list.
|
||||
setAdapter(null);
|
||||
addHeaderView((DefaultActionItemBar) mPrimaryActionItemBar);
|
||||
setAdapter(mAdapter);
|
||||
}
|
||||
});
|
||||
|
||||
if (mActionItemBarPresenter.addActionItem(actionView)) {
|
||||
mActionItems.put(menuItem, actionView);
|
||||
mItems.add(menuItem);
|
||||
return true;
|
||||
if (added = mPrimaryActionItemBar.addActionItem(actionView)) {
|
||||
mPrimaryActionItems.put(menuItem, actionView);
|
||||
mItems.add(menuItem);
|
||||
}
|
||||
} else if (actionEnum == GeckoMenuItem.SHOW_AS_ACTION_IF_ROOM) {
|
||||
if (mSecondaryActionItems.size() == 0) {
|
||||
// Reset the adapter before adding the header view to a list.
|
||||
setAdapter(null);
|
||||
addHeaderView((DefaultActionItemBar) mSecondaryActionItemBar);
|
||||
setAdapter(mAdapter);
|
||||
}
|
||||
|
||||
if (added = mSecondaryActionItemBar.addActionItem(actionView)) {
|
||||
mSecondaryActionItems.put(menuItem, actionView);
|
||||
mItems.add(menuItem);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
// Set the listeners.
|
||||
if (actionView instanceof MenuItemActionBar) {
|
||||
((MenuItemActionBar) actionView).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
handleMenuItemClick(menuItem);
|
||||
}
|
||||
});
|
||||
} else if (actionView instanceof MenuItemActionView) {
|
||||
((MenuItemActionView) actionView).setMenuItemClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
handleMenuItemClick(menuItem);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return added;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -217,10 +256,17 @@ public class GeckoMenu extends ListView
|
||||
return subMenu;
|
||||
}
|
||||
|
||||
private void removeActionBarView() {
|
||||
private void removePrimaryActionBarView() {
|
||||
// Reset the adapter before removing the header view from a list.
|
||||
setAdapter(null);
|
||||
removeHeaderView((DefaultActionItemBar) mActionItemBarPresenter);
|
||||
removeHeaderView((DefaultActionItemBar) mPrimaryActionItemBar);
|
||||
setAdapter(mAdapter);
|
||||
}
|
||||
|
||||
private void removeSecondaryActionBarView() {
|
||||
// Reset the adapter before removing the header view from a list.
|
||||
setAdapter(null);
|
||||
removeHeaderView((DefaultActionItemBar) mSecondaryActionItemBar);
|
||||
setAdapter(mAdapter);
|
||||
}
|
||||
|
||||
@ -248,18 +294,27 @@ public class GeckoMenu extends ListView
|
||||
* remove the old ones. This also ensures that any text associated with
|
||||
* these is switched to the correct locale.
|
||||
*/
|
||||
if (mActionItemBarPresenter != null) {
|
||||
for (View item : mActionItems.values()) {
|
||||
mActionItemBarPresenter.removeActionItem(item);
|
||||
if (mPrimaryActionItemBar != null) {
|
||||
for (View item : mPrimaryActionItems.values()) {
|
||||
mPrimaryActionItemBar.removeActionItem(item);
|
||||
}
|
||||
}
|
||||
mActionItems.clear();
|
||||
mPrimaryActionItems.clear();
|
||||
|
||||
if (mSecondaryActionItemBar != null) {
|
||||
for (View item : mSecondaryActionItems.values()) {
|
||||
mSecondaryActionItemBar.removeActionItem(item);
|
||||
}
|
||||
}
|
||||
mSecondaryActionItems.clear();
|
||||
|
||||
// Remove the view, too -- the first addActionItem will re-add it,
|
||||
// and this is simpler than changing that logic.
|
||||
if (mActionItemBarPresenter instanceof DefaultActionItemBar) {
|
||||
removeActionBarView();
|
||||
if (mPrimaryActionItemBar instanceof DefaultActionItemBar) {
|
||||
removePrimaryActionBarView();
|
||||
}
|
||||
|
||||
removeSecondaryActionBarView();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -301,7 +356,9 @@ public class GeckoMenu extends ListView
|
||||
@Override
|
||||
public boolean hasVisibleItems() {
|
||||
for (GeckoMenuItem menuItem : mItems) {
|
||||
if (menuItem.isVisible() && !mActionItems.containsKey(menuItem))
|
||||
if (menuItem.isVisible() &&
|
||||
!mPrimaryActionItems.containsKey(menuItem) &&
|
||||
!mSecondaryActionItems.containsKey(menuItem))
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -345,16 +402,30 @@ public class GeckoMenu extends ListView
|
||||
}
|
||||
|
||||
// Remove it from own menu.
|
||||
if (mActionItems.containsKey(item)) {
|
||||
if (mActionItemBarPresenter != null)
|
||||
mActionItemBarPresenter.removeActionItem(mActionItems.get(item));
|
||||
if (mPrimaryActionItems.containsKey(item)) {
|
||||
if (mPrimaryActionItemBar != null)
|
||||
mPrimaryActionItemBar.removeActionItem(mPrimaryActionItems.get(item));
|
||||
|
||||
mActionItems.remove(item);
|
||||
mPrimaryActionItems.remove(item);
|
||||
mItems.remove(item);
|
||||
|
||||
if (mActionItems.size() == 0 &&
|
||||
mActionItemBarPresenter instanceof DefaultActionItemBar) {
|
||||
removeActionBarView();
|
||||
if (mPrimaryActionItems.size() == 0 &&
|
||||
mPrimaryActionItemBar instanceof DefaultActionItemBar) {
|
||||
removePrimaryActionBarView();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (mSecondaryActionItems.containsKey(item)) {
|
||||
if (mSecondaryActionItemBar != null)
|
||||
mSecondaryActionItemBar.removeActionItem(mSecondaryActionItems.get(item));
|
||||
|
||||
mSecondaryActionItems.remove(item);
|
||||
mItems.remove(item);
|
||||
|
||||
if (mSecondaryActionItems.size() == 0) {
|
||||
removeSecondaryActionBarView();
|
||||
}
|
||||
|
||||
return;
|
||||
@ -387,14 +458,14 @@ public class GeckoMenu extends ListView
|
||||
|
||||
@Override
|
||||
public boolean hasActionItemBar() {
|
||||
return (mActionItemBarPresenter != null);
|
||||
return (mPrimaryActionItemBar != null) && (mSecondaryActionItemBar != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShowAsActionChanged(GeckoMenuItem item, boolean isActionItem) {
|
||||
public void onShowAsActionChanged(GeckoMenuItem item) {
|
||||
removeItem(item.getItemId());
|
||||
|
||||
if (isActionItem && addActionItem(item)) {
|
||||
if (item.isActionItem() && addActionItem(item)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -403,23 +474,33 @@ public class GeckoMenu extends ListView
|
||||
|
||||
public void onItemChanged(GeckoMenuItem item) {
|
||||
if (item.isActionItem()) {
|
||||
final MenuItemActionBar actionView = (MenuItemActionBar) mActionItems.get(item);
|
||||
if (actionView != null) {
|
||||
// The update could be coming from the background thread.
|
||||
// Post a runnable on the UI thread of the view for it to update.
|
||||
final GeckoMenuItem menuItem = item;
|
||||
actionView.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (menuItem.isVisible()) {
|
||||
actionView.setVisibility(View.VISIBLE);
|
||||
actionView.initialize(menuItem);
|
||||
} else {
|
||||
actionView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
final View actionView;
|
||||
if (item.getActionEnum() == GeckoMenuItem.SHOW_AS_ACTION_ALWAYS) {
|
||||
actionView = mPrimaryActionItems.get(item);
|
||||
} else {
|
||||
actionView = mSecondaryActionItems.get(item);
|
||||
}
|
||||
|
||||
if (actionView != null) {
|
||||
// The update could be coming from the background thread.
|
||||
// Post a runnable on the UI thread of the view for it to update.
|
||||
final GeckoMenuItem menuItem = item;
|
||||
actionView.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (menuItem.isVisible()) {
|
||||
actionView.setVisibility(View.VISIBLE);
|
||||
if (actionView instanceof MenuItemActionBar) {
|
||||
((MenuItemActionBar) actionView).initialize(menuItem);
|
||||
} else {
|
||||
((MenuItemActionView) actionView).initialize(menuItem);
|
||||
}
|
||||
} else {
|
||||
actionView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
mAdapter.notifyDataSetChanged();
|
||||
}
|
||||
@ -445,6 +526,7 @@ public class GeckoMenu extends ListView
|
||||
ActionProvider provider = item.getActionProvider();
|
||||
if (provider != null) {
|
||||
GeckoSubMenu subMenu = new GeckoSubMenu(getContext());
|
||||
subMenu.setShowIcons(true);
|
||||
provider.onPrepareSubMenu(subMenu);
|
||||
item.setSubMenu(subMenu);
|
||||
}
|
||||
@ -491,13 +573,23 @@ public class GeckoMenu extends ListView
|
||||
}
|
||||
|
||||
public void setActionItemBarPresenter(ActionItemBarPresenter presenter) {
|
||||
mActionItemBarPresenter = presenter;
|
||||
mPrimaryActionItemBar = presenter;
|
||||
}
|
||||
|
||||
public void setShowIcons(boolean show) {
|
||||
if (mShowIcons != show) {
|
||||
mShowIcons = show;
|
||||
mAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
// Action Items are added to the header view by default.
|
||||
// URL bar can register itself as a presenter, in case it has a different place to show them.
|
||||
public static class DefaultActionItemBar extends LinearLayout
|
||||
implements ActionItemBarPresenter {
|
||||
private final int mRowHeight;
|
||||
private float mWeightSum;
|
||||
|
||||
public DefaultActionItemBar(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
@ -505,21 +597,42 @@ public class GeckoMenu extends ListView
|
||||
public DefaultActionItemBar(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
||||
setWeightSum(3.0f);
|
||||
mRowHeight = getResources().getDimensionPixelSize(R.dimen.menu_item_row_height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addActionItem(View actionItem) {
|
||||
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(actionItem.getLayoutParams());
|
||||
params.weight = 1.0f;
|
||||
ViewGroup.LayoutParams actualParams = actionItem.getLayoutParams();
|
||||
LinearLayout.LayoutParams params;
|
||||
|
||||
if (actualParams != null) {
|
||||
params = new LinearLayout.LayoutParams(actionItem.getLayoutParams());
|
||||
params.width = 0;
|
||||
} else {
|
||||
params = new LinearLayout.LayoutParams(0, mRowHeight);
|
||||
}
|
||||
|
||||
if (actionItem instanceof MenuItemActionView) {
|
||||
params.weight = ((MenuItemActionView) actionItem).getChildCount();
|
||||
} else {
|
||||
params.weight = 1.0f;
|
||||
}
|
||||
|
||||
mWeightSum += params.weight;
|
||||
|
||||
actionItem.setLayoutParams(params);
|
||||
addView(actionItem);
|
||||
setWeightSum(mWeightSum);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeActionItem(View actionItem) {
|
||||
removeView(actionItem);
|
||||
if (indexOfChild(actionItem) != -1) {
|
||||
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) actionItem.getLayoutParams();
|
||||
mWeightSum -= params.weight;
|
||||
removeView(actionItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -599,6 +712,7 @@ public class GeckoMenu extends ListView
|
||||
}
|
||||
|
||||
// Initialize the view.
|
||||
view.setShowIcon(mShowIcons);
|
||||
view.initialize(item);
|
||||
return (View) view;
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
package org.mozilla.gecko.menu;
|
||||
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.widget.GeckoActionProvider;
|
||||
|
||||
import android.content.Intent;
|
||||
@ -18,21 +19,26 @@ import android.view.View;
|
||||
public class GeckoMenuItem implements MenuItem {
|
||||
private static final String LOGTAG = "GeckoMenuItem";
|
||||
|
||||
public static final int SHOW_AS_ACTION_NEVER = 0;
|
||||
public static final int SHOW_AS_ACTION_IF_ROOM = 1;
|
||||
public static final int SHOW_AS_ACTION_ALWAYS = 2;
|
||||
|
||||
// A View that can show a MenuItem should be able to initialize from
|
||||
// the properties of the MenuItem.
|
||||
public static interface Layout {
|
||||
public void initialize(GeckoMenuItem item);
|
||||
public void setShowIcon(boolean show);
|
||||
}
|
||||
|
||||
public static interface OnShowAsActionChangedListener {
|
||||
public boolean hasActionItemBar();
|
||||
public void onShowAsActionChanged(GeckoMenuItem item, boolean isActionItem);
|
||||
public void onShowAsActionChanged(GeckoMenuItem item);
|
||||
}
|
||||
|
||||
private int mId;
|
||||
private int mOrder;
|
||||
private View mActionView;
|
||||
private boolean mActionItem = false;
|
||||
private int mActionEnum;
|
||||
private CharSequence mTitle;
|
||||
private CharSequence mTitleCondensed;
|
||||
private boolean mCheckable = false;
|
||||
@ -79,6 +85,10 @@ public class GeckoMenuItem implements MenuItem {
|
||||
return (mActionProvider != null);
|
||||
}
|
||||
|
||||
public int getActionEnum() {
|
||||
return mActionEnum;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionProvider getActionProvider() {
|
||||
return mActionProvider;
|
||||
@ -164,7 +174,7 @@ public class GeckoMenuItem implements MenuItem {
|
||||
}
|
||||
|
||||
public boolean isActionItem() {
|
||||
return mActionItem;
|
||||
return (mActionEnum > 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -201,10 +211,14 @@ public class GeckoMenuItem implements MenuItem {
|
||||
@Override
|
||||
public void onTargetSelected() {
|
||||
mMenu.close();
|
||||
|
||||
// Refresh the menu item to show the high frequency apps.
|
||||
mShowAsActionChangedListener.onShowAsActionChanged(GeckoMenuItem.this);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
mShowAsActionChangedListener.onShowAsActionChanged(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -293,27 +307,34 @@ public class GeckoMenuItem implements MenuItem {
|
||||
if (mShowAsActionChangedListener == null)
|
||||
return;
|
||||
|
||||
if (mActionItem == (actionEnum > 0))
|
||||
if (mActionEnum == actionEnum)
|
||||
return;
|
||||
|
||||
if (actionEnum > 0) {
|
||||
if (!mShowAsActionChangedListener.hasActionItemBar())
|
||||
return;
|
||||
|
||||
// Change the type to just an icon
|
||||
MenuItemActionBar actionView;
|
||||
if (style != 0) {
|
||||
actionView = new MenuItemActionBar(mMenu.getContext(), null, style);
|
||||
} else {
|
||||
actionView = new MenuItemActionBar(mMenu.getContext());
|
||||
}
|
||||
actionView.initialize(this);
|
||||
mActionView = actionView;
|
||||
if (!hasActionProvider()) {
|
||||
// Change the type to just an icon
|
||||
MenuItemActionBar actionView;
|
||||
if (style != 0) {
|
||||
actionView = new MenuItemActionBar(mMenu.getContext(), null, style);
|
||||
} else {
|
||||
if (actionEnum == SHOW_AS_ACTION_ALWAYS) {
|
||||
actionView = new MenuItemActionBar(mMenu.getContext());
|
||||
} else {
|
||||
actionView = new MenuItemActionBar(mMenu.getContext(), null, R.attr.menuItemSecondaryActionBarStyle);
|
||||
}
|
||||
}
|
||||
|
||||
mActionItem = (actionEnum > 0);
|
||||
actionView.initialize(this);
|
||||
mActionView = actionView;
|
||||
}
|
||||
|
||||
mActionEnum = actionEnum;
|
||||
}
|
||||
|
||||
mShowAsActionChangedListener.onShowAsActionChanged(this, mActionItem);
|
||||
mShowAsActionChangedListener.onShowAsActionChanged(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -26,9 +26,6 @@ public class MenuItemActionBar extends ImageButton
|
||||
|
||||
public MenuItemActionBar(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
|
||||
int size = (int) (context.getResources().getDimension(R.dimen.browser_toolbar_height));
|
||||
setLayoutParams(new ViewGroup.LayoutParams(size, size));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -42,7 +39,7 @@ public class MenuItemActionBar extends ImageButton
|
||||
setId(item.getItemId());
|
||||
}
|
||||
|
||||
private void setIcon(Drawable icon) {
|
||||
void setIcon(Drawable icon) {
|
||||
if (icon != null) {
|
||||
setImageDrawable(icon);
|
||||
setVisibility(VISIBLE);
|
||||
@ -51,7 +48,7 @@ public class MenuItemActionBar extends ImageButton
|
||||
}
|
||||
}
|
||||
|
||||
private void setIcon(int icon) {
|
||||
void setIcon(int icon) {
|
||||
if (icon != 0) {
|
||||
setImageResource(icon);
|
||||
setVisibility(VISIBLE);
|
||||
@ -60,7 +57,7 @@ public class MenuItemActionBar extends ImageButton
|
||||
}
|
||||
}
|
||||
|
||||
private void setTitle(CharSequence title) {
|
||||
void setTitle(CharSequence title) {
|
||||
// set accessibility contentDescription here
|
||||
setContentDescription(title);
|
||||
}
|
||||
@ -70,4 +67,9 @@ public class MenuItemActionBar extends ImageButton
|
||||
super.setEnabled(enabled);
|
||||
setColorFilter(enabled ? 0 : 0xFF999999);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShowIcon(boolean show) {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ public class MenuItemActionView extends LinearLayout
|
||||
private static final String LOGTAG = "GeckoMenuItemActionView";
|
||||
|
||||
private MenuItemDefault mMenuItem;
|
||||
private ImageButton mMenuButton;
|
||||
private MenuItemActionBar mMenuButton;
|
||||
private List<ImageButton> mActionButtons;
|
||||
private View.OnClickListener mActionButtonListener;
|
||||
|
||||
@ -41,18 +41,28 @@ public class MenuItemActionView extends LinearLayout
|
||||
public MenuItemActionView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
|
||||
Resources res = context.getResources();
|
||||
int width = res.getDimensionPixelSize(R.dimen.menu_item_row_width);
|
||||
int height = res.getDimensionPixelSize(R.dimen.menu_item_row_height);
|
||||
setMinimumWidth(width);
|
||||
setMinimumHeight(height);
|
||||
|
||||
LayoutInflater.from(context).inflate(R.layout.menu_item_action_view, this);
|
||||
mMenuItem = (MenuItemDefault) findViewById(R.id.menu_item);
|
||||
mMenuButton = (ImageButton) findViewById(R.id.menu_item_button);
|
||||
mMenuButton = (MenuItemActionBar) findViewById(R.id.menu_item_button);
|
||||
mActionButtons = new ArrayList<ImageButton>();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
View parent = (View) getParent();
|
||||
if ((right - left) < parent.getMeasuredWidth() || mActionButtons.size() != 0) {
|
||||
// Use the icon.
|
||||
mMenuItem.setVisibility(View.GONE);
|
||||
mMenuButton.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
// Use the button.
|
||||
mMenuItem.setVisibility(View.VISIBLE);
|
||||
mMenuButton.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(GeckoMenuItem item) {
|
||||
if (item == null)
|
||||
@ -65,16 +75,17 @@ public class MenuItemActionView extends LinearLayout
|
||||
|
||||
private void setIcon(Drawable icon) {
|
||||
mMenuItem.setIcon(icon);
|
||||
mMenuButton.setImageDrawable(icon);
|
||||
mMenuButton.setIcon(icon);
|
||||
}
|
||||
|
||||
private void setIcon(int icon) {
|
||||
mMenuItem.setIcon(icon);
|
||||
mMenuButton.setImageResource(icon);
|
||||
mMenuButton.setIcon(icon);
|
||||
}
|
||||
|
||||
private void setTitle(CharSequence title) {
|
||||
mMenuItem.setTitle(title);
|
||||
mMenuButton.setTitle(title);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -82,7 +93,6 @@ public class MenuItemActionView extends LinearLayout
|
||||
super.setEnabled(enabled);
|
||||
mMenuItem.setEnabled(enabled);
|
||||
mMenuButton.setEnabled(enabled);
|
||||
mMenuButton.setAlpha(enabled ? 255 : 99);
|
||||
|
||||
for (ImageButton button : mActionButtons) {
|
||||
button.setEnabled(enabled);
|
||||
@ -103,17 +113,17 @@ public class MenuItemActionView extends LinearLayout
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShowIcon(boolean show) {
|
||||
mMenuItem.setShowIcon(show);
|
||||
}
|
||||
|
||||
public void addActionButton(Drawable drawable) {
|
||||
// If this is the first icon, retain the text.
|
||||
// If not, make the menu item an icon.
|
||||
final int count = mActionButtons.size();
|
||||
if (count == 0) {
|
||||
mMenuItem.setVisibility(View.VISIBLE);
|
||||
mMenuButton.setVisibility(View.GONE);
|
||||
} else {
|
||||
mMenuItem.setVisibility(View.GONE);
|
||||
mMenuButton.setVisibility(View.VISIBLE);
|
||||
}
|
||||
mMenuItem.setVisibility(View.GONE);
|
||||
mMenuButton.setVisibility(View.VISIBLE);
|
||||
|
||||
if (drawable != null) {
|
||||
ImageButton button = new ImageButton(getContext(), null, R.attr.menuItemShareActionButtonStyle);
|
||||
@ -126,8 +136,9 @@ public class MenuItemActionView extends LinearLayout
|
||||
params.weight = 1.0f;
|
||||
button.setLayoutParams(params);
|
||||
|
||||
// Fill in the action-buttons to the left of the actual menu button.
|
||||
mActionButtons.add(button);
|
||||
addView(button);
|
||||
addView(button, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ public class MenuItemDefault extends TextView
|
||||
private boolean mCheckable = false;
|
||||
private boolean mChecked = false;
|
||||
private boolean mHasSubMenu = false;
|
||||
private boolean mShowIcon = false;
|
||||
|
||||
public MenuItemDefault(Context context) {
|
||||
this(context, null);
|
||||
@ -85,6 +86,10 @@ public class MenuItemDefault extends TextView
|
||||
setSubMenuIndicator(item.hasSubMenu());
|
||||
}
|
||||
|
||||
private void refreshIcon() {
|
||||
setCompoundDrawables(mShowIcon ? mIcon : null, null, mState, null);
|
||||
}
|
||||
|
||||
void setIcon(Drawable icon) {
|
||||
mIcon = icon;
|
||||
|
||||
@ -93,7 +98,7 @@ public class MenuItemDefault extends TextView
|
||||
mIcon.setAlpha(isEnabled() ? 255 : 99);
|
||||
}
|
||||
|
||||
setCompoundDrawables(mIcon, null, mState, null);
|
||||
refreshIcon();
|
||||
}
|
||||
|
||||
void setIcon(int icon) {
|
||||
@ -134,6 +139,14 @@ public class MenuItemDefault extends TextView
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShowIcon(boolean show) {
|
||||
if (mShowIcon != show) {
|
||||
mShowIcon = show;
|
||||
refreshIcon();
|
||||
}
|
||||
}
|
||||
|
||||
private void setSubMenuIndicator(boolean hasSubMenu) {
|
||||
if (mHasSubMenu != hasSubMenu) {
|
||||
mHasSubMenu = hasSubMenu;
|
||||
|
@ -8,41 +8,30 @@ package org.mozilla.gecko.menu;
|
||||
import org.mozilla.gecko.R;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.PopupWindow;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.RelativeLayout.LayoutParams;
|
||||
|
||||
/**
|
||||
* A popup to show the inflated MenuPanel. This has an arrow pointing to the anchor.
|
||||
* A popup to show the inflated MenuPanel.
|
||||
*/
|
||||
public class MenuPopup extends PopupWindow {
|
||||
private Resources mResources;
|
||||
|
||||
private ImageView mArrowTop;
|
||||
private ImageView mArrowBottom;
|
||||
private RelativeLayout mPanel;
|
||||
private LinearLayout mPanel;
|
||||
|
||||
private int mYOffset;
|
||||
private int mArrowMargin;
|
||||
private int mPopupWidth;
|
||||
private boolean mShowArrow;
|
||||
|
||||
public MenuPopup(Context context) {
|
||||
super(context);
|
||||
mResources = context.getResources();
|
||||
|
||||
setFocusable(true);
|
||||
|
||||
mYOffset = mResources.getDimensionPixelSize(R.dimen.menu_popup_offset);
|
||||
mArrowMargin = mResources.getDimensionPixelSize(R.dimen.menu_popup_arrow_margin);
|
||||
mPopupWidth = mResources.getDimensionPixelSize(R.dimen.menu_popup_width);
|
||||
mYOffset = context.getResources().getDimensionPixelSize(R.dimen.menu_popup_offset);
|
||||
mPopupWidth = context.getResources().getDimensionPixelSize(R.dimen.menu_popup_width);
|
||||
|
||||
// Setting a null background makes the popup to not close on touching outside.
|
||||
setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
@ -50,13 +39,9 @@ public class MenuPopup extends PopupWindow {
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
|
||||
LayoutInflater inflater = LayoutInflater.from(context);
|
||||
RelativeLayout layout = (RelativeLayout) inflater.inflate(R.layout.menu_popup, null);
|
||||
setContentView(layout);
|
||||
mPanel = (LinearLayout) inflater.inflate(R.layout.menu_popup, null);
|
||||
setContentView(mPanel);
|
||||
|
||||
mArrowTop = (ImageView) layout.findViewById(R.id.menu_arrow_top);
|
||||
mArrowBottom = (ImageView) layout.findViewById(R.id.menu_arrow_bottom);
|
||||
mPanel = (RelativeLayout) layout.findViewById(R.id.menu_panel);
|
||||
mShowArrow = true;
|
||||
setAnimationStyle(R.style.PopupAnimation);
|
||||
}
|
||||
|
||||
@ -66,52 +51,18 @@ public class MenuPopup extends PopupWindow {
|
||||
* @param view The panel view with the menu to be shown.
|
||||
*/
|
||||
public void setPanelView(View view) {
|
||||
view.setLayoutParams(new LinearLayout.LayoutParams(mPopupWidth,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT));
|
||||
|
||||
mPanel.removeAllViews();
|
||||
mPanel.addView(view);
|
||||
mPanel.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show/hide the arrow pointing to the anchor.
|
||||
*
|
||||
* @param show Show/hide the arrow.
|
||||
*/
|
||||
public void showArrowToAnchor(boolean show) {
|
||||
mShowArrow = show;
|
||||
}
|
||||
|
||||
/**
|
||||
* A small little offset for the arrow to overlap the anchor.
|
||||
* A small little offset.
|
||||
*/
|
||||
@Override
|
||||
public void showAsDropDown(View anchor) {
|
||||
if (!mShowArrow) {
|
||||
mArrowTop.setVisibility(View.GONE);
|
||||
mArrowBottom.setVisibility(View.GONE);
|
||||
showAsDropDown(anchor, 0, -mYOffset);
|
||||
return;
|
||||
}
|
||||
|
||||
int[] anchorLocation = new int[2];
|
||||
anchor.getLocationOnScreen(anchorLocation);
|
||||
|
||||
int screenWidth = mResources.getDisplayMetrics().widthPixels;
|
||||
int arrowWidth = mResources.getDimensionPixelSize(R.dimen.menu_popup_arrow_width);
|
||||
int arrowOffset = (anchor.getWidth() - arrowWidth)/2;
|
||||
|
||||
if (anchorLocation[0] + mPopupWidth <= screenWidth) {
|
||||
// left align
|
||||
((LayoutParams) mArrowTop.getLayoutParams()).rightMargin = mPopupWidth - anchor.getWidth() + arrowOffset;
|
||||
((LayoutParams) mArrowBottom.getLayoutParams()).rightMargin = mPopupWidth - anchor.getWidth() + arrowOffset;
|
||||
} else {
|
||||
// right align
|
||||
((LayoutParams) mArrowTop.getLayoutParams()).rightMargin = screenWidth - anchorLocation[0] - anchor.getWidth()/2 - arrowWidth/2;
|
||||
((LayoutParams) mArrowBottom.getLayoutParams()).rightMargin = mArrowMargin;
|
||||
}
|
||||
|
||||
// shown below anchor
|
||||
mArrowTop.setVisibility(View.VISIBLE);
|
||||
mArrowBottom.setVisibility(View.GONE);
|
||||
showAsDropDown(anchor, 0, -mYOffset);
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 393 B After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 757 B After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 393 B |
After Width: | Height: | Size: 278 B |
After Width: | Height: | Size: 593 B |
Before Width: | Height: | Size: 278 B After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 573 B After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 593 B After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 2.4 KiB |
@ -12,6 +12,4 @@
|
||||
android:layout_width="@dimen/menu_item_row_width"
|
||||
android:layout_height="@dimen/browser_toolbar_height"
|
||||
android:orientation="horizontal"
|
||||
android:divider="@drawable/divider_vertical"
|
||||
android:showDividers="middle"
|
||||
android:dividerPadding="0dip"/>
|
||||
android:background="#FFD6DEE4"/>
|
||||
|
@ -5,23 +5,29 @@
|
||||
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<org.mozilla.gecko.menu.MenuItemDefault
|
||||
android:id="@+id/menu_item"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_weight="2.0"
|
||||
android:background="@drawable/action_bar_button"
|
||||
android:clickable="true"
|
||||
android:focusable="true"/>
|
||||
<!-- Application icons will be added dynamically -->
|
||||
|
||||
<ImageButton android:id="@+id/menu_item_button"
|
||||
android:layout_width="0dip"
|
||||
<FrameLayout android:layout_width="0dip"
|
||||
android:layout_height="@dimen/menu_item_row_height"
|
||||
android:layout_weight="1.0"
|
||||
android:padding="10dip"
|
||||
android:scaleType="centerInside"
|
||||
android:background="@drawable/action_bar_button"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:visibility="gone"/>
|
||||
android:layout_weight="1.0">
|
||||
|
||||
<org.mozilla.gecko.menu.MenuItemDefault
|
||||
android:id="@+id/menu_item"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:background="@drawable/action_bar_button"
|
||||
android:clickable="true"
|
||||
android:focusable="true"/>
|
||||
|
||||
<org.mozilla.gecko.menu.MenuItemActionBar
|
||||
style="@style/Widget.MenuItemSecondaryActionBar"
|
||||
android:id="@+id/menu_item_button"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:background="@drawable/action_bar_button"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</merge>
|
||||
|
@ -3,35 +3,14 @@
|
||||
- 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/. -->
|
||||
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/menu_panel"
|
||||
android:layout_width="@dimen/menu_popup_width"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:minWidth="@dimen/menu_popup_width"
|
||||
android:background="@drawable/menu_popup_bg">
|
||||
|
||||
<RelativeLayout android:id="@+id/menu_panel"
|
||||
android:layout_width="@dimen/menu_popup_width"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:background="@drawable/menu_popup_bg">
|
||||
<!-- MenuPanel will be added here dynamically -->
|
||||
|
||||
<!-- MenuPanel will be added here dynamically -->
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<ImageView android:id="@+id/menu_arrow_top"
|
||||
android:layout_width="@dimen/menu_popup_arrow_width"
|
||||
android:layout_height="12dip"
|
||||
android:layout_marginRight="@dimen/menu_popup_arrow_margin"
|
||||
android:layout_alignRight="@id/menu_panel"
|
||||
android:src="@drawable/menu_popup_arrow_top"
|
||||
android:scaleType="fitXY"/>
|
||||
|
||||
<ImageView android:id="@+id/menu_arrow_bottom"
|
||||
android:layout_width="@dimen/menu_popup_arrow_width"
|
||||
android:layout_height="12dip"
|
||||
android:layout_marginRight="@dimen/menu_popup_arrow_margin"
|
||||
android:layout_alignRight="@id/menu_panel"
|
||||
android:layout_alignBottom="@id/menu_panel"
|
||||
android:src="@drawable/menu_popup_arrow_bottom"
|
||||
android:scaleType="fitXY"/>
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- 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/. -->
|
||||
|
||||
<!--
|
||||
Note: This layout is intended to be used only above 11+.
|
||||
android:showDividers are available only 11+
|
||||
-->
|
||||
<view xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
class="org.mozilla.gecko.menu.GeckoMenu$DefaultActionItemBar"
|
||||
android:layout_width="@dimen/menu_item_row_width"
|
||||
android:layout_height="@dimen/browser_toolbar_height"
|
||||
android:orientation="horizontal"
|
||||
android:divider="@drawable/divider_vertical"
|
||||
android:showDividers="middle"
|
||||
android:dividerPadding="0dip"/>
|
@ -10,6 +10,11 @@
|
||||
android:title="@string/reload"
|
||||
android:showAsAction="always"/>
|
||||
|
||||
<item android:id="@+id/back"
|
||||
android:icon="@drawable/ic_menu_back"
|
||||
android:title="@string/back"
|
||||
android:visible="false"/>
|
||||
|
||||
<item android:id="@+id/forward"
|
||||
android:icon="@drawable/ic_menu_forward"
|
||||
android:title="@string/forward"
|
||||
@ -17,11 +22,13 @@
|
||||
|
||||
<item android:id="@+id/bookmark"
|
||||
android:icon="@drawable/ic_menu_bookmark_add"
|
||||
android:title="@string/bookmark"/>
|
||||
android:title="@string/bookmark"
|
||||
android:showAsAction="ifRoom"/>
|
||||
|
||||
<item android:id="@+id/share"
|
||||
android:icon="@drawable/ic_menu_share"
|
||||
android:title="@string/share" />
|
||||
android:title="@string/share"
|
||||
android:showAsAction="ifRoom"/>
|
||||
|
||||
<item android:id="@+id/new_tab"
|
||||
android:icon="@drawable/ic_menu_new_tab"
|
||||
|
@ -5,6 +5,11 @@
|
||||
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:id="@+id/back"
|
||||
android:icon="@drawable/ic_menu_back"
|
||||
android:title="@string/back"
|
||||
android:showAsAction="always"/>
|
||||
|
||||
<item android:id="@+id/forward"
|
||||
android:icon="@drawable/ic_menu_forward"
|
||||
android:title="@string/forward"
|
||||
@ -18,11 +23,12 @@
|
||||
<item android:id="@+id/bookmark"
|
||||
android:icon="@drawable/ic_menu_bookmark_add"
|
||||
android:title="@string/bookmark"
|
||||
android:showAsAction="always"/>
|
||||
android:showAsAction="ifRoom"/>
|
||||
|
||||
<item android:id="@+id/share"
|
||||
android:icon="@drawable/ic_menu_share"
|
||||
android:title="@string/share" />
|
||||
android:title="@string/share"
|
||||
android:showAsAction="ifRoom"/>
|
||||
|
||||
<item android:id="@+id/new_tab"
|
||||
android:icon="@drawable/ic_menu_new_tab"
|
||||
|
@ -10,6 +10,11 @@
|
||||
android:title="@string/reload"
|
||||
android:showAsAction="always"/>
|
||||
|
||||
<item android:id="@+id/back"
|
||||
android:icon="@drawable/ic_menu_back"
|
||||
android:title="@string/back"
|
||||
android:visible="false"/>
|
||||
|
||||
<item android:id="@+id/forward"
|
||||
android:icon="@drawable/ic_menu_forward"
|
||||
android:title="@string/forward"
|
||||
@ -22,7 +27,8 @@
|
||||
|
||||
<item android:id="@+id/share"
|
||||
android:icon="@drawable/ic_menu_share"
|
||||
android:title="@string/share" />
|
||||
android:title="@string/share"
|
||||
android:showAsAction="ifRoom"/>
|
||||
|
||||
<item android:id="@+id/new_tab"
|
||||
android:icon="@drawable/ic_menu_new_tab"
|
||||
|
@ -9,6 +9,11 @@
|
||||
android:icon="@drawable/ic_menu_reload"
|
||||
android:title="@string/reload"/>
|
||||
|
||||
<item android:id="@+id/back"
|
||||
android:icon="@drawable/ic_menu_back"
|
||||
android:title="@string/back"
|
||||
android:visible="false"/>
|
||||
|
||||
<item android:id="@+id/forward"
|
||||
android:icon="@drawable/ic_menu_forward"
|
||||
android:title="@string/forward"/>
|
||||
|
@ -61,6 +61,14 @@
|
||||
<item name="android:paddingRight">0dp</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.MenuItemActionBar">
|
||||
<item name="android:layout_width">@dimen/browser_toolbar_height</item>
|
||||
<item name="android:layout_height">@dimen/browser_toolbar_height</item>
|
||||
<item name="android:padding">@dimen/browser_toolbar_button_padding</item>
|
||||
<item name="android:background">@drawable/action_bar_button</item>
|
||||
<item name="android:scaleType">fitCenter</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.BookmarksListView" parent="Widget.HomeListView">
|
||||
<item name="android:paddingTop">30dp</item>
|
||||
<item name="android:paddingLeft">32dp</item>
|
||||
|
@ -42,12 +42,14 @@
|
||||
<item name="menuItemActionBarStyle">@style/Widget.MenuItemActionBar</item>
|
||||
<item name="menuItemActionViewStyle">@style/Widget.MenuItemActionView</item>
|
||||
<item name="menuItemDefaultStyle">@style/Widget.MenuItemDefault</item>
|
||||
<item name="menuItemShareActionButtonStyle">@style/Widget.MenuItemShareActionButton</item>
|
||||
<item name="menuItemSecondaryActionBarStyle">@style/Widget.MenuItemSecondaryActionBar</item>
|
||||
<item name="menuItemShareActionButtonStyle">@style/Widget.MenuItemSecondaryActionBar</item>
|
||||
<item name="bookmarksListViewStyle">@style/Widget.BookmarksListView</item>
|
||||
<item name="topSitesGridItemViewStyle">@style/Widget.TopSitesGridItemView</item>
|
||||
<item name="topSitesGridViewStyle">@style/Widget.TopSitesGridView</item>
|
||||
<item name="topSitesThumbnailViewStyle">@style/Widget.TopSitesThumbnailView</item>
|
||||
<item name="homeListViewStyle">@style/Widget.HomeListView</item>
|
||||
<item name="geckoMenuListViewStyle">@style/Widget.GeckoMenuListView</item>
|
||||
<item name="menuItemActionModeStyle">@style/GeckoActionBar.Button</item>
|
||||
<item name="android:actionModeStyle">@style/GeckoActionBar</item>
|
||||
<item name="android:actionButtonStyle">@style/GeckoActionBar.Button</item>
|
||||
|
@ -8,6 +8,9 @@
|
||||
<!-- Theme level attributes -->
|
||||
<declare-styleable name="GeckoTheme">
|
||||
|
||||
<!-- Style for GeckoMenu ListView -->
|
||||
<attr name="geckoMenuListViewStyle" format="reference"/>
|
||||
|
||||
<!-- Style for MenuItemActionBar -->
|
||||
<attr name="menuItemActionBarStyle" format="reference"/>
|
||||
|
||||
@ -20,6 +23,9 @@
|
||||
<!-- Style for MenuItemDefault -->
|
||||
<attr name="menuItemDefaultStyle" format="reference"/>
|
||||
|
||||
<!-- Style for MenuItemActionBar when shown in SecondaryActionBar -->
|
||||
<attr name="menuItemSecondaryActionBarStyle" format="reference"/>
|
||||
|
||||
<!-- Style for MenuItemActionView's ShareActionButton -->
|
||||
<attr name="menuItemShareActionButtonStyle" format="reference"/>
|
||||
|
||||
|
@ -74,25 +74,29 @@
|
||||
<item name="android:minWidth">@dimen/doorhanger_input_width</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.GeckoMenuListView" parent="Widget.ListView">
|
||||
<item name="android:divider">#FFC9D3DC</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.MenuItemActionBar">
|
||||
<item name="android:padding">@dimen/browser_toolbar_button_padding</item>
|
||||
<item name="android:padding">8dip</item>
|
||||
<item name="android:background">@drawable/action_bar_button</item>
|
||||
<item name="android:scaleType">fitCenter</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.MenuItemSecondaryActionBar">
|
||||
<item name="android:padding">8dip</item>
|
||||
<item name="android:background">@drawable/action_bar_button</item>
|
||||
<item name="android:scaleType">centerInside</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.MenuItemActionView">
|
||||
<item name="android:divider">@drawable/divider_vertical</item>
|
||||
<item name="android:showDividers">middle</item>
|
||||
<item name="android:dividerPadding">12dip</item>
|
||||
<item name="android:dividerPadding">0dip</item>
|
||||
<item name="android:gravity">left</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.MenuItemShareActionButton">
|
||||
<item name="android:padding">10dip</item>
|
||||
<item name="android:background">@drawable/action_bar_button</item>
|
||||
<item name="android:scaleType">centerInside</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.MenuItemDefault">
|
||||
<item name="android:paddingLeft">10dip</item>
|
||||
<item name="android:paddingRight">10dip</item>
|
||||
|
@ -82,6 +82,7 @@
|
||||
<item name="topSitesGridViewStyle">@style/Widget.TopSitesGridView</item>
|
||||
<item name="topSitesThumbnailViewStyle">@style/Widget.TopSitesThumbnailView</item>
|
||||
<item name="homeListViewStyle">@style/Widget.HomeListView</item>
|
||||
<item name="geckoMenuListViewStyle">@style/Widget.GeckoMenuListView</item>
|
||||
<item name="menuItemDefaultStyle">@style/Widget.MenuItemDefault</item>
|
||||
<item name="menuItemActionBarStyle">@style/Widget.MenuItemActionBar</item>
|
||||
<item name="menuItemActionModeStyle">@style/GeckoActionBar.Button</item>
|
||||
|
@ -962,6 +962,11 @@ public class BrowserToolbar extends GeckoRelativeLayout
|
||||
setTitle(title);
|
||||
}
|
||||
|
||||
public void showDefaultFavicon() {
|
||||
mFavicon.setImageResource(R.drawable.favicon);
|
||||
mLastFavicon = null;
|
||||
}
|
||||
|
||||
private void setFavicon(Bitmap image) {
|
||||
Log.d(LOGTAG, "setFavicon(" + image + ")");
|
||||
if (Tabs.getInstance().getSelectedTab().getState() == Tab.STATE_LOADING) {
|
||||
|
@ -59,6 +59,14 @@ public class GeckoActionProvider extends ActionProvider {
|
||||
historySize = 2;
|
||||
}
|
||||
|
||||
// Historical data is dependent on past selection of activities.
|
||||
// Activity count is determined by the number of activities that can handle
|
||||
// the particular intent. When no intent is set, the activity count is 0,
|
||||
// while the history count can be a valid number.
|
||||
if (historySize > dataModel.getActivityCount()) {
|
||||
return view;
|
||||
}
|
||||
|
||||
for (int i = 0; i < historySize; i++) {
|
||||
view.addActionButton(dataModel.getActivity(i).loadIcon(packageManager));
|
||||
}
|
||||
@ -105,6 +113,11 @@ public class GeckoActionProvider extends ActionProvider {
|
||||
public void setIntent(Intent intent) {
|
||||
ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mHistoryFileName);
|
||||
dataModel.setIntent(intent);
|
||||
|
||||
// Inform the target listener to refresh it's UI, if needed.
|
||||
if (mOnTargetListener != null) {
|
||||
mOnTargetListener.onTargetSelected();
|
||||
}
|
||||
}
|
||||
|
||||
public void setOnTargetSelectedListener(OnTargetSelectedListener listener) {
|
||||
@ -117,15 +130,16 @@ public class GeckoActionProvider extends ActionProvider {
|
||||
private class Callbacks implements OnMenuItemClickListener,
|
||||
OnClickListener {
|
||||
private void chooseActivity(int index) {
|
||||
if (mOnTargetListener != null)
|
||||
mOnTargetListener.onTargetSelected();
|
||||
|
||||
ActivityChooserModel dataModel = ActivityChooserModel.get(mContext, mHistoryFileName);
|
||||
Intent launchIntent = dataModel.chooseActivity(index);
|
||||
if (launchIntent != null) {
|
||||
launchIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
|
||||
mContext.startActivity(launchIntent);
|
||||
}
|
||||
|
||||
if (mOnTargetListener != null) {
|
||||
mOnTargetListener.onTargetSelected();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -137,15 +137,6 @@ public class GeckoPopupMenu implements GeckoMenu.Callback,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show/hide the arrow pointing to the anchor.
|
||||
*
|
||||
* @param show Show/hide the arrow.
|
||||
*/
|
||||
public void showArrowToAnchor(boolean show) {
|
||||
mMenuPopup.showArrowToAnchor(show);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemSelected(MenuItem item) {
|
||||
if (mClickListener != null)
|
||||
|
@ -6,6 +6,13 @@
|
||||
|
||||
const Cu = Components.utils;
|
||||
|
||||
const PREF_BRANCH = "toolkit.telemetry.";
|
||||
#ifdef MOZ_TELEMETRY_ON_BY_DEFAULT
|
||||
const PREF_ENABLED = PREF_BRANCH + "enabledPreRelease";
|
||||
#else
|
||||
const PREF_ENABLED = PREF_BRANCH + "enabled";
|
||||
#endif
|
||||
|
||||
this.EXPORTED_SYMBOLS = [
|
||||
"UITelemetry",
|
||||
];
|
||||
@ -17,10 +24,55 @@ Cu.import("resource://gre/modules/Services.jsm");
|
||||
*
|
||||
* It implements nsIUITelemetryObserver, defined in nsIAndroidBridge.idl.
|
||||
*/
|
||||
this.UITelemetry = Object.freeze({
|
||||
this.UITelemetry = {
|
||||
_enabled: undefined,
|
||||
_activeSessions: {},
|
||||
_measurements: [],
|
||||
|
||||
// Lazily decide whether telemetry is enabled.
|
||||
get enabled() {
|
||||
if (this._enabled !== undefined) {
|
||||
return this._enabled;
|
||||
}
|
||||
|
||||
// Set an observer to watch for changes at runtime.
|
||||
Services.prefs.addObserver(PREF_ENABLED, this, false);
|
||||
Services.obs.addObserver(this, "profile-before-change", false);
|
||||
|
||||
// Pick up the current value.
|
||||
try {
|
||||
this._enabled = Services.prefs.getBoolPref(PREF_ENABLED);
|
||||
} catch (e) {
|
||||
this._enabled = false;
|
||||
}
|
||||
|
||||
return this._enabled;
|
||||
},
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
if (aTopic == "profile-before-change") {
|
||||
Services.obs.removeObserver(this, "profile-before-change");
|
||||
Services.prefs.removeObserver(PREF_ENABLED, this);
|
||||
this._enabled = undefined;
|
||||
return;
|
||||
}
|
||||
|
||||
if (aTopic == "nsPref:changed") {
|
||||
switch (aData) {
|
||||
case PREF_ENABLED:
|
||||
let on = Services.prefs.getBoolPref(PREF_ENABLED);
|
||||
this._enabled = on;
|
||||
|
||||
// Wipe ourselves if we were just disabled.
|
||||
if (!on) {
|
||||
this._activeSessions = {};
|
||||
this._measurements = [];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* This exists exclusively for testing -- our events are not intended to
|
||||
* be retrieved via an XPCOM interface.
|
||||
@ -46,6 +98,10 @@ this.UITelemetry = Object.freeze({
|
||||
* All extant sessions will be recorded by name for each event.
|
||||
*/
|
||||
addEvent: function(aAction, aMethod, aTimestamp, aExtras) {
|
||||
if (!this.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
let sessions = Object.keys(this._activeSessions);
|
||||
let aEvent = {
|
||||
type: "event",
|
||||
@ -66,6 +122,10 @@ this.UITelemetry = Object.freeze({
|
||||
* Begins tracking a session by storing a timestamp for session start.
|
||||
*/
|
||||
startSession: function(aName, aTimestamp) {
|
||||
if (!this.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._activeSessions[aName]) {
|
||||
// Do not overwrite a previous event start if it already exists.
|
||||
return;
|
||||
@ -77,6 +137,10 @@ this.UITelemetry = Object.freeze({
|
||||
* Tracks the end of a session with a timestamp.
|
||||
*/
|
||||
stopSession: function(aName, aReason, aTimestamp) {
|
||||
if (!this.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
let sessionStart = this._activeSessions[aName];
|
||||
delete this._activeSessions[aName];
|
||||
|
||||
@ -107,6 +171,10 @@ this.UITelemetry = Object.freeze({
|
||||
* results of those functions.
|
||||
*/
|
||||
getSimpleMeasures: function() {
|
||||
if (!this.enabled) {
|
||||
return {};
|
||||
}
|
||||
|
||||
let result = {};
|
||||
for (let name in this._simpleMeasureFunctions) {
|
||||
result[name] = this._simpleMeasureFunctions[name]();
|
||||
@ -124,6 +192,10 @@ this.UITelemetry = Object.freeze({
|
||||
* registered for it.
|
||||
*/
|
||||
addSimpleMeasureFunction: function(aName, aFunction) {
|
||||
if (!this.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aName in this._simpleMeasureFunctions) {
|
||||
throw new Error("A simple measurement function is already registered for " + aName);
|
||||
}
|
||||
@ -139,7 +211,11 @@ this.UITelemetry = Object.freeze({
|
||||
delete this._simpleMeasureFunctions[aName];
|
||||
},
|
||||
|
||||
getUIMeasurements: function getUIMeasurements() {
|
||||
getUIMeasurements: function() {
|
||||
if (!this.enabled) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return this._measurements.slice();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -35,6 +35,9 @@ EXTRA_JS_MODULES += [
|
||||
'TelemetryFile.jsm',
|
||||
'TelemetryStopwatch.jsm',
|
||||
'ThirdPartyCookieProbe.jsm',
|
||||
]
|
||||
|
||||
EXTRA_PP_JS_MODULES += [
|
||||
'UITelemetry.jsm',
|
||||
]
|
||||
|
||||
|
@ -778,6 +778,9 @@ this.AddonRepository = {
|
||||
getService(Ci.nsIAppStartup).
|
||||
getStartupInfo();
|
||||
|
||||
params.TIME_MAIN = "";
|
||||
params.TIME_FIRST_PAINT = "";
|
||||
params.TIME_SESSION_RESTORED = "";
|
||||
if (startupInfo.process) {
|
||||
if (startupInfo.main) {
|
||||
params.TIME_MAIN = startupInfo.main - startupInfo.process;
|
||||
|