Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keyboard Navigation #3193

Open
wants to merge 44 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
31e818b
Focus component search box with /
Venkata-Sai-Vishwanath-robo Jul 5, 2024
fe22d80
shortcuts for refreshing companion screen and resetting connection
Venkata-Sai-Vishwanath-robo Jul 5, 2024
a6cd6c5
Rename component with Alt + R
Venkata-Sai-Vishwanath-robo Jul 5, 2024
800c48c
Switch between design and blocks view
Venkata-Sai-Vishwanath-robo Jul 7, 2024
9c4646c
Navigation for the project explorer
Venkata-Sai-Vishwanath-robo Jul 7, 2024
e9af08a
Navigation for dropdowns
Venkata-Sai-Vishwanath-robo Jul 7, 2024
ec12849
css
Venkata-Sai-Vishwanath-robo Jul 7, 2024
64b4e99
Merge branch 'master' into keyboardNavigation
Venkata-Sai-Vishwanath-robo Jul 7, 2024
e8fc45a
shortcuts for blockly editor
Venkata-Sai-Vishwanath-robo Jul 7, 2024
b699190
Merge branch 'keyboardNavigation' of https://github.com/Venkata-Sai-V…
Venkata-Sai-Vishwanath-robo Jul 7, 2024
87eb4c5
checkbox text for screen readers
Venkata-Sai-Vishwanath-robo Jul 8, 2024
14501ed
Accessibility
Venkata-Sai-Vishwanath-robo Jul 8, 2024
d1f02f6
Tooltips and messages
Venkata-Sai-Vishwanath-robo Jul 8, 2024
b296f6c
better version of project explorer navigation
Venkata-Sai-Vishwanath-robo Jul 10, 2024
4e2a979
neo
Venkata-Sai-Vishwanath-robo Jul 14, 2024
d53b293
adding components using keyboard only
Venkata-Sai-Vishwanath-robo Jul 31, 2024
347b05b
focus SourceStructureExplorerItem on selection change.
Venkata-Sai-Vishwanath-robo Jul 31, 2024
79f7391
Focus trap for new folder and new project dialog box
Venkata-Sai-Vishwanath-robo Jul 31, 2024
6115d95
component adding
Venkata-Sai-Vishwanath-robo Aug 5, 2024
cd1c39e
property editors made keyboard accessible
Venkata-Sai-Vishwanath-robo Aug 8, 2024
18484a3
better focus visibility for checkboxes and ColorChoicePropertyEditor
Venkata-Sai-Vishwanath-robo Aug 8, 2024
f4cb850
Dropdown button maintaing focus, check box visibility and UI settings…
Venkata-Sai-Vishwanath-robo Aug 11, 2024
9a96f1a
Color choice property editor maintains focus after selection.
Venkata-Sai-Vishwanath-robo Aug 11, 2024
25d4f32
tree highlight and focus-trap in move projects dialog
Venkata-Sai-Vishwanath-robo Aug 14, 2024
e7e3b0f
Focus search text box with / (better code)
Venkata-Sai-Vishwanath-robo Aug 19, 2024
e5d131f
single line imports
Venkata-Sai-Vishwanath-robo Aug 19, 2024
dc22e43
fix : Constructor visibility
Venkata-Sai-Vishwanath-robo Aug 19, 2024
5963325
dialog boxes
Venkata-Sai-Vishwanath-robo Aug 23, 2024
b6f6330
updated isTextboxFocused method
Venkata-Sai-Vishwanath-robo Aug 23, 2024
2a52e64
Update: Component adding
Venkata-Sai-Vishwanath-robo Aug 25, 2024
4c98faf
Shortcuts Dialog box
Venkata-Sai-Vishwanath-robo Aug 25, 2024
5f40827
fix: shortcuts dialog
Venkata-Sai-Vishwanath-robo Aug 26, 2024
ce12f23
Component Moving
Venkata-Sai-Vishwanath-robo Aug 26, 2024
7ecfa20
tree highlighting upon click
Venkata-Sai-Vishwanath-robo Aug 26, 2024
ab4c3d4
Shortcuts dialog for neo
Venkata-Sai-Vishwanath-robo Aug 28, 2024
1ea4775
Shortcuts to focus the Viewer and Properties, using V and P
Venkata-Sai-Vishwanath-robo Sep 1, 2024
0244b78
fix: dropdown opens with no pre-selected item.
Venkata-Sai-Vishwanath-robo Sep 8, 2024
7e7cad3
chore: remove unused code.
Venkata-Sai-Vishwanath-robo Sep 8, 2024
080be5d
revert: remove unused code.
Venkata-Sai-Vishwanath-robo Sep 8, 2024
91df4cc
OK button addded to shortcuts dialog and fixed shortcut for diff keyb…
Venkata-Sai-Vishwanath-robo Dec 15, 2024
b46f841
variable colors
Venkata-Sai-Vishwanath-robo Dec 15, 2024
87d768b
fix: shortcut
Venkata-Sai-Vishwanath-robo Dec 16, 2024
4547532
fix: Shortcuts
Venkata-Sai-Vishwanath-robo Dec 27, 2024
2a917bb
fix: dialogs
Venkata-Sai-Vishwanath-robo Dec 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions appinventor/appengine/src/com/google/appinventor/client/Ode.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.google.appinventor.client.editor.EditorManager;
import com.google.appinventor.client.editor.FileEditor;
import com.google.appinventor.client.editor.ProjectEditor;
import com.google.appinventor.client.editor.simple.components.MockComponent;
import com.google.appinventor.client.editor.simple.palette.DropTargetProvider;
import com.google.appinventor.client.editor.youngandroid.BlocklyPanel;
import com.google.appinventor.client.editor.youngandroid.DesignToolbar;
Expand Down Expand Up @@ -82,7 +83,11 @@
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.RunAsyncCallback;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.MouseWheelEvent;
import com.google.gwt.event.dom.client.MouseWheelHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
Expand All @@ -94,6 +99,7 @@
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Event.NativePreviewEvent;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
Expand All @@ -117,6 +123,8 @@
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.widgetideas.client.event.KeyDownHandler;

