Replace the top menu bar with a tab panel and links
This removes the need for an implicit FocusPanel from the GWT library,
but still allows the user to implement keyboard navigation.
Signed-off-by: Shawn O. Pearce <sop@google.com>
diff --git a/src/main/java/com/google/gerrit/client/Gerrit.java b/src/main/java/com/google/gerrit/client/Gerrit.java
index 0608d6d..28c3c4c 100644
--- a/src/main/java/com/google/gerrit/client/Gerrit.java
+++ b/src/main/java/com/google/gerrit/client/Gerrit.java
@@ -33,10 +33,13 @@
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
-import com.google.gwt.user.client.ui.MenuBar;
-import com.google.gwt.user.client.ui.MenuItem;
+import com.google.gwt.user.client.ui.InlineLabel;
import com.google.gwt.user.client.ui.RootPanel;
+import com.google.gwt.user.client.ui.TabPanel;
+import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
import com.google.gwtexpui.user.client.UserAgent;
import com.google.gwtexpui.user.client.ViewSite;
import com.google.gwtjsonrpc.client.JsonUtil;
@@ -64,7 +67,8 @@
private static final ArrayList<SignedInListener> signedInListeners =
new ArrayList<SignedInListener>();
- private static LinkMenuBar menuBar;
+ private static TabPanel menuLeft;
+ private static LinkMenuBar menuRight;
private static RootPanel siteHeader;
private static RootPanel siteFooter;
private static ViewSite<Screen> body;
@@ -159,9 +163,21 @@
initHistoryHooks();
populateBottomMenu();
- final RootPanel topMenu = RootPanel.get("gerrit_topmenu");
- menuBar = new LinkMenuBar();
- topMenu.add(menuBar);
+ final RootPanel menuArea = RootPanel.get("gerrit_topmenu");
+ final Grid menuLine = new Grid(1, 3);
+ menuLeft = new TabPanel();
+ menuRight = new LinkMenuBar();
+ menuLeft.setStyleName("gerrit-topmenu-menuLeft");
+ menuRight.addStyleName("gerrit-topmenu-menuRight");
+ menuLine.setStyleName("gerrit-topmenu");
+ menuArea.add(menuLine);
+ menuLine.setWidget(0, 0, menuLeft);
+ menuLine.setWidget(0, 1, new FlowPanel());
+ menuLine.setWidget(0, 2, menuRight);
+ final CellFormatter fmt = menuLine.getCellFormatter();
+ fmt.setStyleName(0, 0, "gerrit-topmenu-TDmenu");
+ fmt.setStyleName(0, 1, "gerrit-topmenu-TDglue");
+ fmt.setStyleName(0, 2, "gerrit-topmenu-TDmenu");
siteHeader = RootPanel.get("gerrit_header");
siteFooter = RootPanel.get("gerrit_footer");
@@ -175,7 +191,7 @@
};
RootPanel.get("gerrit_body").add(body);
- JsonUtil.addRpcStatusListener(new RpcStatus(topMenu));
+ JsonUtil.addRpcStatusListener(new RpcStatus(menuArea));
SYSTEM_SVC.loadGerritConfig(new GerritCallback<GerritConfig>() {
public void onSuccess(final GerritConfig result) {
Common.setGerritConfig(result);
@@ -314,39 +330,39 @@
}
public static void refreshMenuBar() {
- menuBar.clearItems();
+ menuLeft.clear();
+ menuRight.clear();
final boolean signedIn = isSignedIn();
- MenuBar m;
+ LinkMenuBar m;
- m = new MenuBar(true);
+ m = new LinkMenuBar();
addLink(m, C.menuAllOpen(), Link.ALL_OPEN);
addLink(m, C.menuAllMerged(), Link.ALL_MERGED);
addLink(m, C.menuAllAbandoned(), Link.ALL_ABANDONED);
- menuBar.addItem(C.menuAll(), m);
+ menuLeft.add(m, C.menuAll());
if (signedIn) {
- m = new MenuBar(true);
+ m = new LinkMenuBar();
addLink(m, C.menuMyChanges(), Link.MINE);
addLink(m, C.menyMyDrafts(), Link.MINE_DRAFTS);
addLink(m, C.menuMyStarredChanges(), Link.MINE_STARRED);
- addLink(m, C.menuSettings(), Link.SETTINGS);
- menuBar.addItem(C.menuMine(), m);
+ menuLeft.add(m, C.menuMine());
+ menuLeft.selectTab(1);
+ } else {
+ menuLeft.selectTab(0);
}
if (signedIn) {
- m = new MenuBar(true);
+ m = new LinkMenuBar();
addLink(m, C.menuGroups(), Link.ADMIN_GROUPS);
addLink(m, C.menuProjects(), Link.ADMIN_PROJECTS);
- menuBar.addItem(C.menuAdmin(), m);
+ menuLeft.add(m, C.menuAdmin());
}
- menuBar.lastInGroup();
- menuBar.addGlue();
-
if (signedIn) {
whoAmI();
- menuBar.addItem(new LinkMenuItem(C.menuSettings(), Link.SETTINGS));
+ addLink(menuRight, C.menuSettings(), Link.SETTINGS);
boolean signout = false;
switch (Common.getGerritConfig().getLoginType()) {
case HTTP:
@@ -358,7 +374,7 @@
break;
}
if (signout || (GWT.isClient() && !GWT.isScript())) {
- menuBar.addItem(C.menuSignOut(), new Command() {
+ menuRight.addItem(C.menuSignOut(), new Command() {
public void execute() {
doSignOut();
}
@@ -371,7 +387,7 @@
case OPENID:
default:
- menuBar.addItem(C.menuSignIn(), new Command() {
+ menuRight.addItem(C.menuSignIn(), new Command() {
public void execute() {
doSignIn();
}
@@ -379,14 +395,13 @@
break;
}
if (GWT.isClient() && !GWT.isScript()) {
- menuBar.addItem("Become", new Command() {
+ menuRight.addItem("Become", new Command() {
public void execute() {
Window.Location.assign(GWT.getHostPageBaseURL() + "become");
}
});
}
}
- menuBar.lastInGroup();
final boolean view = myAccount == null || myAccount.isShowSiteHeader();
if (siteHeader != null) {
@@ -399,12 +414,12 @@
private static void whoAmI() {
final String name = FormatUtil.nameEmail(getUserAccount());
- final MenuItem me = menuBar.addItem(name, (Command) null);
- me.removeStyleName("gwt-MenuItem");
- me.addStyleName("gerrit-MenuBarUserName");
+ final InlineLabel l = new InlineLabel(name);
+ l.setStyleName("gerrit-MenuBarUserName");
+ menuRight.add(l);
}
- private static void addLink(final MenuBar m, final String text,
+ private static void addLink(final LinkMenuBar m, final String text,
final String historyToken) {
m.addItem(new LinkMenuItem(text, historyToken));
}
diff --git a/src/main/java/com/google/gerrit/client/changes/ChangeScreen.java b/src/main/java/com/google/gerrit/client/changes/ChangeScreen.java
index 6793efa..d41db2a 100644
--- a/src/main/java/com/google/gerrit/client/changes/ChangeScreen.java
+++ b/src/main/java/com/google/gerrit/client/changes/ChangeScreen.java
@@ -328,7 +328,6 @@
});
m.addItem(Util.C.messageExpandAll(), new ExpandAllCommand(c, true));
m.addItem(Util.C.messageCollapseAll(), new ExpandAllCommand(c, false));
- m.lastInGroup();
return m;
}
diff --git a/src/main/java/com/google/gerrit/client/ui/CommandMenuItem.java b/src/main/java/com/google/gerrit/client/ui/CommandMenuItem.java
new file mode 100644
index 0000000..e2dc555
--- /dev/null
+++ b/src/main/java/com/google/gerrit/client/ui/CommandMenuItem.java
@@ -0,0 +1,38 @@
+// Copyright (C) 2009 The Android Open Source Project
+//
+// 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 com.google.gerrit.client.ui;
+
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.ui.Accessibility;
+import com.google.gwt.user.client.ui.Anchor;
+
+public class CommandMenuItem extends Anchor implements ClickHandler {
+ private final Command command;
+
+ public CommandMenuItem(final String text, final Command cmd) {
+ super(text);
+ setStyleName("gerrit-MenuItem");
+ Accessibility.setRole(getElement(), Accessibility.ROLE_MENUITEM);
+ addClickHandler(this);
+ command = cmd;
+ }
+
+ @Override
+ public void onClick(final ClickEvent event) {
+ command.execute();
+ }
+}
diff --git a/src/main/java/com/google/gerrit/client/ui/LinkMenuBar.java b/src/main/java/com/google/gerrit/client/ui/LinkMenuBar.java
index a0055f4..0fef53b 100644
--- a/src/main/java/com/google/gerrit/client/ui/LinkMenuBar.java
+++ b/src/main/java/com/google/gerrit/client/ui/LinkMenuBar.java
@@ -14,44 +14,44 @@
package com.google.gerrit.client.ui;
-import com.google.gwt.user.client.ui.MenuBar;
-import com.google.gwt.user.client.ui.MenuItem;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.ui.Accessibility;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.Widget;
-/** A GWT MenuBar, rendering its items as through they were normal links. */
-public class LinkMenuBar extends MenuBar {
+public class LinkMenuBar extends Composite {
+ private final FlowPanel body;
+
public LinkMenuBar() {
+ body = new FlowPanel();
+ initWidget(body);
setStyleName("gerrit-LinkMenuBar");
+ Accessibility.setRole(getElement(), Accessibility.ROLE_MENUBAR);
}
- @Override
- public MenuItem addItem(final MenuItem item) {
- item.addStyleDependentName("NormalItem");
- return super.addItem(item);
+ public void addItem(final String text, final Command imp) {
+ add(new CommandMenuItem(text, imp));
}
- /**
- * Add a cell to fill the screen width.
- * <p>
- * The glue has 100% width, forcing the browser to align out the next element
- * as far right as possible. If there is exactly 1 glue in the menu bar, the
- * bar is split into a left and right section. If there are 2 glues, the bar
- * will be split into thirds.
- */
- public void addGlue() {
- addSeparator().setStyleName("gerrit-FillMenuCenter");
+ public void addItem(final CommandMenuItem i) {
+ add(i);
}
- /**
- * Mark this item as the last in its group, so it has no border.
- * <p>
- * Usually this is used just before {@link #addGlue()} and after the last item
- * has been added.
- */
- public void lastInGroup() {
- if (!getItems().isEmpty()) {
- final MenuItem i = getItems().get(getItems().size() - 1);
- i.removeStyleDependentName("NormalItem");
- i.addStyleDependentName("LastItem");
+ public void addItem(final LinkMenuItem i) {
+ add(i);
+ }
+
+ public void clear() {
+ body.clear();
+ }
+
+ public void add(final Widget i) {
+ if (body.getWidgetCount() > 0) {
+ final Widget p = body.getWidget(body.getWidgetCount() - 1);
+ p.addStyleName("gerrit-LinkMenuItem-NotLast");
}
+ i.addStyleName("gerrit-LinkMenuItem");
+ body.add(i);
}
}
diff --git a/src/main/java/com/google/gerrit/client/ui/LinkMenuItem.java b/src/main/java/com/google/gerrit/client/ui/LinkMenuItem.java
index df98c67..ab4da2a 100644
--- a/src/main/java/com/google/gerrit/client/ui/LinkMenuItem.java
+++ b/src/main/java/com/google/gerrit/client/ui/LinkMenuItem.java
@@ -14,35 +14,13 @@
package com.google.gerrit.client.ui;
-import com.google.gwt.user.client.Command;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.History;
-import com.google.gwt.user.client.ui.MenuItem;
+import com.google.gwt.user.client.ui.Accessibility;
+import com.google.gwt.user.client.ui.Hyperlink;
-/**
- * A GWT {@link MenuItem} that uses a normal HTML link widget for its UI.
- * <p>
- * Using this widget instead of MenuItem permits the menu item to have the
- * standard right-click "Open in new window" and "Open in new tab" feature found
- * in popular browsers.
- */
-public class LinkMenuItem extends MenuItem {
- /**
- * Creates a hyperlink with its text and target history token specified.
- *
- * @param text the hyperlink's text
- * @param targetHistoryToken the history token to which it will link
- */
+public class LinkMenuItem extends Hyperlink {
public LinkMenuItem(final String text, final String targetHistoryToken) {
- super("", new Command() {
- public void execute() {
- History.newItem(targetHistoryToken);
- }
- });
- final Element a = DOM.createAnchor();
- DOM.setElementProperty(a, "href", "#" + targetHistoryToken);
- DOM.setInnerText(a, text);
- DOM.appendChild(getElement(), a);
+ super(text, targetHistoryToken);
+ setStyleName("gerrit-MenuItem");
+ Accessibility.setRole(getElement(), Accessibility.ROLE_MENUITEM);
}
}
diff --git a/src/main/java/com/google/gerrit/public/gerrit.css b/src/main/java/com/google/gerrit/public/gerrit.css
index da6de82..78daa09 100644
--- a/src/main/java/com/google/gerrit/public/gerrit.css
+++ b/src/main/java/com/google/gerrit/public/gerrit.css
@@ -3,12 +3,7 @@
padding-top: 5px;
padding-left: 5px;
padding-right: 5px;
- height: 15px;
-}
-#gerrit_endtopmenu {
- clear: both;
- height: 5px;
- border-bottom: 1px solid #B0BDCC;
+ background: #d4e9a9;
}
#gerrit_body {
font-size: 11pt;
@@ -72,35 +67,71 @@
/** Menu **/
-.gwt-MenuItem a,
-.gwt-MenuItem a:visited,
-.gwt-MenuItem a:hover {
- color: #2a5db0;
-}
-.gerrit-LinkMenuBar .gwt-MenuItem {
+.gerrit-LinkMenuBar {
font-size: 9pt;
- color: #2a5db0;
- text-decoration: underline;
+ display: inline;
+ white-space: nowrap;
+}
+.gerrit-MenuItem {
+ display: inline;
padding-left: 5px;
padding-right: 5px;
- white-space: nowrap;
- cursor: pointer;
- cursor: hand;
}
-.gerrit-LinkMenuBar .gwt-MenuItem-NormalItem {
+.gerrit-LinkMenuItem-NotLast {
border-right: 1px solid black;
}
-.gerrit-LinkMenuBar .gwt-MenuItem-LastItem {
-}
-.gerrit-FillMenuCenter {
+
+.gerrit-topmenu {
width: 100%;
}
-.gwt-MenuItem .gwt-Hyperlink {
- font-size: 9pt;
- white-space: nowrap;
+.gerrit-topmenu-TDmenu {
+ vertical-align: top;
+}
+.gerrit-topmenu-TDglue {
+ width: 100%;
+}
+.gerrit-topmenu-menuLeft {
+ width: 300px;
+ border-left: 1px solid #d4e9a9;
+ border-right: 1px solid #d4e9a9;
+ border-bottom: 1px solid #d4e9a9;
+}
+.gerrit-topmenu-menuLeft .gwt-TabBarFirst {
+ display: none;
+}
+.gerrit-topmenu-menuLeft .gwt-TabBarItem {
+ margin: 0px;
+ background: #d4e9a9;
+ padding-top: 0px;
+ padding-bottom: 1px;
+ padding-left: 1em;
+ padding-right: 1em;
+ border-right: 1px solid black;
+}
+.gerrit-topmenu-menuLeft .gwt-TabBarItem-selected {
+ background: #ffffcc;
+}
+.gerrit-topmenu-menuLeft .gwt-TabBarRest {
+ background: #d4e9a9;
+}
+.gerrit-topmenu-menuLeft .gwt-TabPanelBottom {
+ background: #d4e9a9;
+ border-top: 1px solid black;
+ border-left: none;
+ border-right: none;
+ border-bottom: none;
+ padding: 1px;
+}
+.gerrit-topmenu-menuLeft .gerrit-MenuItem {
+ padding-left: 1em;
+ padding-right: 1em;
+ border-right: none;
+}
+
+.gerrit-topmenu-menuRight {
+ float: right;
}
.gerrit-MenuBarUserName {
- font-size: 9pt;
font-weight: bold;
padding-left: 5px;
padding-right: 5px;
diff --git a/src/main/webapp/WEB-INF/Gerrit.html b/src/main/webapp/WEB-INF/Gerrit.html
index 87dd74a..424cbb0 100644
--- a/src/main/webapp/WEB-INF/Gerrit.html
+++ b/src/main/webapp/WEB-INF/Gerrit.html
@@ -10,7 +10,6 @@
</head>
<body>
<div id="gerrit_topmenu"></div>
- <div id="gerrit_endtopmenu"></div>
<div id="gerrit_header"></div>
<div id="gerrit_startinggerrit" style="margin-left: 10px;">
<p>Loading <a href="http://code.google.com/p/gerrit/" target="_blank">Gerrit Code Review</a> ...</p>