package net.sourceforge.nattable.ui.binding; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import net.sourceforge.nattable.NatTable; import net.sourceforge.nattable.layer.LabelStack; import net.sourceforge.nattable.ui.action.IDragMode; import net.sourceforge.nattable.ui.action.IKeyAction; import net.sourceforge.nattable.ui.action.IMouseAction; import net.sourceforge.nattable.ui.matcher.IKeyEventMatcher; import net.sourceforge.nattable.ui.matcher.IMouseEventMatcher; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.MouseEvent; public class UiBindingRegistry implements IUiBindingRegistry { private NatTable natTable; private LinkedList<KeyBinding> keyBindings = new LinkedList<KeyBinding>(); private Map<MouseEventTypeEnum, LinkedList<MouseBinding>> mouseBindingsMap = new HashMap<MouseEventTypeEnum, LinkedList<MouseBinding>>(); private LinkedList<DragBinding> dragBindings = new LinkedList<DragBinding>(); public UiBindingRegistry(NatTable natTable) { this.natTable = natTable; } // Lookup ///////////////////////////////////////////////////////////////// public IKeyAction getKeyEventAction(KeyEvent event) { for (KeyBinding keyBinding : keyBindings) { if (keyBinding.getKeyEventMatcher().matches(event)) { return keyBinding.getAction(); } } return null; } public IDragMode getDragMode(MouseEvent event) { LabelStack regionLabels = natTable.getRegionLabelsByXY(event.x, event.y); for (DragBinding dragBinding : dragBindings) { if (dragBinding.getMouseEventMatcher().matches(natTable, event, regionLabels)) { return dragBinding.getDragMode(); } } return null; } public IMouseAction getMouseMoveAction(MouseEvent event) { return getMouseEventAction(MouseEventTypeEnum.MOUSE_MOVE, event); } public IMouseAction getMouseDownAction(MouseEvent event) { return getMouseEventAction(MouseEventTypeEnum.MOUSE_DOWN, event); } public IMouseAction getSingleClickAction(MouseEvent event) { return getMouseEventAction(MouseEventTypeEnum.MOUSE_SINGLE_CLICK, event); } public IMouseAction getDoubleClickAction(MouseEvent event) { return getMouseEventAction(MouseEventTypeEnum.MOUSE_DOUBLE_CLICK, event); } /////////////////////////////////////////////////////////////////////////// private IMouseAction getMouseEventAction(MouseEventTypeEnum mouseEventType, MouseEvent event) { // TODO: This code can be made more performant by mapping mouse bindings not only to the mouseEventType but // also to the region that they are interested in. That way, given an area and an event we can narrow down the // list of mouse bindings that need to be searched. -- Azubuko.Obele try { LinkedList<MouseBinding> mouseEventBindings = mouseBindingsMap.get(mouseEventType); if (mouseEventBindings != null) { LabelStack regionLabels = natTable.getRegionLabelsByXY(event.x, event.y); for (MouseBinding mouseBinding : mouseEventBindings) { if (mouseBinding.getMouseEventMatcher().matches(natTable, event, regionLabels)) { return mouseBinding.getAction(); } } } } catch (Exception e) { e.printStackTrace(); } return null; } // Registration /////////////////////////////////////////////////////////// // Key public void registerFirstKeyBinding(IKeyEventMatcher keyMatcher, IKeyAction action) { keyBindings.addFirst(new KeyBinding(keyMatcher, action)); } public void registerKeyBinding(IKeyEventMatcher keyMatcher, IKeyAction action) { keyBindings.addLast(new KeyBinding(keyMatcher, action)); } public void unregisterKeyBinding(IKeyEventMatcher keyMatcher) { for (KeyBinding keyBinding : keyBindings) { if (keyBinding.getKeyEventMatcher().equals(keyMatcher)) { keyBindings.remove(keyBinding); return; } } } // Drag public void registerFirstMouseDragMode(IMouseEventMatcher mouseEventMatcher, IDragMode dragMode) { dragBindings.addFirst(new DragBinding(mouseEventMatcher, dragMode)); } public void registerMouseDragMode(IMouseEventMatcher mouseEventMatcher, IDragMode dragMode) { dragBindings.addLast(new DragBinding(mouseEventMatcher, dragMode)); } public void unregisterMouseDragMode(IMouseEventMatcher mouseEventMatcher) { for (DragBinding dragBinding : dragBindings) { if (dragBinding.getMouseEventMatcher().equals(mouseEventMatcher)) { dragBindings.remove(dragBinding); return; } } } // Mouse move public void registerFirstMouseMoveBinding(IMouseEventMatcher mouseEventMatcher, IMouseAction action) { registerMouseBinding(true, MouseEventTypeEnum.MOUSE_MOVE, mouseEventMatcher, action); } public void registerMouseMoveBinding(IMouseEventMatcher mouseEventMatcher, IMouseAction action) { registerMouseBinding(false, MouseEventTypeEnum.MOUSE_MOVE, mouseEventMatcher, action); } public void unregisterMouseMoveBinding(IMouseEventMatcher mouseEventMatcher) { unregisterMouseBinding(MouseEventTypeEnum.MOUSE_MOVE, mouseEventMatcher); } // Mouse down public void registerFirstMouseDownBinding(IMouseEventMatcher mouseEventMatcher, IMouseAction action) { registerMouseBinding(true, MouseEventTypeEnum.MOUSE_DOWN, mouseEventMatcher, action); } public void registerMouseDownBinding(IMouseEventMatcher mouseEventMatcher, IMouseAction action) { registerMouseBinding(false, MouseEventTypeEnum.MOUSE_DOWN, mouseEventMatcher, action); } public void unregisterMouseDownBinding(IMouseEventMatcher mouseEventMatcher) { unregisterMouseBinding(MouseEventTypeEnum.MOUSE_DOWN, mouseEventMatcher); } // Single click public void registerFirstSingleClickBinding(IMouseEventMatcher mouseEventMatcher, IMouseAction action) { registerMouseBinding(true, MouseEventTypeEnum.MOUSE_SINGLE_CLICK, mouseEventMatcher, action); } public void registerSingleClickBinding(IMouseEventMatcher mouseEventMatcher, IMouseAction action) { registerMouseBinding(false, MouseEventTypeEnum.MOUSE_SINGLE_CLICK, mouseEventMatcher, action); } public void unregisterSingleClickBinding(IMouseEventMatcher mouseEventMatcher) { unregisterMouseBinding(MouseEventTypeEnum.MOUSE_SINGLE_CLICK, mouseEventMatcher); } // Double click public void registerFirstDoubleClickBinding(IMouseEventMatcher mouseEventMatcher, IMouseAction action) { registerMouseBinding(true, MouseEventTypeEnum.MOUSE_DOUBLE_CLICK, mouseEventMatcher, action); } public void registerDoubleClickBinding(IMouseEventMatcher mouseEventMatcher, IMouseAction action) { registerMouseBinding(false, MouseEventTypeEnum.MOUSE_DOUBLE_CLICK, mouseEventMatcher, action); } public void unregisterDoubleClickBinding(IMouseEventMatcher mouseEventMatcher) { unregisterMouseBinding(MouseEventTypeEnum.MOUSE_DOUBLE_CLICK, mouseEventMatcher); } /////////////////////////////////////////////////////////////////////////// private void registerMouseBinding(boolean first, MouseEventTypeEnum mouseEventType, IMouseEventMatcher mouseEventMatcher, IMouseAction action) { LinkedList<MouseBinding> mouseEventBindings = mouseBindingsMap.get(mouseEventType); if (mouseEventBindings == null) { mouseEventBindings = new LinkedList<MouseBinding>(); mouseBindingsMap.put(mouseEventType, mouseEventBindings); } if (first) { mouseEventBindings.addFirst(new MouseBinding(mouseEventMatcher, action)); } else { mouseEventBindings.addLast(new MouseBinding(mouseEventMatcher, action)); } } private void unregisterMouseBinding(MouseEventTypeEnum mouseEventType, IMouseEventMatcher mouseEventMatcher) { LinkedList<MouseBinding> mouseBindings = mouseBindingsMap.get(mouseEventType); for (MouseBinding mouseBinding : mouseBindings) { if (mouseBinding.getMouseEventMatcher().equals(mouseEventMatcher)) { mouseBindings.remove(mouseBinding); return; } } } private enum MouseEventTypeEnum { MOUSE_DOWN, MOUSE_MOVE, MOUSE_SINGLE_CLICK, MOUSE_DOUBLE_CLICK } }