import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
Expand Down Expand Up @@ -1609,6 +1617,15 @@ public DialogBox createEmptyTrashDialog(boolean showDialog) {
dialogBox.show();
}

Event.addNativePreviewHandler(new Event.NativePreviewHandler() {
@Override
public void onPreviewNativeEvent(Event.NativePreviewEvent event) {
if (event.getTypeInt() == Event.ONKEYDOWN && dialogBox.isShowing()) {
dialogBox.hide();
}
}
});

return dialogBox;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -655,15 +655,15 @@ public interface OdeMessages extends Messages, AutogeneratedOdeMessages {
@Description("Message providing details about starting a USB connection.")
String usbMenuItem();

@DefaultMessage("Reset Connection")
@DefaultMessage("Reset Connection (Alt + Shift + R)")
SusanRatiLane marked this conversation as resolved.
Show resolved Hide resolved
@Description("Reset all connections.")
String resetConnectionsMenuItem();

@DefaultMessage("Hard Reset")
@Description("Hard Reset the Emulator.")
String hardResetConnectionsMenuItem();

@DefaultMessage("Refresh Companion Screen")
@DefaultMessage("Refresh Companion Screen (Alt + R)")
@Description("Refresh the companion screen.")
String refreshCompanionMenuItem();

Expand Down Expand Up @@ -725,6 +725,10 @@ public interface OdeMessages extends Messages, AutogeneratedOdeMessages {
@Description("Redisplay the Splash Screen")
String showSplashMenuItem();

@DefaultMessage("Show Keyboard Shortcuts (Alt + ?)")
@Description("Display the Shortcuts dialog")
String showShortcuts();

@DefaultMessage("Library")
@Description("Name of Library link")
String libraryMenuItem();
Expand Down Expand Up @@ -1254,7 +1258,7 @@ public interface OdeMessages extends Messages, AutogeneratedOdeMessages {
String blocksLoadFailure(String formName);

// Used in editor/youngandroid/palette/YoungAndroidPalettePanel.java
@DefaultMessage("Search Components...")
@DefaultMessage("Type / to search components")
@Description("Text shown in the component palette search box")
String searchComponents();

Expand Down Expand Up @@ -5119,6 +5123,39 @@ String newerVersionComponentException(String componentType, int srcCompVersion,
@Description("")
String MaximumRangeMethods();

@DefaultMessage(
"<table border='1' cellpadding='8' cellspacing='0'>" +
"<thead>" +
"<tr>" +
"<th>Action</th>" +
"<th>Key Combination</th>" +
"</tr>" +
"</thead>" +
"<tbody>" +
"<tr><td>Focus Component search box</td><td>/</td></tr>" +
"<tr><td>Focus Components tree</td><td>T</td></tr>" +
"<tr><td>Focus Viewer</td><td>V</td></tr>" +
"<tr><td>Focus Properties Panel</td><td>P</td></tr>" +
Venkata-Sai-Vishwanath-robo marked this conversation as resolved.
Show resolved Hide resolved
"<tr><td>Switch between Designer and Block editor</td><td>Ctrl + Alt</td></tr>" +
"<tr><td>Rename Component</td><td>Alt + N</td></tr>" +
Venkata-Sai-Vishwanath-robo marked this conversation as resolved.
Show resolved Hide resolved
"<tr><td>Reset Connection</td><td>Alt + Shift + R</td></tr>" +
"<tr><td>Refresh Companion Screen</td><td>Alt + R</td></tr>" +
"<tr><td>Open/Close Backpack</td><td>Alt + B</td></tr>" +
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alt(Opt)-B also does not seem to work for me on either Firefox or Chrome. I'm still not sure what makes these key combinations distinctive.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Alt + B shortcut was implemented in a way so that it works only when the user clicks on the blockly workspace to make it active, this was done because if the shortcut was pressed in the designer view then the backpack flyout opens but in a weird way where the blocks are outside of the flyout.

"<tr><td>Switch between Inline and External Inputs</td><td>Alt + I</td></tr>" +
"<tr><td>Add comment to a block</td><td>Alt + K</td></tr>" +
"<tr><td>Expand/Collapse block</td><td>Alt + O</td></tr>" +
"<tr><td>Navigate up the blocks</td><td>Alt + S</td></tr>" +
"<tr><td>Navigate down the blocks</td><td>Alt + W</td></tr>" +
"<tr><td>Zoom in</td><td>Alt + +</td></tr>" +
"<tr><td>Zoom out</td><td>Alt + -</td></tr>" +
"<tr><td>Re-center</td><td>Alt + G</td></tr>" +
"<tr><td>Navigate Components</td><td>↑/↓</td></tr>" +
Venkata-Sai-Vishwanath-robo marked this conversation as resolved.
Show resolved Hide resolved
"<tr><td>Open this dialog</td><td>Alt + ?</td></tr>" +
"</tbody>" +
"</table>")
Venkata-Sai-Vishwanath-robo marked this conversation as resolved.
Show resolved Hide resolved
@Description("")
String KeyBoardShortcuts();

// =========== ListPicker
@DefaultMessage("ItemTextColor")
@Description("")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,9 @@
<ai:DropDownItem name="ShowSplash" caption="{messages.showSplashMenuItem}">
<actions:ShowSplashAction/>
</ai:DropDownItem>
<ai:DropDownItem name="ShowShortcuts" caption="{messages.showShortcuts}">
<actions:ShowShortcutsAction/>
</ai:DropDownItem>
</ai:DropDownButton>

<!-- Admin Menu -->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// -*- mode: java; c-basic-offset: 2; -*-
// Copyright 2009-2011 Google, All Rights reserved
// Copyright 2011-2023 MIT, All rights reserved
// Released under the Apache License, Version 2.0
// http://www.apache.org/licenses/LICENSE-2.0

package com.google.appinventor.client.actions;

import static com.google.appinventor.client.Ode.MESSAGES;

import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.VerticalPanel;

public class ShowShortcutsAction implements Command {

private DialogBox db;

SusanRatiLane marked this conversation as resolved.
Show resolved Hide resolved
public ShowShortcutsAction() {
db = new DialogBox(true, false);
db.setText("Keyboard Shortcuts");
db.setStyleName("ode-DialogBox");
db.setHeight("200px");
db.setWidth("400px");
db.setGlassEnabled(true);
db.setAnimationEnabled(true);

shortcutKeyHandler();
}

@Override
public void execute() {
VerticalPanel DialogBoxContents = new VerticalPanel();
SusanRatiLane marked this conversation as resolved.
Show resolved Hide resolved
HTML message = new HTML(MESSAGES.KeyBoardShortcuts());
DialogBoxContents.add(message);
db.setWidget(DialogBoxContents);
db.center();
db.show();
}

private void shortcutKeyHandler() {
Event.addNativePreviewHandler(new Event.NativePreviewHandler() {
@Override
public void onPreviewNativeEvent(Event.NativePreviewEvent event) {
NativeEvent nativeEvent = event.getNativeEvent();
if (event.getTypeInt() == Event.ONKEYDOWN && nativeEvent.getAltKey() && nativeEvent.getKeyCode() == 191 && !db.isShowing()) {
nativeEvent.preventDefault();
execute();
} else if (event.getTypeInt() == Event.ONKEYDOWN && db.isShowing()) {
nativeEvent.preventDefault();
db.hide();
}
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
Expand All @@ -42,6 +43,7 @@ interface SimpleVisibleComponentsPanelUiBinder extends UiBinder<VerticalPanel, S
@UiField(provided = true) protected ListBox listboxPhonePreview; // A ListBox for Holo/Material/iOS preview styles
private final int[][] drop_lst = { {320, 505}, {480, 675}, {768, 1024} };
private final String[] drop_lst_phone_preview = { "Android Material", "Android Holo", "iOS" };
@UiField protected CheckBox HiddenComponentsCheckbox;

// Corresponding panel for non-visible components (because we allow users to drop
// non-visible components onto the form, but we show them in the non-visible
Expand Down Expand Up @@ -218,6 +220,10 @@ public void enablePhonePreviewCheckBox(boolean enable){
listboxPhonePreview.setEnabled(enable);
}

public void focusCheckbox() {
HiddenComponentsCheckbox.setFocus(true);
}

/**
* Associates a Simple form component with this panel.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<ui:with field="messages" type="com.google.appinventor.client.OdeMessages"/>
<g:VerticalPanel styleName="ode-SimpleFormDesigner">
<g:VerticalPanel ui:field="phoneScreen" stylePrimaryName="ode-SimpleFormDesigner">
<ed:HiddenComponentsCheckbox text="{messages.showHiddenComponentsCheckbox}"/>
<ed:HiddenComponentsCheckbox ui:field="HiddenComponentsCheckbox" text="{messages.showHiddenComponentsCheckbox}"/>
<g:ListBox ui:field="listboxPhoneTablet">
<g:item value="0">
<ui:text from="{messages.previewPhoneSize}"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,12 @@
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.DomEvent;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.dom.client.HasAllTouchHandlers;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.event.dom.client.TouchCancelHandler;
import com.google.gwt.event.dom.client.TouchEndHandler;
import com.google.gwt.event.dom.client.TouchMoveHandler;
Expand Down Expand Up @@ -110,22 +112,25 @@ private class RenameDialog extends DialogBox {
private final LabeledTextBox newNameTextBox;

RenameDialog(String oldName) {
super(false, true);

super(false, false);
setGlassEnabled(true);
setStylePrimaryName("ode-DialogBox");
setText(MESSAGES.renameTitle());
VerticalPanel contentPanel = new VerticalPanel();

Button topInvisible = new Button();
contentPanel.add(topInvisible);

LabeledTextBox oldNameTextBox = new LabeledTextBox(MESSAGES.oldNameLabel());
oldNameTextBox.setText(getName());
oldNameTextBox.setEnabled(false);
contentPanel.add(oldNameTextBox);

newNameTextBox = new LabeledTextBox(MESSAGES.newNameLabel());
newNameTextBox.setText(oldName);
newNameTextBox.getTextBox().addKeyUpHandler(new KeyUpHandler() {
newNameTextBox.getTextBox().addKeyDownHandler(new KeyDownHandler() {
@Override
public void onKeyUp(KeyUpEvent event) {
public void onKeyDown(KeyDownEvent event) {
int keyCode = event.getNativeKeyCode();
if (keyCode == KeyCodes.KEY_ENTER) {
handleOkClick();
Expand All @@ -150,9 +155,26 @@ public void onClick(ClickEvent event) {
handleOkClick();
}
});

Button bottomInvisible = new Button();
bottomInvisible.setStyleName("FocusTrap");
topInvisible.setStyleName("FocusTrap");
topInvisible.addFocusHandler(new FocusHandler() {
@Override
public void onFocus(FocusEvent event) {
okButton.setFocus(true);
}
});
bottomInvisible.addFocusHandler(new FocusHandler() {
public void onFocus(FocusEvent event) {
newNameTextBox.setFocus(true);
}
});

HorizontalPanel buttonPanel = new HorizontalPanel();
buttonPanel.add(cancelButton);
buttonPanel.add(okButton);
buttonPanel.add(bottomInvisible);
buttonPanel.setSize("100%", "24px");
contentPanel.add(buttonPanel);
contentPanel.setSize("320px", "100%");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import com.google.appinventor.client.ComponentsTranslation;
import com.google.appinventor.client.editor.simple.SimpleEditor;
import com.google.appinventor.client.editor.simple.SimpleNonVisibleComponentsPanel;
import com.google.appinventor.client.editor.youngandroid.properties.YoungAndroidLengthPropertyEditor;
import com.google.appinventor.client.widgets.properties.TextPropertyEditor;
import com.google.appinventor.components.common.ComponentConstants;
Expand Down Expand Up @@ -158,4 +159,9 @@ public void onPropertyChange(String propertyName, String newValue) {
refreshForm();
}
}
}

public SimpleNonVisibleComponentsPanel getNonVisibleComponentsPanel() {
return editor.getNonVisibleComponentsPanel();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,24 @@

package com.google.appinventor.client.editor.simple.palette;

import java.util.List;

import com.google.appinventor.client.ComponentsTranslation;
import com.google.appinventor.client.editor.simple.components.MockComponent;
import com.google.appinventor.client.editor.simple.components.MockComponentsUtil;
import com.google.appinventor.client.editor.simple.components.MockContainer;
import com.google.appinventor.client.editor.simple.components.MockForm;
import com.google.appinventor.client.editor.simple.components.MockVisibleComponent;
import com.google.appinventor.client.widgets.dnd.DragSourcePanel;
import com.google.appinventor.client.widgets.dnd.DragSourceSupport;
import com.google.appinventor.client.widgets.dnd.DropTarget;
import com.google.gwt.event.dom.client.DoubleClickEvent;
import com.google.gwt.event.dom.client.DoubleClickHandler;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.event.dom.client.TouchStartEvent;
Expand Down Expand Up @@ -114,6 +126,40 @@ public void onTouchStart(TouchStartEvent event) {
select(getWidget());
}
});
addFocusHandler(new FocusHandler() {
@Override
public void onFocus(FocusEvent event) {
select(getWidget());
}
});
addKeyDownHandler(new KeyDownHandler() {
@Override
public void onKeyDown (KeyDownEvent event) {
if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
addComponent();
}
}
});
addDoubleClickHandler(new DoubleClickHandler() {
public void onDoubleClick (DoubleClickEvent event) {
addComponent();
}
});
}

private void addComponent() {
MockComponent component = createMockComponent();
MockVisibleComponent mockVisibleComponent = (MockVisibleComponent) dropTargetProvider.getDropTargets()[0];
MockForm form = mockVisibleComponent.getForm();
MockComponent selectedComponent = form.getLastSelectedComponent();
if (selectedComponent instanceof MockContainer && ((MockContainer) selectedComponent).willAcceptComponentType(component.getType()) && component.isVisibleComponent()) {
((MockContainer) selectedComponent).addComponent(component);
} else if (form.willAcceptComponentType(component.getType()) && component.isVisibleComponent()) {
form.addComponent(component);
} else if (form.willAcceptComponentType(component.getType()) && !component.isVisibleComponent()) {
form.addComponent(component);
form.getNonVisibleComponentsPanel().addComponent(component);
}
}

/**
Expand Down
Loading