浏览代码

add some files about inspector

/zgh-devtools
guanghuispark 4 年前
当前提交
b7dd4161
共有 11 个文件被更改,包括 1354 次插入0 次删除
  1. 23
      com.unity.uiwidgets.devtools/Editor/enum_utils.cs
  2. 8
      com.unity.uiwidgets.devtools/Editor/theme.cs
  3. 450
      com.unity.uiwidgets.devtools/Editor/inspector/layout_explorer/box/box.cs
  4. 374
      com.unity.uiwidgets.devtools/Editor/inspector/layout_explorer/ui/arrow.cs
  5. 39
      com.unity.uiwidgets.devtools/Editor/inspector/layout_explorer/ui/dimension.cs
  6. 170
      com.unity.uiwidgets.devtools/Editor/inspector/layout_explorer/ui/free_space.cs
  7. 70
      com.unity.uiwidgets.devtools/Editor/inspector/layout_explorer/ui/overflow_indicator_painter.cs
  8. 220
      com.unity.uiwidgets.devtools/Editor/inspector/layout_explorer/ui/theme.cs

23
com.unity.uiwidgets.devtools/Editor/enum_utils.cs


using System.Collections.Generic;
using Unity.UIWidgets.foundation;
namespace Unity.UIWidgets.DevTools
{
public class EnumUtils<T> {
EnumUtils(List<T> enumValues) {
foreach (var val in enumValues) {
var enumDescription = DiagnosticUtils.describeEnum(val);
_lookupTable[enumDescription] = val;
_reverseLookupTable[val] = enumDescription;
}
}
Dictionary<string, T> _lookupTable = new Dictionary<string, T>();
Dictionary<T, string> _reverseLookupTable = new Dictionary<T, string>();
T enumEntry(string enumName) => _lookupTable[enumName];
string name(T enumEntry) => _reverseLookupTable[enumEntry];
}
}

8
com.unity.uiwidgets.devtools/Editor/theme.cs


namespace Unity.UIWidgets.DevTools
{
public class CommonThemeUtils
{
public static readonly float denseSpacing = 8.0f;
public static readonly float defaultIconSize = 16.0f;
}
}

450
com.unity.uiwidgets.devtools/Editor/inspector/layout_explorer/box/box.cs


