Implement AlignmentMode in layoutplugin

Summary:
Add a Button to toggle alignment lines on Sonar interface.

Call sonar plugin in java, sending isAlignmentMode flag.

Changed API for setHighlighted to include alignment mode flag.

Button design to be added in future diffs by @[100003260904633:maximg]

Reviewed By: danielbuechele

Differential Revision: D9123749

fbshipit-source-id: 01c299f299be30dbb695bfb1d8007d63c27643d5
This commit is contained in:
Phoomraphee Luenam
2018-08-06 07:38:36 -07:00
committed by Facebook Github Bot
parent 764ad440cb
commit 2c48afdf04
19 changed files with 80 additions and 44 deletions

View File

@@ -30,12 +30,8 @@ public class HighlightedOverlay {
* @param padding A {@link Rect} containing the padding values * @param padding A {@link Rect} containing the padding values
* @param contentBounds The {@link Rect} bounds of the content, which includes padding * @param contentBounds The {@link Rect} bounds of the content, which includes padding
*/ */
public static void setHighlighted(
View targetView, Rect margin, Rect padding, Rect contentBounds) {
setHighlightedAndAlignment(targetView, margin, padding, contentBounds, false);
}
public static void setHighlightedAndAlignment( public static void setHighlighted(
View targetView, Rect margin, Rect padding, Rect contentBounds, boolean isAlignmentMode) { View targetView, Rect margin, Rect padding, Rect contentBounds, boolean isAlignmentMode) {
if (!VIEW_OVERLAY_SUPPORT) { if (!VIEW_OVERLAY_SUPPORT) {
return; return;

View File

@@ -151,7 +151,7 @@ public class InspectorSonarPlugin implements SonarPlugin {
@Override @Override
public void onDisconnect() throws Exception { public void onDisconnect() throws Exception {
if (mHighlightedId != null) { if (mHighlightedId != null) {
setHighlighted(mHighlightedId, false); setHighlighted(mHighlightedId, false, false);
mHighlightedId = null; mHighlightedId = null;
} }
@@ -292,15 +292,15 @@ public class InspectorSonarPlugin implements SonarPlugin {
public void onReceiveOnMainThread(final SonarObject params, SonarResponder responder) public void onReceiveOnMainThread(final SonarObject params, SonarResponder responder)
throws Exception { throws Exception {
final String nodeId = params.getString("id"); final String nodeId = params.getString("id");
final boolean isAlignmentMode = params.getBoolean("isAlignmentMode");
if (mHighlightedId != null) { if (mHighlightedId != null) {
setHighlighted(mHighlightedId, false); setHighlighted(mHighlightedId, false, isAlignmentMode);
} }
if (nodeId != null) { if (nodeId != null) {
setHighlighted(nodeId, true); setHighlighted(nodeId, true, isAlignmentMode);
} }
mHighlightedId = nodeId; mHighlightedId = nodeId;
} }
}; };
@@ -416,7 +416,7 @@ public class InspectorSonarPlugin implements SonarPlugin {
descriptor.hitTest(mApplication, touch); descriptor.hitTest(mApplication, touch);
} }
private void setHighlighted(final String id, final boolean highlighted) throws Exception { private void setHighlighted(final String id, final boolean highlighted, final boolean isAlignmentMode) throws Exception {
final Object obj = mObjectTracker.get(id); final Object obj = mObjectTracker.get(id);
if (obj == null) { if (obj == null) {
return; return;
@@ -427,7 +427,7 @@ public class InspectorSonarPlugin implements SonarPlugin {
return; return;
} }
descriptor.setHighlighted(obj, highlighted); descriptor.setHighlighted(obj, highlighted, isAlignmentMode);
} }
public SearchResultNode searchTree(String query, Object obj) throws Exception { public SearchResultNode searchTree(String query, Object obj) throws Exception {

View File

@@ -167,7 +167,8 @@ public abstract class NodeDescriptor<T> {
* node which is selected in the inspector. The plugin automatically takes care of de-selecting * node which is selected in the inspector. The plugin automatically takes care of de-selecting
* the previously highlighted node. * the previously highlighted node.
*/ */
public abstract void setHighlighted(T node, boolean selected) throws Exception; public abstract void setHighlighted(T node, boolean selected, boolean isAlignmentMode)
throws Exception;
/** /**
* Perform hit testing on the given node. Either continue the search in a child with {@link * Perform hit testing on the given node. Either continue the search in a child with {@link

View File

@@ -78,9 +78,9 @@ public class ActivityDescriptor extends NodeDescriptor<Activity> {
} }
@Override @Override
public void setHighlighted(Activity node, boolean selected) throws Exception { public void setHighlighted(Activity node, boolean selected, boolean isAlignmentMode) throws Exception {
final NodeDescriptor descriptor = descriptorForClass(Window.class); final NodeDescriptor descriptor = descriptorForClass(Window.class);
descriptor.setHighlighted(node.getWindow(), selected); descriptor.setHighlighted(node.getWindow(), selected, isAlignmentMode);
} }
@Override @Override

View File

@@ -186,12 +186,12 @@ public class ApplicationDescriptor extends NodeDescriptor<ApplicationWrapper> {
} }
@Override @Override
public void setHighlighted(ApplicationWrapper node, boolean selected) throws Exception { public void setHighlighted(ApplicationWrapper node, boolean selected, boolean isAlignmentMode) throws Exception {
final int childCount = getChildCount(node); final int childCount = getChildCount(node);
if (childCount > 0) { if (childCount > 0) {
final Object topChild = getChildAt(node, childCount - 1); final Object topChild = getChildAt(node, childCount - 1);
final NodeDescriptor descriptor = descriptorForClass(topChild.getClass()); final NodeDescriptor descriptor = descriptorForClass(topChild.getClass());
descriptor.setHighlighted(topChild, selected); descriptor.setHighlighted(topChild, selected, isAlignmentMode);
} }
} }

View File

@@ -58,9 +58,9 @@ public class DialogDescriptor extends NodeDescriptor<Dialog> {
} }
@Override @Override
public void setHighlighted(Dialog node, boolean selected) throws Exception { public void setHighlighted(Dialog node, boolean selected, boolean isAlignmentMode) throws Exception {
final NodeDescriptor descriptor = descriptorForClass(Window.class); final NodeDescriptor descriptor = descriptorForClass(Window.class);
descriptor.setHighlighted(node.getWindow(), selected); descriptor.setHighlighted(node.getWindow(), selected, isAlignmentMode);
} }
@Override @Override

View File

@@ -71,10 +71,10 @@ public class DialogFragmentDescriptor extends NodeDescriptor<DialogFragment> {
} }
@Override @Override
public void setHighlighted(DialogFragment node, boolean selected) throws Exception { public void setHighlighted(DialogFragment node, boolean selected, boolean isAlignmentMode) throws Exception {
final NodeDescriptor descriptor = descriptorForClass(Dialog.class); final NodeDescriptor descriptor = descriptorForClass(Dialog.class);
if (node.getDialog() != null) { if (node.getDialog() != null) {
descriptor.setHighlighted(node.getDialog(), selected); descriptor.setHighlighted(node.getDialog(), selected, isAlignmentMode);
} }
} }

View File

@@ -107,7 +107,7 @@ public class DrawableDescriptor extends NodeDescriptor<Drawable> {
} }
@Override @Override
public void setHighlighted(Drawable node, boolean selected) { public void setHighlighted(Drawable node, boolean selected, boolean isAlignmentMode) {
// Ensure we handle wrapping drawable // Ensure we handle wrapping drawable
Drawable.Callback callbacks = node.getCallback(); Drawable.Callback callbacks = node.getCallback();
while (callbacks instanceof Drawable) { while (callbacks instanceof Drawable) {
@@ -122,7 +122,7 @@ public class DrawableDescriptor extends NodeDescriptor<Drawable> {
if (selected) { if (selected) {
final Rect zero = new Rect(); final Rect zero = new Rect();
final Rect bounds = node.getBounds(); final Rect bounds = node.getBounds();
HighlightedOverlay.setHighlighted(callbackView, zero, zero, bounds); HighlightedOverlay.setHighlighted(callbackView, zero, zero, bounds, isAlignmentMode);
} else { } else {
HighlightedOverlay.removeHighlight(callbackView); HighlightedOverlay.removeHighlight(callbackView);
} }

View File

@@ -94,13 +94,13 @@ public class FragmentDescriptor extends NodeDescriptor<Fragment> {
} }
@Override @Override
public void setHighlighted(Fragment node, boolean selected) throws Exception { public void setHighlighted(Fragment node, boolean selected, boolean isAlignmentMode) throws Exception {
if (node.getView() == null) { if (node.getView() == null) {
return; return;
} }
final NodeDescriptor descriptor = descriptorForClass(View.class); final NodeDescriptor descriptor = descriptorForClass(View.class);
descriptor.setHighlighted(node.getView(), selected); descriptor.setHighlighted(node.getView(), selected, isAlignmentMode);
} }
@Override @Override

View File

@@ -56,7 +56,7 @@ public class ObjectDescriptor extends NodeDescriptor<Object> {
} }
@Override @Override
public void setHighlighted(Object node, boolean selected) {} public void setHighlighted(Object node, boolean selected, boolean isAlignmentMode) {}
@Override @Override
public void hitTest(Object node, Touch touch) { public void hitTest(Object node, Touch touch) {

View File

@@ -71,10 +71,10 @@ public class SupportDialogFragmentDescriptor extends NodeDescriptor<DialogFragme
} }
@Override @Override
public void setHighlighted(DialogFragment node, boolean selected) throws Exception { public void setHighlighted(DialogFragment node, boolean selected, boolean isAlignmentMode) throws Exception {
final NodeDescriptor descriptor = descriptorForClass(Dialog.class); final NodeDescriptor descriptor = descriptorForClass(Dialog.class);
if (node.getDialog() != null) { if (node.getDialog() != null) {
descriptor.setHighlighted(node.getDialog(), selected); descriptor.setHighlighted(node.getDialog(), selected, isAlignmentMode);
} }
} }

View File

@@ -84,13 +84,13 @@ public class SupportFragmentDescriptor extends NodeDescriptor<Fragment> {
} }
@Override @Override
public void setHighlighted(Fragment node, boolean selected) throws Exception { public void setHighlighted(Fragment node, boolean selected, boolean isAlignmentMode) throws Exception {
if (node.getView() == null) { if (node.getView() == null) {
return; return;
} }
final NodeDescriptor descriptor = descriptorForClass(View.class); final NodeDescriptor descriptor = descriptorForClass(View.class);
descriptor.setHighlighted(node.getView(), selected); descriptor.setHighlighted(node.getView(), selected, isAlignmentMode);
} }
@Override @Override

View File

@@ -138,9 +138,9 @@ public class TextViewDescriptor extends NodeDescriptor<TextView> {
} }
@Override @Override
public void setHighlighted(TextView node, boolean selected) throws Exception { public void setHighlighted(TextView node, boolean selected, boolean isAlignmentMode) throws Exception {
final NodeDescriptor descriptor = descriptorForClass(View.class); final NodeDescriptor descriptor = descriptorForClass(View.class);
descriptor.setHighlighted(node, selected); descriptor.setHighlighted(node, selected, isAlignmentMode);
} }
@Override @Override

View File

@@ -477,7 +477,7 @@ public class ViewDescriptor extends NodeDescriptor<View> {
} }
@Override @Override
public void setHighlighted(View node, boolean selected) { public void setHighlighted(View node, boolean selected, boolean isAlignmentMode) {
// We need to figure out whether the given View has a parent View since margins are not // We need to figure out whether the given View has a parent View since margins are not
// included within a View's bounds. So, in order to display the margin values for a particular // included within a View's bounds. So, in order to display the margin values for a particular
// view, we need to apply an overlay on its parent rather than itself. // view, we need to apply an overlay on its parent rather than itself.
@@ -525,7 +525,7 @@ public class ViewDescriptor extends NodeDescriptor<View> {
contentBounds.offset(-left, -top); contentBounds.offset(-left, -top);
} }
HighlightedOverlay.setHighlighted(targetView, margin, padding, contentBounds); HighlightedOverlay.setHighlighted(targetView, margin, padding, contentBounds, isAlignmentMode);
} }
@Override @Override

View File

@@ -243,9 +243,9 @@ public class ViewGroupDescriptor extends NodeDescriptor<ViewGroup> {
} }
@Override @Override
public void setHighlighted(ViewGroup node, boolean selected) throws Exception { public void setHighlighted(ViewGroup node, boolean selected, boolean isAlignmentMode) throws Exception {
final NodeDescriptor descriptor = descriptorForClass(View.class); final NodeDescriptor descriptor = descriptorForClass(View.class);
descriptor.setHighlighted(node, selected); descriptor.setHighlighted(node, selected, isAlignmentMode);
} }
@Override @Override

View File

@@ -58,9 +58,10 @@ public class WindowDescriptor extends NodeDescriptor<Window> {
} }
@Override @Override
public void setHighlighted(Window node, boolean selected) throws Exception { public void setHighlighted(Window node, boolean selected, boolean isAlignmentMode)
throws Exception {
final NodeDescriptor descriptor = descriptorForClass(View.class); final NodeDescriptor descriptor = descriptorForClass(View.class);
descriptor.setHighlighted(node.getDecorView(), selected); descriptor.setHighlighted(node.getDecorView(), selected, isAlignmentMode);
} }
@Override @Override

View File

@@ -582,7 +582,7 @@ public class DebugComponentDescriptor extends NodeDescriptor<DebugComponent> {
} }
@Override @Override
public void setHighlighted(DebugComponent node, boolean selected) { public void setHighlighted(DebugComponent node, boolean selected, boolean isAlignmentMode) {
final LithoView lithoView = node.getLithoView(); final LithoView lithoView = node.getLithoView();
if (lithoView == null) { if (lithoView == null) {
return; return;
@@ -616,7 +616,7 @@ public class DebugComponentDescriptor extends NodeDescriptor<DebugComponent> {
hasNode ? (int) layout.getResultPadding(YogaEdge.BOTTOM) : 0); hasNode ? (int) layout.getResultPadding(YogaEdge.BOTTOM) : 0);
final Rect contentBounds = node.getBoundsInLithoView(); final Rect contentBounds = node.getBoundsInLithoView();
HighlightedOverlay.setHighlighted(lithoView, margin, padding, contentBounds); HighlightedOverlay.setHighlighted(lithoView, margin, padding, contentBounds, isAlignmentMode);
} }
@Override @Override

View File

@@ -125,9 +125,9 @@ public class LithoViewDescriptor extends NodeDescriptor<LithoView> {
} }
@Override @Override
public void setHighlighted(LithoView node, boolean selected) throws Exception { public void setHighlighted(LithoView node, boolean selected, boolean isAlignmentMode) throws Exception {
final NodeDescriptor descriptor = descriptorForClass(ViewGroup.class); final NodeDescriptor descriptor = descriptorForClass(ViewGroup.class);
descriptor.setHighlighted(node, selected); descriptor.setHighlighted(node, selected, isAlignmentMode);
} }
@Override @Override

View File

@@ -49,6 +49,7 @@ export type InspectorState = {|
AXelements: {[key: ElementID]: Element}, AXelements: {[key: ElementID]: Element},
inAXMode: boolean, inAXMode: boolean,
AXtoNonAXMapping: {[key: ElementID]: ElementID}, AXtoNonAXMapping: {[key: ElementID]: ElementID},
isAlignmentMode: boolean,
|}; |};
type SelectElementArgs = {| type SelectElementArgs = {|
@@ -182,6 +183,7 @@ export default class Layout extends SonarPlugin<InspectorState> {
AXselected: null, AXselected: null,
AXfocused: null, AXfocused: null,
AXtoNonAXMapping: {}, AXtoNonAXMapping: {},
isAlignmentMode: false,
}; };
reducers = { reducers = {
@@ -308,6 +310,13 @@ export default class Layout extends SonarPlugin<InspectorState> {
return {isSearchActive}; return {isSearchActive};
}, },
SetAlignmentActive(
state: InspectorState,
{isAlignmentMode}: {isAlignmentMode: boolean},
) {
return {isAlignmentMode};
},
SetAXMode(state: InspectorState, {inAXMode}: {inAXMode: boolean}) { SetAXMode(state: InspectorState, {inAXMode}: {inAXMode: boolean}) {
return {inAXMode}; return {inAXMode};
}, },
@@ -510,7 +519,10 @@ export default class Layout extends SonarPlugin<InspectorState> {
this.dispatchAction({expand: true, key, type: 'ExpandElement'}); this.dispatchAction({expand: true, key, type: 'ExpandElement'});
} }
this.client.send('setHighlighted', {id: selected}); this.client.send('setHighlighted', {
id: selected,
isAlignmentMode: this.state.isAlignmentMode,
});
this.client.send('setSearchActive', {active: false}); this.client.send('setSearchActive', {active: false});
}, },
); );
@@ -702,6 +714,10 @@ export default class Layout extends SonarPlugin<InspectorState> {
const inAXMode = !this.state.inAXMode; const inAXMode = !this.state.inAXMode;
this.dispatchAction({inAXMode, type: 'SetAXMode'}); this.dispatchAction({inAXMode, type: 'SetAXMode'});
}; };
onToggleAlignment = () => {
const isAlignmentMode = !this.state.isAlignmentMode;
this.dispatchAction({isAlignmentMode, type: 'SetAlignmentActive'});
};
onElementSelected = debounce((key: ElementID) => { onElementSelected = debounce((key: ElementID) => {
let finalKey = key; let finalKey = key;
@@ -737,7 +753,10 @@ export default class Layout extends SonarPlugin<InspectorState> {
AXkey: finalAXkey, AXkey: finalAXkey,
type: 'SelectElement', type: 'SelectElement',
}); });
this.client.send('setHighlighted', {id: key}); this.client.send('setHighlighted', {
id: key,
isAlignmentMode: this.state.isAlignmentMode,
});
this.getNodes([finalKey], {force: true, ax: false}).then( this.getNodes([finalKey], {force: true, ax: false}).then(
(elements: Array<Element>) => { (elements: Array<Element>) => {
this.dispatchAction({elements, type: 'UpdateElements'}); this.dispatchAction({elements, type: 'UpdateElements'});
@@ -753,7 +772,10 @@ export default class Layout extends SonarPlugin<InspectorState> {
}); });
onElementHovered = debounce((key: ?ElementID) => { onElementHovered = debounce((key: ?ElementID) => {
this.client.send('setHighlighted', {id: key}); this.client.send('setHighlighted', {
id: key,
isAlignmentMode: this.state.isAlignmentMode,
});
}); });
onDataValueChanged = (path: Array<string>, value: any) => { onDataValueChanged = (path: Array<string>, value: any) => {
@@ -808,6 +830,7 @@ export default class Layout extends SonarPlugin<InspectorState> {
isSearchActive, isSearchActive,
inAXMode, inAXMode,
outstandingSearchQuery, outstandingSearchQuery,
isAlignmentMode,
} = this.state; } = this.state;
return ( return (
@@ -845,6 +868,21 @@ export default class Layout extends SonarPlugin<InspectorState> {
/> />
</SearchIconContainer> </SearchIconContainer>
) : null} ) : null}
<SearchIconContainer
onClick={this.onToggleAlignment}
role="button"
tabIndex={-1}
title="Toggle AlignmentMode to show alignment lines">
<Glyph
name="borders"
size={16}
color={
isAlignmentMode
? colors.macOSTitleBarIconSelected
: colors.macOSTitleBarIconActive
}
/>
</SearchIconContainer>
<SearchBox tabIndex={-1}> <SearchBox tabIndex={-1}>
<SearchIcon <SearchIcon
name="magnifying-glass" name="magnifying-glass"