PL-9003 Shortcuts API for containers

This commit is contained in:
Gleb Gorelov 2017-06-22 18:24:23 +04:00
parent e429ae9fc8
commit f33d827bec
40 changed files with 568 additions and 105 deletions

View File

@ -438,4 +438,14 @@ public abstract class DesktopAbstractBox
@Override
public void removeLayoutClickListener(LayoutClickListener listener) {
}
@Override
public void addShortcutAction(ShortcutAction action) {
// do nothing
}
@Override
public void removeShortcutAction(ShortcutAction action) {
// do nothing
}
}

View File

@ -400,4 +400,14 @@ public class DesktopGridLayout extends DesktopAbstractComponent<JPanel> implemen
@Override
public void removeLayoutClickListener(LayoutClickListener listener) {
}
@Override
public void addShortcutAction(ShortcutAction action) {
// do nothing
}
@Override
public void removeShortcutAction(ShortcutAction action) {
// do nothing
}
}

View File

@ -371,4 +371,14 @@ public class DesktopScrollBoxLayout extends DesktopAbstractComponent<JScrollPane
public void setDescription(String description) {
impl.setToolTipText(description);
}
@Override
public void addShortcutAction(ShortcutAction action) {
// do nothing
}
@Override
public void removeShortcutAction(ShortcutAction action) {
// do nothing
}
}

View File