using System;
using System.Collections.Generic;
using System.Linq;
using Unity.UIWidgets.DevTools.inspector.layout_explorer.ui;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEngine;
using ThemeUtils = Unity.UIWidgets.DevTools.inspector.layout_explorer.ui.ThemeUtils;
namespace Unity.UIWidgets.DevTools.inspector.layout_explorer.box{
public class BoxUtils
{
public static string describeBoxName(LayoutProperties properties) {
var title = properties.node.description;
var renderDescription = properties.node?.renderObject?.description;
// TODO(jacobr): consider de-emphasizing the render object name by putting it
// in more transparent text or just calling the widget Parent instead of
// surfacing a widget name.
if(renderDescription != null) {
title += " - $renderDescription";
}
return title;
}
}
public class BoxLayoutExplorerWidget : LayoutExplorerWidget {
public BoxLayoutExplorerWidget(
InspectorController inspectorController,
Key key
) : base(inspectorController, key: key){ }
public static bool shouldDisplay(RemoteDiagnosticsNode node) {
// TODO(jacobr) pass a RemoteDiagnosticsNode to this method that contains
// the layout explorer related supplemental properties so that we can
// accurately determine whether the widget uses box layout.
return node != null;
}
public override State createState()
{
return new _BoxLayoutExplorerWidgetState();
}
}
public class _BoxLayoutExplorerWidgetState :
LayoutExplorerWidgetState<BoxLayoutExplorerWidget, LayoutProperties>
{
public override RemoteDiagnosticsNode getRoot(RemoteDiagnosticsNode node) {
if (!shouldDisplay(node)) return null;
return node;
}
public override bool shouldDisplay(RemoteDiagnosticsNode node) {
return BoxLayoutExplorerWidget.shouldDisplay(selectedNode);
}
public override AnimatedLayoutProperties<LayoutProperties> computeAnimatedProperties(
LayoutProperties nextProperties
) {
return new AnimatedLayoutProperties<LayoutProperties>(
animatedProperties?.copyWith() ?? properties,
nextProperties,
changeAnimation
);
}
public override LayoutProperties computeLayoutProperties(RemoteDiagnosticsNode node)
{
return new LayoutProperties(node);
}
public override void updateHighlighted(LayoutProperties newProperties) {
setState(() =>{
// This implementation will need to change if we support showing more than
// a single widget in the box visualization for the layout explorer.
if (newProperties != null && selectedNode == newProperties.node) {
highlighted = newProperties;
} else {
highlighted = null;
}
});
}
public override Widget build(BuildContext context) {
if (properties == null) return new SizedBox();
return new Container(
margin: EdgeInsets.all(ThemeUtils.margin),
padding: EdgeInsets.only(bottom: ThemeUtils.margin, right: ThemeUtils.margin),
child: new AnimatedBuilder(
animation: changeController,
builder: (context2, _) => {
return new LayoutBuilder(builder: _buildLayout);
}
)
);
}
/// TODO(jacobr): see if we can unify with the stylized version of the overall
/// layout used for Flex. Our constraints are quite different as we can
/// guarantee that the entire layout fits without scrolling while in the Flex
/// case that would be difficult.
static List<float?> minFractionLayout(
float? availableSize,
List<float?> sizes,
List<float?> minFractions
) {
D.assert(sizes.Count == minFractions.Count);
var length = sizes.Count;
float total = 1.0f;
var fractions = minFractions.ToList();
foreach (var size in sizes) {
if (size != null) {
total += Mathf.Max(0, size.Value);
}
}
float totalFraction = 0.0f;
for (int i = 0; i < length; i++) {
var size = sizes[i];
if (size != null) {
fractions[i] = Mathf.Max(size.Value / total, minFractions[i]?? 0.0f);
totalFraction += fractions[i].Value;
} else {
fractions[i] = 0.0f;
}
}
if (Mathf.Abs(totalFraction - 1.0f) > 1E-10) {
for (int i = 0; i < length; i++) {
fractions[i] = fractions[i] / totalFraction;
}
}
var output = new List<float?>();
foreach (var fraction in fractions) {
output.Add(fraction * availableSize);
}
return output;
}
public Widget _buildChild(BuildContext context) {
var theme = Theme.of(context);
var colorScheme = theme.colorScheme;
var parentProperties = this.parentProperties ?? properties;
var parentSize = parentProperties.size;
var boxParentData = new BoxParentData();
boxParentData.offset = new Offset(0, 0);
var offset = properties.node?.parentData ?? boxParentData;
if (properties.size == null) {
return new Center(
child: new Text(
"Visualizing layouts for ${properties.description} widgets is not yet supported."
)
);
}
return new LayoutBuilder(
builder: (BuildContext context2, BoxConstraints constraints) =>
{
// Subtract out one pixel border on each side.
var availableHeight = constraints.maxHeight - 2;
var availableWidth = constraints.maxWidth - 2;
var minFractions = new List<float?> {0.2f, 0.5f, 0.2f};
float? nullOutZero(float value)
{
return value != 0.0f ? value : (float?) null;
}
var widths = new List<float?>
{
nullOutZero(offset.offset.dx),
properties.size.width,
nullOutZero(parentSize != null
? parentSize.width - (properties.size.width + offset.offset.dx)
: 0.0f)
};
var heights = new List<float?>
{
nullOutZero(offset.offset.dy),
properties.size.height,
nullOutZero(parentSize != null
? parentSize.height - (properties.size.height + offset.offset.dy)
: 0.0f)
};
// 3 element array with [left padding, widget width, right padding].
var displayWidths = minFractionLayout(
availableSize: availableWidth,
sizes: widths,
minFractions: minFractions
);
// 3 element array with [top padding, widget height, bottom padding].
var displayHeights = minFractionLayout(
availableSize: availableHeight,
sizes: heights,
minFractions: minFractions
);
var widgetWidth = displayWidths[1];
var widgetHeight = displayHeights[1];
var safeParentSize = parentSize ?? properties.size;
List<Widget> widgets = new List<Widget>();
widgets.Add(new LayoutExplorerBackground(colorScheme: colorScheme));
if (widths[0] != null)
{
widgets.Add(new PaddingVisualizerWidget(
new RenderProperties(
axis: Axis.horizontal,
size: new Size(displayWidths[0].Value, widgetHeight.Value),
offset: new Offset(0, displayHeights[0].Value),
realSize: new Size(widths[0].Value, safeParentSize.height),
layoutProperties: properties,
isFreeSpace: true
),
horizontal: true
));
}
if (heights[0] != null)
{
widgets.Add(new PaddingVisualizerWidget(
new RenderProperties(
axis: Axis.horizontal,
size: new Size(widgetWidth.Value, displayHeights[0].Value),
offset: new Offset(displayWidths[0].Value, 0),
realSize: new Size(safeParentSize.width, heights[0].Value),
layoutProperties: properties,
isFreeSpace: true
),
horizontal: false
));
}
if (widths[2] != null)
{
widgets.Add(new PaddingVisualizerWidget(
new RenderProperties(
axis: Axis.horizontal,
size: new Size(displayWidths[2].Value, widgetHeight.Value),
offset: new Offset(
displayWidths[0].Value + displayWidths[1].Value, displayHeights[0].Value),
realSize: new Size(widths[2].Value, safeParentSize.height),
layoutProperties: properties,
isFreeSpace: true
),
horizontal: true
));
}
if (heights[2] != null)
{
widgets.Add(new PaddingVisualizerWidget(
new RenderProperties(
axis: Axis.horizontal,
size: new Size(widgetWidth.Value, displayHeights[2].Value),
offset: new Offset(displayWidths[0].Value,
displayHeights[0].Value + displayHeights[1].Value),
realSize: new Size(safeParentSize.width, heights[2].Value),
layoutProperties: properties,
isFreeSpace: true
),
horizontal: false
));
}
widgets.Add(new BoxChildVisualizer(
isSelected: true,
state: this,
layoutProperties: properties,
renderProperties:
new RenderProperties(
axis: Axis.horizontal,
size: new Size(widgetWidth.Value, widgetHeight.Value),
offset: new Offset(displayWidths[0].Value, displayHeights[0].Value),
realSize: properties.size,
layoutProperties: properties
)
));
return new Container(
width: constraints.maxWidth,
height: constraints.maxHeight,
decoration: new BoxDecoration(
border: Border.all(
color: ThemeUtils.regularWidgetColor
)
),
child: new Stack(
children: widgets
)
);
}
);
}
LayoutProperties parentProperties {
get
{
var parentElement = properties?.node?.parentRenderElement;
if (parentElement == null) return null;
var parentProperties = computeLayoutProperties(parentElement);
if (parentProperties.size == null) return null;
return parentProperties;
}
}
Widget _buildLayout(BuildContext context, BoxConstraints constraints) {
var maxHeight = constraints.maxHeight;
var maxWidth = constraints.maxWidth;
Widget widget = _buildChild(context);
var parentProperties = this.parentProperties;
if (parentProperties != null) {
widget = new WidgetVisualizer(
// TODO(jacobr): this node's name can be misleading more often than
// in the flex case the widget doesn't have its own RenderObject.
// Consider showing the true ancestor for the summary tree that first
// has a different render object.
title: BoxUtils.describeBoxName(parentProperties),
largeTitle: true,
layoutProperties: parentProperties,
isSelected: false,
child: new VisualizeWidthAndHeightWithConstraints(
properties: parentProperties,
warnIfUnconstrained: false,
child: new Padding(
padding: EdgeInsets.all(CommonThemeUtils.denseSpacing),
child: widget
)
)
);
}
return new Container(
constraints: new BoxConstraints(maxWidth: maxWidth, maxHeight: maxHeight),
child: widget
);
}
}
public class BoxChildVisualizer : StatelessWidget {
public BoxChildVisualizer(
Key key = null,
_BoxLayoutExplorerWidgetState state = null,
LayoutProperties layoutProperties = null,
RenderProperties renderProperties = null,
bool isSelected = false
) : base(key: key)
{
this.state = state;
this.layoutProperties = layoutProperties;
this.renderProperties = renderProperties;
this.isSelected = isSelected;
}
public readonly _BoxLayoutExplorerWidgetState state;
public readonly bool isSelected;
public readonly LayoutProperties layoutProperties;
public readonly RenderProperties renderProperties;
public LayoutProperties root
{
get
{
return state.properties;
}
}
public LayoutProperties properties
{
get
{
return renderProperties.layoutProperties;
}
}
public override Widget build(BuildContext context2) {
var renderSize = renderProperties.size;
var renderOffset = renderProperties.offset;
Widget buildEntranceAnimation(BuildContext context3, Widget child) {
var size = renderSize;
// TODO(jacobr): does this entrance animation really add value.
return new Opacity(
opacity: Mathf.Min(state.entranceCurve.value * 5, 1.0f),
child: new Padding(
padding: EdgeInsets.symmetric(
horizontal: Mathf.Max(0.0f, (renderSize.width - size.width) / 2),
vertical: Mathf.Max(0.0f, (renderSize.height - size.height) / 2)
),
child: child
)
);
}
return new Positioned(
top: renderOffset.dy,
left: renderOffset.dx,
child: new InkWell(
onTap: () => state.onTap(properties),
onDoubleTap: () => state.onDoubleTap(properties),
onLongPress: () => state.onDoubleTap(properties),
child: new SizedBox(
width: utils.safePositiveFloat(renderSize.width),
height: utils.safePositiveFloat(renderSize.height),
child: new AnimatedBuilder(
animation: state.entranceController,
builder: buildEntranceAnimation,
child: new WidgetVisualizer(
isSelected: isSelected,
layoutProperties: layoutProperties,
title: BoxUtils.describeBoxName(properties),
// TODO(jacobr): consider surfacing the overflow size information
// if we determine
// overflowSide: properties.overflowSide,
// We only show one child at a time so a large title is safe.
largeTitle: true,
child: new VisualizeWidthAndHeightWithConstraints(
arrowHeadSize: ThemeUtils.arrowHeadSize,
properties: properties,
warnIfUnconstrained: false,
child: null
)
)
)
)
)
);
}
}
}

