Skip to content

Commit

Permalink
Fixed hotkeys not triggering if the element was outside of the naviga…
Browse files Browse the repository at this point in the history
…tion element node
  • Loading branch information
tomcashman committed May 14, 2017
1 parent f10f89d commit 7a8744f
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 49 deletions.
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ To change it back set config.targetTimestep to 0.1f
- Fixed NPE when resetting navigation with no navigation elements configured
- Fixed GridUiNavigation misordering elements when using set#(x,y)
- Fixed GridUiNavigation triggering unnecessary cursor resets
- Fixed hotkeys not triggering if the element was outside of the navigation element node

[1.4.9]
- Fix @PostDeserialize not being invoked for nested objects
Expand Down
6 changes: 3 additions & 3 deletions ui/src/main/java/org/mini2Dx/ui/render/ModalRenderNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public ActionableRenderNode hotkey(int keycode) {
if (id == null) {
return null;
}
RenderNode<?, ?> renderNode = getElementById(id);
RenderNode<?, ?> renderNode = searchTreeForElementById(id);
if (renderNode == null) {
return null;
}
Expand All @@ -60,7 +60,7 @@ public ActionableRenderNode hotkey(ControllerButton controllerButton) {
if (id == null) {
return null;
}
RenderNode<?, ?> renderNode = getElementById(id);
RenderNode<?, ?> renderNode = searchTreeForElementById(id);
if (renderNode == null) {
return null;
}
Expand Down Expand Up @@ -103,7 +103,7 @@ public ActionableRenderNode navigate(int keycode) {
if (actionable == null) {
return null;
}
return (ActionableRenderNode) getElementById(actionable.getId());
return (ActionableRenderNode) searchTreeForElementById(actionable.getId());
}

@Override
Expand Down
8 changes: 8 additions & 0 deletions ui/src/main/java/org/mini2Dx/ui/render/ParentRenderNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ public void layout(LayoutState layoutState) {
}

float parentWidth = layoutState.getParentWidth();
rootNode = layoutState.getUiContainerRenderTree();
style = determineStyleRule(layoutState);

if(this.zIndex != element.getZIndex()) {
Expand Down Expand Up @@ -280,6 +281,13 @@ public void setState(NodeState state) {
return null;
}

public RenderNode<?, ?> searchTreeForElementById(String id) {
if(rootNode == null) {
return getElementById(id);
}
return rootNode.getElementById(id);
}

public LayoutRuleset getLayoutRuleset() {
return layoutRuleset;
}
Expand Down
2 changes: 2 additions & 0 deletions ui/src/main/java/org/mini2Dx/ui/render/RenderNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public abstract class RenderNode<T extends UiElement, S extends StyleRule> imple
protected final ParentRenderNode<?, ?> parent;
protected final T element;

protected UiContainerRenderTree rootNode;
protected S style;
protected float preferredContentWidth, preferredContentHeight;
protected float xOffset, yOffset;
Expand Down Expand Up @@ -195,6 +196,7 @@ public void layout(LayoutState layoutState) {
if (!isDirty() && !layoutState.isScreenSizeChanged()) {
return;
}
rootNode = layoutState.getUiContainerRenderTree();
style = determineStyleRule(layoutState);

if (this.zIndex != element.getZIndex()) {
Expand Down
38 changes: 27 additions & 11 deletions ui/src/main/java/org/mini2Dx/ui/render/TabRenderNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,37 @@
* {@link RenderNode} implementation for {@link Tab}
*/
public class TabRenderNode extends RowRenderNode implements NavigatableRenderNode {
private Map<Integer, ActionableRenderNode> keyboardHotkeys = new HashMap<Integer, ActionableRenderNode>();
private Map<String, ActionableRenderNode> controllerHotkeys = new HashMap<String, ActionableRenderNode>();
private Map<Integer, String> keyboardHotkeys = new HashMap<Integer, String>();
private Map<String, String> controllerHotkeys = new HashMap<String, String>();

public TabRenderNode(ParentRenderNode<?, ?> parent, Tab tab) {
super(parent, tab);
}

@Override
public ActionableRenderNode hotkey(int keycode) {
return keyboardHotkeys.get(keycode);
String id = keyboardHotkeys.get(keycode);
if (id == null) {
return null;
}
RenderNode<?, ?> renderNode = searchTreeForElementById(id);
if (renderNode == null) {
return null;
}
return (ActionableRenderNode) renderNode;
}

@Override
public ActionableRenderNode hotkey(ControllerButton controllerButton) {
return controllerHotkeys.get(controllerButton.getAbsoluteValue());
String id = controllerHotkeys.get(controllerButton.getAbsoluteValue());
if (id == null) {
return null;
}
RenderNode<?, ?> renderNode = searchTreeForElementById(id);
if (renderNode == null) {
return null;
}
return (ActionableRenderNode) renderNode;
}

@Override
Expand All @@ -41,9 +57,9 @@ public void syncHotkeys(Queue<ControllerHotKeyOperation> controllerHotKeyOperati
ControllerHotKeyOperation hotKeyOperation = controllerHotKeyOperations.poll();
if (hotKeyOperation.isMapOperation()) {
controllerHotkeys.put(hotKeyOperation.getControllerButton().getAbsoluteValue(),
(ActionableRenderNode) getElementById(hotKeyOperation.getActionable().getId()));
hotKeyOperation.getActionable().getId());
} else {
if(hotKeyOperation.getControllerButton() == null) {
if (hotKeyOperation.getControllerButton() == null) {
controllerHotkeys.clear();
} else {
controllerHotkeys.remove(hotKeyOperation.getControllerButton().getAbsoluteValue());
Expand All @@ -52,10 +68,10 @@ public void syncHotkeys(Queue<ControllerHotKeyOperation> controllerHotKeyOperati
}
while (!keyboardHotKeyOperations.isEmpty()) {
KeyboardHotKeyOperation hotKeyOperation = keyboardHotKeyOperations.poll();
if(hotKeyOperation.isMapOperation()) {
keyboardHotkeys.put(hotKeyOperation.getKeycode(), (ActionableRenderNode) getElementById(hotKeyOperation.getActionable().getId()));
if (hotKeyOperation.isMapOperation()) {
keyboardHotkeys.put(hotKeyOperation.getKeycode(), hotKeyOperation.getActionable().getId());
} else {
if(hotKeyOperation.getKeycode() == Integer.MAX_VALUE) {
if (hotKeyOperation.getKeycode() == Integer.MAX_VALUE) {
keyboardHotkeys.clear();
} else {
keyboardHotkeys.remove(hotKeyOperation.getKeycode());
Expand All @@ -67,10 +83,10 @@ public void syncHotkeys(Queue<ControllerHotKeyOperation> controllerHotKeyOperati
@Override
public ActionableRenderNode navigate(int keycode) {
Actionable actionable = ((Tab) element).getNavigation().navigate(keycode);
if(actionable == null) {
if (actionable == null) {
return null;
}
return (ActionableRenderNode) getElementById(actionable.getId());
return (ActionableRenderNode) searchTreeForElementById(actionable.getId());
}

}
95 changes: 60 additions & 35 deletions ui/src/main/java/org/mini2Dx/ui/render/UiContainerRenderTree.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
package org.mini2Dx.ui.render;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.mini2Dx.core.controller.ControllerType;
import org.mini2Dx.ui.InputSource;
Expand All @@ -30,36 +32,41 @@
*/
public class UiContainerRenderTree extends ParentRenderNode<UiContainer, ParentStyleRule> {
private static final String LOGGING_TAG = UiContainerRenderTree.class.getSimpleName();

private final AssetManager assetManager;

private final Map<String, RenderNode<?, ?>> elementIdLookupCache = new HashMap<String, RenderNode<?, ?>>();

private List<ScreenSizeListener> screenSizeListeners;
private ScreenSize currentScreenSize = ScreenSize.XS;
private boolean screenSizeChanged = false;

public UiContainerRenderTree(UiContainer uiContainer, AssetManager assetManager) {
super(null, uiContainer);
this.assetManager = assetManager;

onResize(uiContainer.getWidth(), uiContainer.getHeight());
}

public void update(float delta) {
super.update(this, delta);
}

public void layout() {
layout(new LayoutState(this, assetManager, element.getTheme(), currentScreenSize, 12, ((UiContainer) element).getWidth(), screenSizeChanged));
layout(new LayoutState(this, assetManager, element.getTheme(), currentScreenSize, 12,
((UiContainer) element).getWidth(), screenSizeChanged));
}

@Override
public void layout(LayoutState layoutState) {
if(!isDirty() && !layoutState.isScreenSizeChanged()) {
if (!isDirty() && !layoutState.isScreenSizeChanged()) {
return;
}
if(element.isDebugEnabled()) {
if (element.isDebugEnabled()) {
Gdx.app.log(LOGGING_TAG, "Layout triggered");
}
rootNode = this;
elementIdLookupCache.clear();

style = determineStyleRule(layoutState);
zIndex = element.getZIndex();
flexDirection = element.getFlexDirection();
Expand All @@ -68,81 +75,81 @@ public void layout(LayoutState layoutState) {
xOffset = determineXOffset(layoutState);
yOffset = determineYOffset(layoutState);
outerArea.forceTo(xOffset, yOffset, preferredContentWidth, preferredContentHeight);
for(RenderLayer layer : layers.values()) {

for (RenderLayer layer : layers.values()) {
layer.layout(layoutState);
}

setImmediateDirty(false);
setDirty(false);
childDirty = false;
screenSizeChanged = false;
initialLayoutOccurred = true;
}

@Override
public void addChild(RenderNode<?, ?> child) {
int zIndex = child.getZIndex();
if(!layers.containsKey(zIndex)) {
if (!layers.containsKey(zIndex)) {
layers.put(zIndex, new UiContainerRenderLayer(this, zIndex));
}
layers.get(zIndex).add(child);
setDirty(true);
}

public void onResize(int width, int height) {
ScreenSize screenSize = ScreenSize.XS;
if(width >= ScreenSize.SM.getMinSize()) {
if (width >= ScreenSize.SM.getMinSize()) {
screenSize = ScreenSize.SM;
}
if(width >= ScreenSize.MD.getMinSize()) {
if (width >= ScreenSize.MD.getMinSize()) {
screenSize = ScreenSize.MD;
}
if(width >= ScreenSize.LG.getMinSize()) {
if (width >= ScreenSize.LG.getMinSize()) {
screenSize = ScreenSize.LG;
}
if(width >= ScreenSize.XL.getMinSize()) {
if (width >= ScreenSize.XL.getMinSize()) {
screenSize = ScreenSize.XL;
}
screenSizeChanged = true;
this.currentScreenSize = screenSize;
if(element.isDebugEnabled()) {

if (element.isDebugEnabled()) {
Gdx.app.log(LOGGING_TAG, "Screen resize to " + currentScreenSize + " - " + width + "x" + height);
}
if(screenSizeListeners == null) {

if (screenSizeListeners == null) {
return;
}
for(int i = screenSizeListeners.size() - 1; i >= 0; i--) {
for (int i = screenSizeListeners.size() - 1; i >= 0; i--) {
screenSizeListeners.get(i).onScreenSizeChanged(currentScreenSize);
}
}

public void addScreenSizeListener(ScreenSizeListener listener) {
if(screenSizeListeners == null) {
if (screenSizeListeners == null) {
screenSizeListeners = new ArrayList<ScreenSizeListener>(1);
}
screenSizeListeners.add(listener);
}

public void removeScreenSizeListener(ScreenSizeListener listener) {
if(screenSizeListeners == null) {
if (screenSizeListeners == null) {
return;
}
screenSizeListeners.remove(listener);
}

@Override
protected float determinePreferredContentWidth(LayoutState layoutState) {
return ((UiContainer) element).getWidth();
}

@Override
protected float determinePreferredContentHeight(LayoutState layoutState) {
return ((UiContainer) element).getHeight();
}

@Override
protected float determineXOffset(LayoutState layoutState) {
return 0f;
Expand All @@ -152,21 +159,39 @@ protected float determineXOffset(LayoutState layoutState) {
protected float determineYOffset(LayoutState layoutState) {
return 0f;
}

@Override
protected ParentStyleRule determineStyleRule(LayoutState layoutState) {
return new ParentStyleRule();
}


@Override
public RenderNode<?, ?> getElementById(String id) {
if (element.getId().equals(id)) {
return this;
}
if (elementIdLookupCache.containsKey(id)) {
return elementIdLookupCache.get(id);
}
for (RenderLayer layer : layers.values()) {
RenderNode<?, ?> result = layer.getElementById(id);
if (result != null) {
elementIdLookupCache.put(id, result);
return result;
}
}
return null;
}

@Override
public boolean isDirty() {
return screenSizeChanged || super.isDirty();
}

public InputSource getLastInputSource() {
return ((UiContainer) element).getLastInputSource();
}

public ControllerType getLastControllerType() {
return ((UiContainer) element).getLastControllerType();
}
Expand Down

0 comments on commit 7a8744f

Please sign in to comment.