@ -17,7 +17,8 @@
package com.haulmont.cuba.gui.components;
public interface BoxLayout extends ExpandingLayout, Component.OrderedContainer, Component.Spacing, Component.Margin,
Component.BelongToFrame, Component.HasCaption, Component.HasIcon, Component.LayoutClickNotifier {
Component.BelongToFrame, Component.HasCaption, Component.HasIcon,
Component.LayoutClickNotifier, Component.ShortcutNotifier {
/**
* @deprecated Use {@link VBoxLayout#NAME}
*/

View File

@ -25,6 +25,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.EventObject;
import java.util.function.Consumer;
/**
* Root of the GenericUI components hierarchy
@ -351,6 +352,77 @@ public interface Component {
}
}
/**
* Component having a shortcut listener.
*/
interface ShortcutNotifier {
void addShortcutAction(ShortcutAction action);
void removeShortcutAction(ShortcutAction action);
}
/**
* The ShortcutAction is triggered when the user presses a given key combination.
*/
class ShortcutAction {
protected final KeyCombination shortcut;
protected final Consumer<ShortcutTriggeredEvent> handler;
public ShortcutAction(String shortcut, Consumer<ShortcutTriggeredEvent> handler) {
this(KeyCombination.create(shortcut), handler);
}
public ShortcutAction(KeyCombination shortcut, Consumer<ShortcutTriggeredEvent> handler) {
this.shortcut = shortcut;
this.handler = handler;
}
/**
* @return the key combination that the shortcut reacts to
*/
public KeyCombination getShortcutCombination() {
return shortcut;
}
/**
* @return the handler invoked when the shortcut is triggered
*/
public Consumer<ShortcutTriggeredEvent> getHandler() {
return handler;
}
}
/**
* Describes shortcut triggered event.
* The event contains a data about source component and target component.
*/
class ShortcutTriggeredEvent extends EventObject {
private final Component target;
/**
* Constructs a shortcut triggered event.
*
* @param source the component on which the Event initially occurred
* @param target the component which was focused when the Event occurred
* @throws IllegalArgumentException if source is null
*/
public ShortcutTriggeredEvent(Component source, Component target) {
super(source);
this.target = target;
}
@Override
public Component getSource() {
return (Component) super.getSource();
}
/**
* @return the component which was focused when the Event occurred
*/
public Component getTarget() {
return target;
}
}
/**
* Object having a border
*/

View File

@ -18,7 +18,7 @@
package com.haulmont.cuba.gui.components;
public interface CssLayout extends Component.OrderedContainer, Component.BelongToFrame, Component.HasCaption,
Component.HasIcon, Component.LayoutClickNotifier
Component.HasIcon, Component.LayoutClickNotifier, Component.ShortcutNotifier
{
String NAME = "cssLayout";

View File

@ -18,7 +18,8 @@
package com.haulmont.cuba.gui.components;
public interface FlowBoxLayout extends Component.OrderedContainer, Component.BelongToFrame, Component.Margin,
Component.Spacing, Component.HasCaption, Component.HasIcon, Component.LayoutClickNotifier {
Component.Spacing, Component.HasCaption, Component.HasIcon,
Component.LayoutClickNotifier, Component.ShortcutNotifier {
String NAME = "flowBox";
}

View File

@ -19,7 +19,7 @@ package com.haulmont.cuba.gui.components;
public interface GridLayout
extends Component.Container, Component.Spacing, Component.Margin, Component.BelongToFrame,
Component.HasIcon, Component.HasCaption, Component.LayoutClickNotifier
Component.HasIcon, Component.HasCaption, Component.LayoutClickNotifier, Component.ShortcutNotifier
{
String NAME = "grid";

View File

@ -20,7 +20,7 @@ public interface GroupBoxLayout
extends ExpandingLayout,
Component.OrderedContainer,
Component.HasIcon, Component.HasCaption, Component.HasBorder, Component.Spacing,
Component.Collapsable, Component.BelongToFrame, Component.HasSettings {
Component.Collapsable, Component.BelongToFrame, Component.HasSettings, Component.ShortcutNotifier {
String NAME = "groupBox";

View File

@ -18,7 +18,7 @@ package com.haulmont.cuba.gui.components;
public interface ScrollBoxLayout
extends Component.OrderedContainer, Component.BelongToFrame, Component.Margin, Component.Spacing,
Component.HasIcon, Component.HasCaption {
Component.HasIcon, Component.HasCaption, Component.ShortcutNotifier {
String NAME = "scrollBox";

View File

@ -18,13 +18,11 @@
package com.haulmont.cuba.web.toolkit.ui.client.flowlayout;
import com.haulmont.cuba.web.toolkit.ui.CubaFlowLayout;
import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.ui.csslayout.CssLayoutConnector;
import com.haulmont.cuba.web.toolkit.ui.client.cssactionslayout.CubaCssActionsLayoutConnector;
import com.vaadin.shared.ui.Connect;
import com.vaadin.shared.ui.MarginInfo;
@Connect(CubaFlowLayout.class)
public class CubaFlowLayoutConnector extends CssLayoutConnector {
public class CubaFlowLayoutConnector extends CubaCssActionsLayoutConnector {
@Override
public CubaFlowLayoutState getState() {
@ -35,12 +33,4 @@ public class CubaFlowLayoutConnector extends CssLayoutConnector {
public CubaFlowLayoutWidget getWidget() {
return (CubaFlowLayoutWidget) super.getWidget();
}
@Override
public void onStateChanged(StateChangeEvent stateChangeEvent) {
super.onStateChanged(stateChangeEvent);
getWidget().setMargin(new MarginInfo(getState().marginsBitmask));
getWidget().setSpacing(getState().spacing);
}
}

View File

@ -17,29 +17,7 @@
package com.haulmont.cuba.web.toolkit.ui.client.flowlayout;
import com.vaadin.client.ui.VCssLayout;
import com.vaadin.shared.ui.MarginInfo;
import com.haulmont.cuba.web.toolkit.ui.client.cssactionslayout.CubaCssActionsLayoutWidget;
public class CubaFlowLayoutWidget extends VCssLayout {
public void setMargin(MarginInfo marginInfo) {
if (marginInfo != null) {
// Styles inherited from v-csslayout from base theme
enableStyleDependentName("margin-top", marginInfo.hasTop());
enableStyleDependentName("margin-right", marginInfo.hasRight());
enableStyleDependentName("margin-bottom", marginInfo.hasBottom());
enableStyleDependentName("margin-left", marginInfo.hasLeft());
}
}
public void setSpacing(boolean spacing) {
enableStyleDependentName("spacing", spacing);
}
public void enableStyleDependentName(String suffix, boolean enable) {
if (enable)
addStyleDependentName(suffix);
else
removeStyleDependentName(suffix);
}
public class CubaFlowLayoutWidget extends CubaCssActionsLayoutWidget {
}

View File

@ -20,15 +20,15 @@ package com.haulmont.cuba.web.toolkit.ui.client.gridlayout;
import com.google.gwt.user.client.ui.Widget;
import com.haulmont.cuba.web.toolkit.ui.CubaGridLayout;
import com.haulmont.cuba.web.toolkit.ui.client.caption.CubaCaptionWidget;
import com.vaadin.client.ComponentConnector;
import com.vaadin.client.VCaption;
import com.vaadin.client.*;
import com.vaadin.client.ui.ShortcutActionHandler;
import com.vaadin.client.ui.VGridLayout;
import com.vaadin.client.ui.gridlayout.GridLayoutConnector;
import com.vaadin.client.ui.layout.VLayoutSlot;
import com.vaadin.shared.ui.Connect;
@Connect(CubaGridLayout.class)
public class CubaGridLayoutConnector extends GridLayoutConnector {
public class CubaGridLayoutConnector extends GridLayoutConnector implements Paintable {
@Override
public CubaGridLayoutWidget getWidget() {
@ -62,4 +62,18 @@ public class CubaGridLayoutConnector extends GridLayoutConnector {
getLayoutManager().setNeedsLayout(this);
}
}
@Override
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
final int cnt = uidl.getChildCount();
for (int i = 0; i < cnt; i++) {
UIDL childUidl = uidl.getChildUIDL(i);
if (childUidl.getTag().equals("actions")) {
if (getWidget().getShortcutHandler() == null) {
getWidget().setShortcutHandler(new ShortcutActionHandler(uidl.getId(), client));
}
getWidget().getShortcutHandler().updateActionMap(childUidl);
}
}
}
}

View File

@ -17,12 +17,23 @@
package com.haulmont.cuba.web.toolkit.ui.client.gridlayout;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.vaadin.client.ComponentConnector;
import com.vaadin.client.ui.ShortcutActionHandler;
import com.vaadin.client.ui.VGridLayout;
import com.vaadin.client.ui.layout.ComponentConnectorLayoutSlot;
public class CubaGridLayoutWidget extends VGridLayout {
protected ShortcutActionHandler shortcutHandler;
public CubaGridLayoutWidget() {
super();
getElement().setTabIndex(-1);
DOM.sinkEvents(getElement(), Event.ONKEYDOWN);
}
public VGridLayout.Cell[][] getCellMatrix() {
return cells;
}
@ -46,4 +57,22 @@ public class CubaGridLayoutWidget extends VGridLayout {
cells[col][row] = cell;
return cell;
}
@Override
public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
final int type = DOM.eventGetType(event);
if (type == Event.ONKEYDOWN && shortcutHandler != null) {
shortcutHandler.handleKeyboardEvent(event);
}
}
public ShortcutActionHandler getShortcutHandler() {
return shortcutHandler;
}
public void setShortcutHandler(ShortcutActionHandler shortcutHandler) {
this.shortcutHandler = shortcutHandler;
}
}

View File

@ -18,14 +18,14 @@ package com.haulmont.cuba.web.toolkit.ui.client.scrollboxlayout;
import com.google.gwt.user.client.Element;
import com.haulmont.cuba.web.toolkit.ui.CubaScrollBoxLayout;
import com.haulmont.cuba.web.toolkit.ui.client.cssactionslayout.CubaCssActionsLayoutConnector;
import com.haulmont.cuba.web.toolkit.ui.client.cubascrollboxlayout.CubaScrollBoxLayoutServerRpc;
import com.haulmont.cuba.web.toolkit.ui.client.cubascrollboxlayout.CubaScrollBoxLayoutState;
import com.vaadin.client.ui.SimpleManagedLayout;
import com.vaadin.client.ui.csslayout.CssLayoutConnector;
import com.vaadin.shared.ui.Connect;
@Connect(CubaScrollBoxLayout.class)
public class CubaScrollBoxLayoutConnector extends CssLayoutConnector implements SimpleManagedLayout {
public class CubaScrollBoxLayoutConnector extends CubaCssActionsLayoutConnector implements SimpleManagedLayout {
@Override
public CubaScrollBoxLayoutState getState() {

View File

@ -19,11 +19,11 @@ package com.haulmont.cuba.web.toolkit.ui.client.scrollboxlayout;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.vaadin.client.ui.VCssLayout;
import com.haulmont.cuba.web.toolkit.ui.client.cssactionslayout.CubaCssActionsLayoutWidget;
import java.util.function.BiConsumer;
public class CubaScrollBoxLayoutWidget extends VCssLayout {
public class CubaScrollBoxLayoutWidget extends CubaCssActionsLayoutWidget {
protected int scrollTop = 0;
protected int scrollLeft = 0;
@ -31,7 +31,7 @@ public class CubaScrollBoxLayoutWidget extends VCssLayout {
public BiConsumer<Integer, Integer> onScrollHandler;
protected CubaScrollBoxLayoutWidget() {
DOM.sinkEvents(getElement(), Event.ONSCROLL);
DOM.sinkEvents(getElement(), Event.ONKEYDOWN | Event.ONSCROLL);
}
@Override

View File

@ -40,7 +40,8 @@ import com.haulmont.cuba.web.jmx.JmxControlAPI;
import com.haulmont.cuba.web.jmx.JmxControlException;
import com.haulmont.cuba.web.jmx.JmxRemoteLoggingAPI;
import com.haulmont.cuba.web.toolkit.ui.CubaScrollBoxLayout;
import com.vaadin.event.ShortcutAction;
import com.vaadin.event.ShortcutAction.KeyCode;
import com.vaadin.event.ShortcutAction.ModifierKey;
import com.vaadin.event.ShortcutListener;
import com.vaadin.ui.ComboBox;
import org.apache.commons.lang.StringEscapeUtils;
@ -191,15 +192,15 @@ public class ServerLogWindow extends AbstractWindow {
downloadButton.setEnabled(security.isSpecificPermitted("cuba.gui.administration.downloadlogs"));
ComboBox comboBox = logFileNameField.unwrap(ComboBox.class);
comboBox.addShortcutListener(new ShortcutListener("", ShortcutAction.KeyCode.D,
new int[]{ShortcutAction.ModifierKey.CTRL, ShortcutAction.ModifierKey.SHIFT}) {
comboBox.addShortcutListener(new ShortcutListener("", KeyCode.D,
new int[]{ModifierKey.CTRL, ModifierKey.SHIFT}) {
@Override
public void handleAction(Object sender, Object target) {
downloadLog();
}
});
comboBox.addShortcutListener(new ShortcutListener("", ShortcutAction.KeyCode.S,
new int[]{ShortcutAction.ModifierKey.CTRL, ShortcutAction.ModifierKey.SHIFT}) {
comboBox.addShortcutListener(new ShortcutListener("", KeyCode.S,
new int[]{ModifierKey.CTRL, ModifierKey.SHIFT}) {
@Override
public void handleAction(Object sender, Object target) {
showLogTail();

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2008-2017 Haulmont.
*
* 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.haulmont.cuba.web.gui.components;
import com.haulmont.cuba.gui.components.Component;
import com.haulmont.cuba.gui.components.KeyCombination;
public class ContainerShortcutActionWrapper extends com.vaadin.event.ShortcutListener {
protected Component.ShortcutAction action;
protected Component.Container container;
protected KeyCombination keyCombination;
public ContainerShortcutActionWrapper(Component.ShortcutAction action,
Component.Container container, KeyCombination keyCombination) {
super(null, keyCombination.getKey().getCode(), KeyCombination.Modifier.codes(keyCombination.getModifiers()));
this.action = action;
this.keyCombination = keyCombination;
this.container = container;
}
@Override
public void handleAction(Object sender, Object target) {
Component.ShortcutTriggeredEvent event = WebComponentsHelper.getShortcutEvent(container,
(com.vaadin.ui.Component) target);
action.getHandler().accept(event);
}
public Component.ShortcutAction getAction() {
return action;
}
public Component.Container getContainer() {
return container;
}
public KeyCombination getKeyCombination() {
return keyCombination;
}
}

View File

@ -21,7 +21,9 @@ import com.haulmont.cuba.gui.ComponentsHelper;
import com.haulmont.cuba.gui.components.BoxLayout;
import com.haulmont.cuba.gui.components.Component;
import com.haulmont.cuba.gui.components.Frame;
import com.haulmont.cuba.gui.components.KeyCombination;
import com.vaadin.event.LayoutEvents;
import com.vaadin.event.ShortcutListener;
import com.vaadin.shared.ui.MarginInfo;
import com.vaadin.ui.AbstractOrderedLayout;
@ -34,6 +36,7 @@ public abstract class WebAbstractBox<T extends AbstractOrderedLayout>
protected List<Component> ownComponents = new ArrayList<>();
protected LayoutEvents.LayoutClickListener layoutClickListener;
protected Map<Component.ShortcutAction, ShortcutListener> shortcuts;
@Override
public void add(Component childComponent) {
@ -231,4 +234,28 @@ public abstract class WebAbstractBox<T extends AbstractOrderedLayout>
layoutClickListener = null;
}
}
@Override
public void addShortcutAction(ShortcutAction action) {
KeyCombination keyCombination = action.getShortcutCombination();
com.vaadin.event.ShortcutListener shortcut =
new ContainerShortcutActionWrapper(action, this, keyCombination);
component.addShortcutListener(shortcut);
if (shortcuts == null) {
shortcuts = new HashMap<>();
}
shortcuts.put(action, shortcut);
}
@Override
public void removeShortcutAction(ShortcutAction action) {
if (shortcuts != null) {
component.removeShortcutListener(shortcuts.remove(action));
if (shortcuts.isEmpty()) {
shortcuts = null;
}
}
}
}

View File

@ -21,7 +21,9 @@ import com.haulmont.bali.util.Preconditions;
import com.haulmont.cuba.gui.ComponentsHelper;
import com.haulmont.cuba.gui.components.Component;
import com.haulmont.cuba.gui.components.Frame;
import com.haulmont.cuba.gui.components.KeyCombination;
import com.vaadin.event.LayoutEvents;
import com.vaadin.event.ShortcutListener;
import com.vaadin.ui.AbstractComponent;
import javax.annotation.Nonnull;
@ -30,10 +32,12 @@ import java.util.*;
public class WebAbstractOrderedLayout<T extends com.vaadin.ui.CssLayout>
extends WebAbstractComponent<T>
implements Component.OrderedContainer, Component.BelongToFrame, Component.HasCaption, Component.HasIcon, Component.LayoutClickNotifier {
implements Component.OrderedContainer, Component.BelongToFrame, Component.HasCaption, Component.HasIcon,
Component.LayoutClickNotifier, Component.ShortcutNotifier {
protected Collection<Component> ownComponents = new LinkedHashSet<>();
protected LayoutEvents.LayoutClickListener layoutClickListener;
protected Map<Component.ShortcutAction, ShortcutListener> shortcuts;
@Override
public void add(Component childComponent) {
@ -202,4 +206,28 @@ public class WebAbstractOrderedLayout<T extends com.vaadin.ui.CssLayout>
layoutClickListener = null;
}
}
@Override
public void addShortcutAction(ShortcutAction action) {
KeyCombination keyCombination = action.getShortcutCombination();
com.vaadin.event.ShortcutListener shortcut =
new ContainerShortcutActionWrapper(action, this, keyCombination);
component.addShortcutListener(shortcut);
if (shortcuts == null) {
shortcuts = new HashMap<>();
}
shortcuts.put(action, shortcut);
}
@Override
public void removeShortcutAction(ShortcutAction action) {
if (shortcuts != null) {
component.removeShortcutListener(shortcuts.remove(action));
if (shortcuts.isEmpty()) {
shortcuts = null;
}
}
}
}

View File

@ -19,6 +19,8 @@ package com.haulmont.cuba.web.gui.components;
import com.haulmont.cuba.core.global.AppBeans;
import com.haulmont.cuba.core.global.Configuration;
import com.haulmont.cuba.gui.components.*;
import com.haulmont.cuba.gui.components.Component.Container;
import com.haulmont.cuba.gui.components.Component.ShortcutTriggeredEvent;
import com.haulmont.cuba.gui.components.Formatter;
import com.haulmont.cuba.gui.components.TextField;
import com.haulmont.cuba.gui.theme.ThemeConstants;
@ -27,10 +29,7 @@ import com.haulmont.cuba.web.App;
import com.haulmont.cuba.web.WebConfig;
import com.haulmont.cuba.web.toolkit.VersionedThemeResource;
import com.haulmont.cuba.web.toolkit.data.AggregationContainer;
import com.haulmont.cuba.web.toolkit.ui.CubaGroupBox;
import com.haulmont.cuba.web.toolkit.ui.CubaHorizontalActionsLayout;
import com.haulmont.cuba.web.toolkit.ui.CubaTextField;
import com.haulmont.cuba.web.toolkit.ui.CubaVerticalActionsLayout;
import com.haulmont.cuba.web.toolkit.ui.*;
import com.vaadin.event.Action;
import com.vaadin.event.ShortcutAction;
import com.vaadin.event.ShortcutListener;
@ -50,7 +49,6 @@ import java.io.File;
import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.lang.reflect.Field;
public class WebComponentsHelper {
@ -555,4 +553,59 @@ public class WebComponentsHelper {
}
}
}
public static ShortcutTriggeredEvent getShortcutEvent(com.haulmont.cuba.gui.components.Component source,
Component target) {
Component vaadinSource = getVaadinSource(source);
if (vaadinSource == target) {
return new ShortcutTriggeredEvent(source, source);
}
if (source instanceof Container) {
Container container = (Container) source;
Component targetComponent = getDirectChildComponent(target, vaadinSource);
com.haulmont.cuba.gui.components.Component childComponent =
findChildComponent(container, targetComponent);
return new ShortcutTriggeredEvent(source, childComponent);
}
return new ShortcutTriggeredEvent(source, null);
}
protected static Component getVaadinSource(com.haulmont.cuba.gui.components.Component source) {
Component component = source.unwrapComposition(Component.class);
if (component instanceof AbstractSingleComponentContainer) {
return ((AbstractSingleComponentContainer) component).getContent();
}
if (component instanceof CubaScrollBoxLayout) {
return ((CubaScrollBoxLayout) component).getComponent(0);
}
return component;
}
/**
* @return the direct child component of the layout which contains the component involved to event
*/
protected static Component getDirectChildComponent(Component targetComponent, Component vaadinSource) {
while (targetComponent != null
&& targetComponent.getParent() != vaadinSource) {
targetComponent = targetComponent.getParent();
}
return targetComponent;
}
@Nullable
protected static com.haulmont.cuba.gui.components.Component findChildComponent(Container container,
Component target) {
Collection<com.haulmont.cuba.gui.components.Component> components = container.getComponents();
for (com.haulmont.cuba.gui.components.Component childComponent : components) {
if (childComponent.unwrapComposition(Component.class) == target) {
return childComponent;
}
}
return null;
}
}

View File

@ -18,9 +18,10 @@
package com.haulmont.cuba.web.gui.components;
import com.haulmont.cuba.gui.components.CssLayout;
import com.haulmont.cuba.web.toolkit.ui.CubaCssActionsLayout;
public class WebCssLayout extends WebAbstractOrderedLayout<com.vaadin.ui.CssLayout> implements CssLayout {
public WebCssLayout() {
component = new com.vaadin.ui.CssLayout();
component = new CubaCssActionsLayout();
}
}

View File

@ -21,8 +21,10 @@ import com.haulmont.cuba.gui.ComponentsHelper;
import com.haulmont.cuba.gui.components.Component;
import com.haulmont.cuba.gui.components.Frame;
import com.haulmont.cuba.gui.components.GridLayout;
import com.haulmont.cuba.gui.components.KeyCombination;
import com.haulmont.cuba.web.toolkit.ui.CubaGridLayout;
import com.vaadin.event.LayoutEvents;
import com.vaadin.event.ShortcutListener;
import com.vaadin.shared.ui.MarginInfo;
import javax.annotation.Nonnull;
@ -33,6 +35,7 @@ public class WebGridLayout extends WebAbstractComponent<CubaGridLayout> implemen
protected List<Component> ownComponents = new ArrayList<>();
protected LayoutEvents.LayoutClickListener layoutClickListener;
protected Map<Component.ShortcutAction, ShortcutListener> shortcuts;
public WebGridLayout() {
component = new CubaGridLayout();
@ -257,4 +260,28 @@ public class WebGridLayout extends WebAbstractComponent<CubaGridLayout> implemen
layoutClickListener = null;
}
}
@Override
public void addShortcutAction(ShortcutAction action) {
KeyCombination keyCombination = action.getShortcutCombination();
com.vaadin.event.ShortcutListener shortcut =
new ContainerShortcutActionWrapper(action, this, keyCombination);
component.addShortcutListener(shortcut);
if (shortcuts == null) {
shortcuts = new HashMap<>();
}
shortcuts.put(action, shortcut);
}
@Override
public void removeShortcutAction(ShortcutAction action) {
if (shortcuts != null) {
component.removeShortcutListener(shortcuts.remove(action));
if (shortcuts.isEmpty()) {
shortcuts = null;
}
}
}
}

View File

@ -21,11 +21,13 @@ import com.haulmont.cuba.gui.ComponentsHelper;
import com.haulmont.cuba.gui.components.Component;
import com.haulmont.cuba.gui.components.Frame;
import com.haulmont.cuba.gui.components.GroupBoxLayout;
import com.haulmont.cuba.gui.components.KeyCombination;
import com.haulmont.cuba.gui.components.compatibility.ComponentExpandCollapseListenerWrapper;
import com.haulmont.cuba.web.toolkit.ui.CubaGroupBox;
import com.haulmont.cuba.web.toolkit.ui.CubaHorizontalActionsLayout;
import com.haulmont.cuba.web.toolkit.ui.CubaOrderedActionsLayout;
import com.haulmont.cuba.web.toolkit.ui.CubaVerticalActionsLayout;
import com.vaadin.event.ShortcutListener;
import com.vaadin.ui.AbstractOrderedLayout;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
@ -45,6 +47,8 @@ public class WebGroupBox extends WebAbstractComponent<CubaGroupBox> implements G
protected boolean settingsEnabled = true;
protected Map<Component.ShortcutAction, ShortcutListener> shortcuts;
public WebGroupBox() {
component = new CubaGroupBox();
component.addStyleName(GROUPBOX_PANEL_STYLENAME);
@ -377,4 +381,28 @@ public class WebGroupBox extends WebAbstractComponent<CubaGroupBox> implements G
public String getStyleName() {
return StringUtils.normalizeSpace(super.getStyleName().replace(GROUPBOX_PANEL_STYLENAME, ""));
}
@Override
public void addShortcutAction(ShortcutAction action) {
KeyCombination keyCombination = action.getShortcutCombination();
com.vaadin.event.ShortcutListener shortcut =
new ContainerShortcutActionWrapper(action, this, keyCombination);
component.addShortcutListener(shortcut);
if (shortcuts == null) {
shortcuts = new HashMap<>();
}
shortcuts.put(action, shortcut);
}
@Override
public void removeShortcutAction(ShortcutAction action) {
if (shortcuts != null) {
component.removeShortcutListener(shortcuts.remove(action));
if (shortcuts.isEmpty()) {
shortcuts = null;
}
}
}
}

View File

@ -19,7 +19,7 @@ package com.haulmont.cuba.web.gui.components;
import com.haulmont.cuba.gui.components.MaskedField;
import com.haulmont.cuba.web.toolkit.ui.CubaMaskedTextField;
import com.vaadin.event.ShortcutAction;
import com.vaadin.event.ShortcutAction.KeyCode;
import com.vaadin.event.ShortcutListener;
public class WebMaskedField extends WebAbstractTextField<CubaMaskedTextField> implements MaskedField {
@ -86,7 +86,7 @@ public class WebMaskedField extends WebAbstractTextField<CubaMaskedTextField> im
getEventRouter().addListener(EnterPressListener.class, listener);
if (enterShortcutListener == null) {
enterShortcutListener = new ShortcutListener("enter", ShortcutAction.KeyCode.ENTER, null) {
enterShortcutListener = new ShortcutListener("enter", KeyCode.ENTER, null) {
@Override
public void handleAction(Object sender, Object target) {
EnterPressEvent event = new EnterPressEvent(WebMaskedField.this);

View File

@ -20,10 +20,12 @@ import com.haulmont.bali.util.Preconditions;
import com.haulmont.cuba.gui.ComponentsHelper;
import com.haulmont.cuba.gui.components.Component;
import com.haulmont.cuba.gui.components.Frame;
import com.haulmont.cuba.gui.components.KeyCombination;
import com.haulmont.cuba.gui.components.ScrollBoxLayout;
import com.haulmont.cuba.web.toolkit.ui.CubaHorizontalActionsLayout;
import com.haulmont.cuba.web.toolkit.ui.CubaScrollBoxLayout;
import com.haulmont.cuba.web.toolkit.ui.CubaVerticalActionsLayout;
import com.vaadin.event.ShortcutListener;
import com.vaadin.server.Sizeable;
import com.vaadin.shared.ui.MarginInfo;
import com.vaadin.ui.AbstractOrderedLayout;
@ -44,6 +46,8 @@ public class WebScrollBoxLayout extends WebAbstractComponent<CubaScrollBoxLayout
protected Orientation orientation = Orientation.VERTICAL;
protected ScrollBarPolicy scrollBarPolicy = ScrollBarPolicy.VERTICAL;
protected Map<Component.ShortcutAction, ShortcutListener> shortcuts;
public WebScrollBoxLayout() {
component = new CubaScrollBoxLayout();
component.setWidth("100%");
@ -282,4 +286,28 @@ public class WebScrollBoxLayout extends WebAbstractComponent<CubaScrollBoxLayout
public void setSpacing(boolean enabled) {
getContent().setSpacing(enabled);
}
@Override
public void addShortcutAction(ShortcutAction action) {
KeyCombination keyCombination = action.getShortcutCombination();
com.vaadin.event.ShortcutListener shortcut =
new ContainerShortcutActionWrapper(action, this, keyCombination);
component.addShortcutListener(shortcut);
if (shortcuts == null) {
shortcuts = new HashMap<>();
}
shortcuts.put(action, shortcut);
}
@Override
public void removeShortcutAction(ShortcutAction action) {
if (shortcuts != null) {
component.removeShortcutListener(shortcuts.remove(action));
if (shortcuts.isEmpty()) {
shortcuts = null;
}
}
}
}

View File

@ -22,7 +22,7 @@ import com.haulmont.cuba.gui.components.Formatter;
import com.haulmont.cuba.gui.components.TextField;
import com.haulmont.cuba.web.toolkit.ui.CubaTextField;
import com.vaadin.event.FieldEvents;
import com.vaadin.event.ShortcutAction;
import com.vaadin.event.ShortcutAction.KeyCode;
import com.vaadin.event.ShortcutListener;
public class WebTextField extends WebAbstractTextField<CubaTextField> implements TextField {
@ -189,7 +189,7 @@ public class WebTextField extends WebAbstractTextField<CubaTextField> implements
getEventRouter().addListener(EnterPressListener.class, listener);
if (enterShortcutListener == null) {
enterShortcutListener = new ShortcutListener("", ShortcutAction.KeyCode.ENTER, null) {
enterShortcutListener = new ShortcutListener("", KeyCode.ENTER, null) {
@Override
public void handleAction(Object sender, Object target) {
EnterPressEvent event = new EnterPressEvent(WebTextField.this);

View File

@ -18,11 +18,9 @@
package com.haulmont.cuba.web.toolkit.ui;
import com.haulmont.cuba.web.toolkit.ui.client.flowlayout.CubaFlowLayoutState;
import com.vaadin.shared.ui.MarginInfo;
import com.vaadin.ui.CssLayout;
import com.vaadin.ui.Layout;
public class CubaFlowLayout extends CssLayout implements Layout.MarginHandler, Layout.SpacingHandler {
public class CubaFlowLayout extends CubaCssActionsLayout implements Layout.MarginHandler, Layout.SpacingHandler {
public CubaFlowLayout() {
setStyleName("c-flowlayout");
@ -37,29 +35,4 @@ public class CubaFlowLayout extends CssLayout implements Layout.MarginHandler, L
protected CubaFlowLayoutState getState(boolean markAsDirty) {
return (CubaFlowLayoutState) super.getState(markAsDirty);
}
@Override
public void setMargin(boolean enabled) {
setMargin(new MarginInfo(enabled));
}
@Override
public MarginInfo getMargin() {
return new MarginInfo(getState().marginsBitmask);
}
@Override
public void setMargin(MarginInfo marginInfo) {
getState().marginsBitmask = marginInfo.getBitMask();
}
@Override
public void setSpacing(boolean spacing) {
getState().spacing = spacing;
}
@Override
public boolean isSpacing() {
return getState().spacing;
}
}

View File

@ -17,11 +17,67 @@
package com.haulmont.cuba.web.toolkit.ui;
import com.vaadin.event.Action;
import com.vaadin.event.ActionManager;
import com.vaadin.event.ShortcutListener;
import com.vaadin.server.PaintException;
import com.vaadin.server.PaintTarget;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.LegacyComponent;
public class CubaGridLayout extends GridLayout {
import java.util.Map;
public class CubaGridLayout extends GridLayout implements Action.Container, LegacyComponent {
protected ActionManager actionManager;
public CubaGridLayout() {
setHideEmptyRowsAndColumns(true);
}
@Override
public void addActionHandler(Action.Handler actionHandler) {
getActionManager().addActionHandler(actionHandler);
markAsDirty();
}
@Override
public void removeActionHandler(Action.Handler actionHandler) {
if (actionManager != null) {
actionManager.removeActionHandler(actionHandler);
markAsDirty();
}
}
@Override
public void addShortcutListener(ShortcutListener listener) {
getActionManager().addAction(listener);
}
@Override
public void removeShortcutListener(ShortcutListener listener) {
getActionManager().removeAction(listener);
}
@Override
protected ActionManager getActionManager() {
if (actionManager == null) {
actionManager = new ActionManager(this);
}
return actionManager;
}
@Override
public void paintContent(PaintTarget target) throws PaintException {
if (actionManager != null) {
actionManager.paintActions(null, target);
}
}
@Override
public void changeVariables(Object source, Map<String, Object> variables) {
if (actionManager != null) {
actionManager.handleActions(variables, this);
}
}
}

View File

@ -18,9 +18,8 @@ package com.haulmont.cuba.web.toolkit.ui;
import com.haulmont.cuba.web.toolkit.ui.client.cubascrollboxlayout.CubaScrollBoxLayoutServerRpc;
import com.haulmont.cuba.web.toolkit.ui.client.cubascrollboxlayout.CubaScrollBoxLayoutState;
import com.vaadin.ui.CssLayout;
public class CubaScrollBoxLayout extends CssLayout {
public class CubaScrollBoxLayout extends CubaCssActionsLayout {
protected CubaScrollBoxLayoutServerRpc serverRpc;

View File

@ -16,9 +16,9 @@
package com.haulmont.cuba.web.toolkit.ui.client.cubascrollboxlayout;
import com.vaadin.shared.ui.csslayout.CssLayoutState;
import com.haulmont.cuba.web.toolkit.ui.client.cssactionslayout.CubaCssActionsLayoutState;
public class CubaScrollBoxLayoutState extends CssLayoutState {
public class CubaScrollBoxLayoutState extends CubaCssActionsLayoutState {
public int scrollTop = 0;
public int scrollLeft = 0;

View File

@ -17,10 +17,7 @@
package com.haulmont.cuba.web.toolkit.ui.client.flowlayout;
import com.vaadin.shared.ui.csslayout.CssLayoutState;
import com.haulmont.cuba.web.toolkit.ui.client.cssactionslayout.CubaCssActionsLayoutState;
public class CubaFlowLayoutState extends CssLayoutState {
public int marginsBitmask = 0;
public boolean spacing = false;
public class CubaFlowLayoutState extends CubaCssActionsLayoutState {
}

View File

@ -0,0 +1,22 @@
/*!
* Copyright (c) 2008-2017 Haulmont.
*
* 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.
*/
@mixin halo-csslayout($primary-stylename: v-csslayout) {
.#{$primary-stylename} {
outline: none;
}
}

View File

@ -0,0 +1,21 @@
/*!
* Copyright (c) 2008-2017 Haulmont.
*
* 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.
*/
@mixin halo-gridlayout($primary-stylename: v-gridlayout) {
.#{$primary-stylename} {
outline: none;
}
}

View File

@ -21,6 +21,7 @@
box-shadow: none;
background: transparent;
overflow: auto;
outline: none;
}
.#{$primary-stylename} > .v-panel-content {

View File

@ -50,6 +50,8 @@
@import "components/scrollbox/scrollbox";
@import "components/twincolumn/twincolumn";
@import "components/flowlayout/flowlayout";
@import "components/csslayout/csslayout";
@import "components/gridlayout/gridlayout";
@import "components/fileupload/fileupload";
@import "components/pickerfield/pickerfield";
@import "components/listeditor/listeditor";
@ -134,6 +136,8 @@
@include halo-textarea;
@include halo-draganddrop;
@include halo-colorpicker;
@include halo-gridlayout;
@include halo-csslayout;
@include halo-cuba-image;
@include halo-cuba-groupbox;

View File

@ -0,0 +1,22 @@
/*!
* Copyright (c) 2008-2017 Haulmont.
*
* 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.
*/
@mixin havana-csslayout($primary-stylename: v-csslayout) {
.#{$primary-stylename} {
outline: none;
}
}

View File

@ -15,8 +15,11 @@
*
*/
@mixin havana-gridlayout {
@mixin havana-gridlayout($primary-stylename: v-gridlayout) {
// just a stub for possible extension
// do not assign box defaults mixin to grid layout slot
.#{$primary-stylename} {
outline: none;
}
}

View File

@ -17,6 +17,7 @@
@mixin havana-scrollbox($primary-stylename: c-scrollbox) {
.#{$primary-stylename} {
overflow: auto;
outline: none;
.#{$primary-stylename}-content {
border: 0;

View File

@ -50,6 +50,7 @@
@import "components/popupview/popupview";
@import "components/fieldgroup/fieldgroup";
@import "components/flowlayout/flowlayout";
@import "components/csslayout/csslayout";
@import "components/gridlayout/gridlayout";
@import "components/splitpanel/splitpanel";
@import "components/grouptable/grouptable";
@ -147,6 +148,7 @@
@include havana-scrollbox;
@include havana-calendar;
@include havana-colorpicker;
@include havana-csslayout;
@include havana-cuba-groupbox;
@include havana-cuba-tokenlist;