374
com.unity.uiwidgets.devtools/Editor/inspector/layout_explorer/ui/arrow.cs


using System.Collections.Generic;
using uiwidgets;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEngine;
using Canvas = Unity.UIWidgets.ui.Canvas;
using Color = Unity.UIWidgets.ui.Color;
namespace Unity.UIWidgets.DevTools.inspector.layout_explorer.ui
{
public class ArrowUtils{
public static Color defaultArrowColor = Colors.white;
public static float defaultArrowStrokeWidth = 2.0f;
public static float defaultDistanceToArrow = 4.0f;
public static Axis axis(ArrowType? type)
{
return (type == ArrowType.up || type == ArrowType.down)
? Axis.vertical
: Axis.horizontal;
}
}
public enum ArrowType {
up,
left,
right,
down,
}
public class ArrowWrapper : StatelessWidget {
public ArrowWrapper(
Key key = null,
Widget child = null,
ArrowType? type = null,
Color arrowColor = null,
float? arrowHeadSize = null,
float? arrowStrokeWidth = null,
float? childMarginFromArrow = null
)
{
D.assert(type != null);
D.assert(arrowHeadSize != null && arrowHeadSize > 0.0);
D.assert(arrowStrokeWidth != null && arrowHeadSize > 0.0);
D.assert(childMarginFromArrow != null && childMarginFromArrow > 0.0);
direction = ArrowUtils.axis(type);
isBidirectional = false;
startArrowType = type;
endArrowType = type;
this.child = child;
this.arrowColor = arrowColor?? ArrowUtils.defaultArrowColor;
this.arrowHeadSize = arrowHeadSize?? CommonThemeUtils.defaultIconSize;
this.arrowStrokeWidth = arrowStrokeWidth ?? ArrowUtils.defaultArrowStrokeWidth;
this.childMarginFromArrow = childMarginFromArrow ?? ArrowUtils.defaultDistanceToArrow;
}
public ArrowWrapper(
Key key = null,
Widget child = null,
Axis? direction = null,
Color arrowColor = null,
float? arrowHeadSize = null,
float? arrowStrokeWidth = null,
float? childMarginFromArrow = null
)
{
D.assert(direction != null);
D.assert(arrowColor != null);
D.assert(arrowHeadSize != null && arrowHeadSize >= 0.0);
D.assert(arrowStrokeWidth != null && arrowHeadSize >= 0.0);
D.assert(childMarginFromArrow != null && childMarginFromArrow >= 0.0);
isBidirectional = true;
startArrowType =
direction == Axis.horizontal ? ArrowType.left : ArrowType.up;
endArrowType =
direction == Axis.horizontal ? ArrowType.right : ArrowType.down;
this.child = child;
this.direction = direction;
this.arrowColor = arrowColor?? ArrowUtils.defaultArrowColor;
this.arrowHeadSize = arrowHeadSize?? CommonThemeUtils.defaultIconSize;
this.arrowStrokeWidth = arrowStrokeWidth ?? ArrowUtils.defaultArrowStrokeWidth;
this.childMarginFromArrow = childMarginFromArrow ?? ArrowUtils.defaultDistanceToArrow;
}
public readonly Color arrowColor;
public readonly float? arrowHeadSize;
public readonly float? arrowStrokeWidth;
public readonly Widget child;
public readonly float childMarginFromArrow;
public readonly Axis? direction;
public readonly bool isBidirectional;
public readonly ArrowType? startArrowType;
public readonly ArrowType? endArrowType;
public float verticalMarginFromArrow {
get
{
if (child == null || direction == Axis.horizontal) return 0.0f;
return childMarginFromArrow;
}
}
public float horizontalMarginFromArrow {
get
{
if (child == null || direction == Axis.vertical) return 0.0f;
return childMarginFromArrow;
}
}
public override Widget build(BuildContext context)
{
List<Widget> widgets = new List<Widget>();
widgets.Add(new Expanded(
child: new Container(
margin: EdgeInsets.only(
bottom: verticalMarginFromArrow,
right: horizontalMarginFromArrow
),
child: new ArrowWidget(
color: arrowColor,
headSize: arrowHeadSize,
strokeWidth: arrowStrokeWidth,
type: startArrowType,
shouldDrawHead: isBidirectional
? true
: (startArrowType == ArrowType.left ||
startArrowType == ArrowType.up)
)
)
));
if(child!= null)widgets.Add(child);
widgets.Add(new Expanded(
child: new Container(
margin: EdgeInsets.only(
top: verticalMarginFromArrow,
left: horizontalMarginFromArrow
),
child: new ArrowWidget(
color: arrowColor,
headSize: arrowHeadSize,
strokeWidth: arrowStrokeWidth,
type: endArrowType,
shouldDrawHead: isBidirectional
? true
: (endArrowType == ArrowType.right ||
endArrowType == ArrowType.down)
)
)
));
return new Flex(
direction: direction.Value,
children: widgets
);
}
}
public class ArrowWidget : StatelessWidget {
public ArrowWidget(
Color color = null,
float? headSize = null,
Key key = null,
bool shouldDrawHead = true,
float? strokeWidth = null,
ArrowType? type = null
) : base(key: key)
{
this.headSize = headSize ?? CommonThemeUtils.defaultIconSize;
this.strokeWidth = strokeWidth ?? ArrowUtils.defaultArrowStrokeWidth;
D.assert(headSize != null && headSize > 0.0);
D.assert(strokeWidth != null && strokeWidth > 0.0);
D.assert(type != null);
this.color = color ?? ArrowUtils.defaultArrowColor;
this.shouldDrawHead = shouldDrawHead;
this.type = type;
_painter = new _ArrowPainter(
headSize: headSize,
color: color,
strokeWidth: strokeWidth,
type: type,
shouldDrawHead: shouldDrawHead
);
}
public readonly Color color;
/// The arrow head is a Equilateral triangle
public readonly float? headSize;
public readonly float? strokeWidth;
public readonly ArrowType? type;
public readonly CustomPainter _painter;
public readonly bool shouldDrawHead;
public override Widget build(BuildContext context) {
return new CustomPaint(
painter: _painter,
child: new Container()
);
}
}
public class _ArrowPainter : CustomPainter {
public _ArrowPainter(
float? headSize = null,
float? strokeWidth = null,
Color color = null,
bool shouldDrawHead = true,
ArrowType? type = null
)
{
D.assert(headSize != null);
D.assert(color != null);
D.assert(strokeWidth != null);
D.assert(type != null);
D.assert(shouldDrawHead != null);
// the height of an equilateral triangle
headHeight = 0.5f * Mathf.Sqrt(3) * headSize.Value;
this.headSize = headSize?? CommonThemeUtils.defaultIconSize;
this.strokeWidth = strokeWidth?? ArrowUtils.defaultArrowStrokeWidth;
this.color = color?? ArrowUtils.defaultArrowColor;
this.shouldDrawHead = shouldDrawHead;
this.type = type;
}
public readonly Color color;
public readonly float headSize;
public readonly bool shouldDrawHead;
public readonly float strokeWidth;
public readonly ArrowType? type;
public readonly float headHeight;
bool headIsGreaterThanConstraint(Size size) {
if (type == ArrowType.left || type == ArrowType.right) {
return headHeight >= (size.width);
}
return headHeight >= (size.height);
}
public bool shouldRepaint(CustomPainter oldDelegate)
{
return !(oldDelegate is _ArrowPainter &&
headSize == ((_ArrowPainter)oldDelegate).headSize &&
strokeWidth == ((_ArrowPainter)oldDelegate).strokeWidth &&
color == ((_ArrowPainter)oldDelegate).color &&
type == ((_ArrowPainter)oldDelegate).type);
}
public void paint(Canvas canvas, Size size)
{
Paint paint = new Paint();
paint.color = color;
paint.strokeWidth = strokeWidth;
var originX = size.width / 2;
var originY = size.height / 2;
Offset lineStartingPoint = Offset.zero;
Offset lineEndingPoint = Offset.zero;
if (!headIsGreaterThanConstraint(size) && shouldDrawHead) {
Offset p1 = null, p2 = null, p3 = null;
var headSizeDividedBy2 = headSize / 2;
switch (type) {
case ArrowType.up:
p1 = new Offset(originX, 0);
p2 = new Offset(originX - headSizeDividedBy2, headHeight);
p3 = new Offset(originX + headSizeDividedBy2, headHeight);
break;
case ArrowType.left:
p1 = new Offset(0, originY);
p2 = new Offset(headHeight, originY - headSizeDividedBy2);
p3 = new Offset(headHeight, originY + headSizeDividedBy2);
break;
case ArrowType.right:
var startingX = size.width - headHeight;
p1 = new Offset(size.width, originY);
p2 = new Offset(startingX, originY - headSizeDividedBy2);
p3 = new Offset(startingX, originY + headSizeDividedBy2);
break;
case ArrowType.down:
var startingY = size.height - headHeight;
p1 = new Offset(originX, size.height);
p2 = new Offset(originX - headSizeDividedBy2, startingY);
p3 = new Offset(originX + headSizeDividedBy2, startingY);
break;
}
Path path = new Path();
path.moveTo(p1.dx, p1.dy);
path.lineTo(p2.dx, p2.dy);
path.lineTo(p3.dx, p3.dy);
path.close();
canvas.drawPath(path, paint);
switch (type) {
case ArrowType.up:
lineStartingPoint = new Offset(originX, headHeight);
lineEndingPoint = new Offset(originX, size.height);
break;
case ArrowType.left:
lineStartingPoint = new Offset(headHeight, originY);
lineEndingPoint = new Offset(size.width, originY);
break;
case ArrowType.right:
var arrowHeadStartingX = size.width - headHeight;
lineStartingPoint = new Offset(0, originY);
lineEndingPoint = new Offset(arrowHeadStartingX, originY);
break;
case ArrowType.down:
var headStartingY = size.height - headHeight;
lineStartingPoint = new Offset(originX, 0);
lineEndingPoint = new Offset(originX, headStartingY);
break;
}
} else {
// draw full line
switch (type) {
case ArrowType.up:
case ArrowType.down:
lineStartingPoint = new Offset(originX, 0);
lineEndingPoint = new Offset(originX, size.height);
break;
case ArrowType.left:
case ArrowType.right:
lineStartingPoint = new Offset(0, originY);
lineEndingPoint = new Offset(size.width, originY);
break;
}
}
canvas.drawLine(
lineStartingPoint,
lineEndingPoint,
paint
);
}
public bool? hitTest(Offset position)
{
throw new System.NotImplementedException();
}
public void addListener(VoidCallback listener)
{
throw new System.NotImplementedException();
}
public void removeListener(VoidCallback listener)
{
throw new System.NotImplementedException();
}
}
}

39
com.unity.uiwidgets.devtools/Editor/inspector/layout_explorer/ui/dimension.cs


using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
namespace Unity.UIWidgets.DevTools.inspector.layout_explorer.ui
{
public class Dimension
{
public static Widget dimensionDescription(
TextSpan description,
bool overflow,
ColorScheme colorScheme
) {
var text = Text.rich(
description,
textAlign: TextAlign.center,
style:
ThemeUtils.dimensionIndicatorTextStyle,
overflow: TextOverflow.ellipsis
);
if (overflow) {
return new Container(
padding: EdgeInsets.symmetric(
vertical: ThemeUtils.minPadding,
horizontal: ThemeUtils.overflowTextHorizontalPadding
),
decoration: new BoxDecoration(
color: ThemeUtils.overflowBackgroundColor,
borderRadius: BorderRadius.circular(4.0f)
),
child: new Center(child: text)
);
}
return text;
}
}
}

170
com.unity.uiwidgets.devtools/Editor/inspector/layout_explorer/ui/free_space.cs


using System.Collections.Generic;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.widgets;
namespace Unity.UIWidgets.DevTools.inspector.layout_explorer.ui
{
public class FreeSpaceVisualizerWidget : StatelessWidget {
public FreeSpaceVisualizerWidget(
RenderProperties renderProperties,
Key key = null
) : base(key: key)
{
}
public readonly RenderProperties renderProperties;
public override Widget build(BuildContext context) {
var colorScheme = Theme.of(context).colorScheme;
var heightDescription =
$"h={renderProperties.realHeight}";
var widthDescription = $"w={renderProperties.realWidth}";
var showWidth = renderProperties.realWidth !=
(renderProperties.layoutProperties?.width);
var widthWidget = new Container(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: new List<Widget>{
new Flexible(
child: Dimension.dimensionDescription(
new TextSpan(
text: widthDescription
),
false,
colorScheme
)
),
new Container(
margin: EdgeInsets.symmetric(vertical: ThemeUtils.arrowMargin),
child: new ArrowWrapper(
arrowColor: ThemeUtils.widthIndicatorColor,
direction: Axis.horizontal,
arrowHeadSize: ThemeUtils.arrowHeadSize
)
),
}
)
);
var heightWidget = new Container(
width: ThemeUtils.heightOnlyIndicatorSize,
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: new List<Widget>{
new Flexible(
child: Dimension.dimensionDescription(
new TextSpan(text: heightDescription),
false,
colorScheme
)
),
new Container(
margin: EdgeInsets.symmetric(horizontal: ThemeUtils.arrowMargin),
child: new ArrowWrapper(
arrowColor: ThemeUtils.heightIndicatorColor,
direction: Axis.vertical,
arrowHeadSize: ThemeUtils.arrowHeadSize,
childMarginFromArrow: 0.0f
)
)
}
)
);
return new Positioned(
top: renderProperties.offset.dy,
left: renderProperties.offset.dx,
child: new Container(
width: renderProperties.width,
height: renderProperties.height,
child: new Tooltip(
message: $"{widthDescription}\n{heightDescription}",
child: showWidth ? widthWidget : heightWidget
)
)
);
}
}
public class PaddingVisualizerWidget : StatelessWidget {
public PaddingVisualizerWidget(
RenderProperties renderProperties,
bool horizontal,
Key key = null
) : base(key: key)
{
this.renderProperties = renderProperties;
this.horizontal = horizontal;
}
public readonly RenderProperties renderProperties;
public readonly bool horizontal;
public override Widget build(BuildContext context) {
var colorScheme = Theme.of(context).colorScheme;
var heightDescription =
$"h={renderProperties.realHeight}";
var widthDescription = $"w={renderProperties.realWidth}";
var widthWidget = new Container(child:
new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: new List<Widget>{
new Flexible(
child: Dimension.dimensionDescription(
new TextSpan(
text: widthDescription
),
false,
colorScheme
)
),
new Container(
margin: EdgeInsets.symmetric(vertical: ThemeUtils.arrowMargin),
child: new ArrowWrapper(
arrowColor: ThemeUtils.widthIndicatorColor,
direction: Axis.horizontal,
arrowHeadSize: ThemeUtils.arrowHeadSize
)
)
}
)
);
var heightWidget = new Container(
width: ThemeUtils.heightOnlyIndicatorSize,
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: new List<Widget>{
new Flexible(
child: Dimension.dimensionDescription(
new TextSpan(text: heightDescription),
false,
colorScheme
)
),
new Container(
margin: EdgeInsets.symmetric(horizontal: ThemeUtils.arrowMargin),
child: new ArrowWrapper(
arrowColor: ThemeUtils.heightIndicatorColor,
direction: Axis.vertical,
arrowHeadSize: ThemeUtils.arrowHeadSize,
childMarginFromArrow: 0.0f
)
)
}
)
);
return new Positioned(
top: renderProperties.offset.dy,
left: renderProperties.offset.dx,
child: new Container(
width: utils.safePositiveFloat(renderProperties.width),
height: utils.safePositiveFloat(renderProperties.height),
child: horizontal ? widthWidget : heightWidget
)
);
}
}
}

70
com.unity.uiwidgets.devtools/Editor/inspector/layout_explorer/ui/overflow_indicator_painter.cs


using System.Collections.Generic;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
namespace Unity.UIWidgets.DevTools.inspector.layout_explorer.ui
{
public class OverflowIndicatorPainter : CustomPainter {
public OverflowIndicatorPainter(OverflowSide side, float size)
{
this.side = side;
this.size = size;
indicatorPaint.shader = Gradient.linear(
new Offset(0.0f, 0.0f),
new Offset(10.0f, 10.0f),
new List<Color>{
black, yellow, yellow, black
},
new List<float>{
0.25f, 0.25f, 0.75f, 0.75f
},
TileMode.repeated
);
}
public readonly OverflowSide side;
public readonly float size;
Color black = new Color(0xBF000000);
Color yellow = new Color(0xBFFFFF00);
Paint indicatorPaint = new Paint();
public void paint(Canvas canvas, Size size) {
var bottomOverflow = OverflowSide.bottom == side;
var width = bottomOverflow ? size.width : this.size;
var height = !bottomOverflow ? size.height : this.size;
var left = bottomOverflow ? 0.0f : size.width - width;
var top = side == OverflowSide.right ? 0.0f : size.height - height;
var rect = Rect.fromLTWH(left, top, width, height);
canvas.drawRect(rect, indicatorPaint);
}
public bool shouldRepaint(CustomPainter oldDelegate) {
return oldDelegate is OverflowIndicatorPainter &&
(side != ((OverflowIndicatorPainter)oldDelegate).side || size != ((OverflowIndicatorPainter)oldDelegate).size);
}
public bool? hitTest(Offset position)
{
throw new System.NotImplementedException();
}
public void addListener(VoidCallback listener)
{
throw new System.NotImplementedException();
}
public void removeListener(VoidCallback listener)
{
throw new System.NotImplementedException();
}
}
}

220
com.unity.uiwidgets.devtools/Editor/inspector/layout_explorer/ui/theme.cs


using uiwidgets;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using TextStyle = Unity.UIWidgets.painting.TextStyle;
namespace Unity.UIWidgets.DevTools.inspector.layout_explorer.ui
{
public class ThemeUtils
{
public static readonly float margin = 8.0f;
public static readonly float arrowHeadSize = 8.0f;
public static readonly float arrowMargin = 4.0f;
public static readonly float arrowStrokeWidth = 1.5f;
/// Hardcoded sizes for scaling the flex children widget properly.
public static readonly float minRenderWidth = 250.0f;
public static readonly float minRenderHeight = 250.0f;
public static readonly float minPadding = 2.0f;
public static readonly float overflowTextHorizontalPadding = 8.0f;
/// The size to shrink a widget by when animating it in.
public static readonly float entranceMargin = 50.0f;
public static readonly float defaultMaxRenderWidth = 400.0f;
public static readonly float defaultMaxRenderHeight = 400.0f;
public static readonly float widgetTitleMaxWidthPercentage = 0.75f;
/// Hardcoded arrow size respective to its cross axis (because it's unconstrained).
public static readonly float heightAndConstraintIndicatorSize = 48.0f;
public static readonly float widthAndConstraintIndicatorSize = 56.0f;
public static readonly float mainAxisArrowIndicatorSize = 48.0f;
public static readonly float crossAxisArrowIndicatorSize = 48.0f;
public static readonly float heightOnlyIndicatorSize = 72.0f;
public static readonly float widthOnlyIndicatorSize = 32.0f;
/// Minimum size to display width/height inside the arrow
public static readonly float minWidthToDisplayWidthInsideArrow = 200.0f;
public static readonly float minHeightToDisplayHeightInsideArrow = 200.0f;
public static readonly float largeTextScaleFactor = 1.2f;
public static readonly float smallTextScaleFactor = 0.8f;
/// Height for limiting asset image (selected one in the drop down).
public static readonly float axisAlignmentAssetImageHeight = 24.0f;
/// Width for limiting asset image (when drop down menu is open for the vertical).
public static readonly float axisAlignmentAssetImageWidth = 96.0f;
public static readonly float dropdownMaxSize = 220.0f;
public static readonly float minHeightToAllowTruncating = 375.0f;
public static readonly float minWidthToAllowTruncating = 375.0f;
// Story of Layout colors
public static readonly Color mainAxisLightColor = new Color(0xff2c5daa);
public static readonly Color mainAxisDarkColor = new Color(0xff2c5daa);
public static readonly Color rowColor = new Color(0xff2c5daa);
public static readonly Color columnColor = new Color(0xff77974d);
public static readonly Color regularWidgetColor = new Color(0xff88b1de);
public static readonly Color selectedWidgetColor = new Color(0xff36c6f4);
public static readonly Color textColor = new Color(0xff55767f);
public static readonly Color emphasizedTextColor = new Color(0xff009aca);
public static readonly Color crossAxisLightColor = new Color(0xff8ac652);
public static readonly Color crossAxisDarkColor = new Color(0xff8ac652);
public static readonly Color mainAxisTextColorLight = new Color(0xFF1375bc);
public static readonly Color mainAxisTextColorDark = new Color(0xFF1375bc);
public static readonly Color crossAxisTextColorLight = new Color(0xFF66672C);
public static readonly Color crossAxisTextColorsDark = new Color(0xFFB3D25A);
public static readonly Color overflowBackgroundColorDark = new Color(0xFFB00020);
public static readonly Color overflowBackgroundColorLight = new Color(0xFFB00020);
public static readonly Color overflowTextColorDark = new Color(0xfff5846b);
public static readonly Color overflowTextColorLight = new Color(0xffdea089);
public static readonly Color backgroundColorSelectedDark = new Color(
0x4d474747); // TODO(jacobr): we would like Color(0x4dedeeef) but that makes the background show through.
public static readonly Color backgroundColorSelectedLight = new Color(0x4dedeeef);
public static bool isLight = false;
public static Color mainAxisColor
{
get
{
return isLight? mainAxisLightColor : mainAxisDarkColor;
}
}
public static Color widgetNameColor
{
get
{
return isLight ? Colors.white : Colors.black;
}
}
public static Color crossAxisColor
{
get
{
return isLight ? crossAxisLightColor : crossAxisDarkColor;
}
}
public static Color mainAxisTextColor
{
get
{
return isLight ? mainAxisTextColorLight : mainAxisTextColorDark;
}
}
public static Color crossAxisTextColor
{
get
{
return isLight ? crossAxisTextColorLight : crossAxisTextColorsDark;
}
}
public static Color overflowBackgroundColor
{
get
{
return isLight ? overflowBackgroundColorLight : overflowBackgroundColorDark;
}
}
public static Color overflowTextColor
{
get
{
return isLight ? overflowTextColorLight : overflowTextColorDark;
}
}
public static Color backgroundColorSelected
{
get
{
return isLight ? backgroundColorSelectedLight : backgroundColorSelectedDark;
}
}
public static Color backgroundColor
{
get
{
return isLight ? backgroundColorLight : backgroundColorDark;
}
}
public static Color unconstrainedColor
{
get
{
return isLight ? unconstrainedLightColor : unconstrainedDarkColor;
}
}
public static readonly Color backgroundColorDark = new Color(0xff30302f);
public static readonly Color backgroundColorLight = new Color(0xffffffff);
public static readonly Color unconstrainedDarkColor = new Color(0xffdea089);
public static readonly Color unconstrainedLightColor = new Color(0xfff5846b);
public static readonly Color widthIndicatorColor = textColor;
public static readonly Color heightIndicatorColor = textColor;
public static readonly string negativeSpaceDarkAssetName =
"assets/img/layout_explorer/negative_space_dark.png";
public static readonly string negativeSpaceLightAssetName =
"assets/img/layout_explorer/negative_space_light.png";
public static TextStyle dimensionIndicatorTextStyle = new TextStyle(
height: 1.0f,
letterSpacing: 1.1f,
color: emphasizedTextColor
);
public static TextStyle overflowingDimensionIndicatorTextStyle(ColorScheme colorScheme)
{
return new TextStyle(
height: 1.0f,
letterSpacing: 1.1f,
color: overflowTextColor,
fontWeight: FontWeight.bold
);
}
public Widget buildUnderline() {
return new Container(
height: 1.0f,
decoration: new BoxDecoration(
border: new Border(
bottom: new BorderSide(
color: textColor,
width: 0.0f
)
)
)
);
}
}
}
正在加载...
取消
保存