kg
6 年前
当前提交
1c77a600
共有 40 个文件被更改,包括 2230 次插入 和 736 次删除
-
9README.md
-
2Runtime/material/material.cs
-
2Runtime/material/text_selection.cs
-
8Runtime/material/utils.cs
-
80Runtime/painting/image_resolution.cs
-
6Runtime/painting/text_painter.cs
-
2Runtime/painting/text_style.cs
-
15Runtime/rendering/editable.cs
-
6Runtime/rendering/paragraph.cs
-
3Runtime/ui/painting/canvas.cs
-
5Runtime/ui/painting/canvas_impl.cs
-
106Runtime/ui/painting/txt/mesh_generator.cs
-
56Runtime/ui/painting/txt/text_blob.cs
-
4Runtime/ui/text.cs
-
314Runtime/ui/txt/linebreaker.cs
-
721Runtime/ui/txt/paragraph.cs
-
6Runtime/ui/txt/word_separate.cs
-
4Runtime/widgets/basic.cs
-
2Runtime/widgets/routes.cs
-
2Runtime/widgets/scrollbar.cs.meta
-
2Samples/UIWidgetSample/CustomPaintCanvas.cs
-
2Tests/Editor/CanvasAndLayers.cs
-
8Tests/Editor/EditableTextWiget.cs
-
102Runtime/material/scrollbar.cs
-
11Runtime/material/scrollbar.cs.meta
-
218Runtime/rendering/custom_paint.cs
-
11Runtime/rendering/custom_paint.cs.meta
-
102Runtime/ui/txt/layout.cs
-
11Runtime/ui/txt/layout.cs.meta
-
14Runtime/ui/txt/layout_utils.cs
-
11Runtime/ui/txt/layout_utils.cs.meta
-
147Runtime/ui/txt/wordbreaker.cs
-
11Runtime/ui/txt/wordbreaker.cs.meta
-
191Runtime/widgets/scrollbar.cs
-
502Samples/UIWidgetSample/ScrollBar.unity
-
7Samples/UIWidgetSample/ScrollBar.unity.meta
-
42Samples/UIWidgetSample/ScrollbarCanvas.cs
-
11Samples/UIWidgetSample/ScrollbarCanvas.cs.meta
-
210Runtime/widgets/custom_paint.cs
-
0/Runtime/widgets/scrollbar.cs.meta
|
|||
using Unity.UIWidgets.foundation; |
|||
using System.Collections.Generic; |
|||
using Unity.UIWidgets.foundation; |
|||
|
|||
|
|||
public TextBlob(string text, int start, int end, Vector2d[] positions, TextStyle style, Rect bounds) { |
|||
D.assert(start < end); |
|||
public TextBlob(string text, int textOffset, int textSize, Vector2d[] positions, Rect bounds, TextStyle style) { |
|||
this.instanceId = ++_nextInstanceId; |
|||
this.positions = positions; |
|||
this.start = start; |
|||
this.end = end; |
|||
this.positions = positions; |
|||
this.textOffset = textOffset; |
|||
this.textSize = textSize; |
|||
get { return this.bounds.shift(new Offset(this.positions[this.start].x, this.positions[this.start].y)); } |
|||
get { return this.bounds.shift(new Offset(this.positions[0].x, this.positions[0].y)); } |
|||
static long _nextInstanceId = 0; |
|||
public readonly long instanceId; |
|||
public readonly int start; |
|||
public readonly int end; |
|||
public readonly int textOffset; |
|||
public readonly int textSize; |
|||
} |
|||
|
|||
public class TextBlobBuilder { |
|||
TextStyle _style; |
|||
public Vector2d[] positions; |
|||
string _text; |
|||
int _textOffset; |
|||
int _size; |
|||
Rect _bounds; |
|||
|
|||
public void allocRunPos(TextStyle style, string text, int offset, int size) { |
|||
|
|||
this._style = style; |
|||
this._text = text; |
|||
this._textOffset = offset; |
|||
this._size = size; |
|||
if (this.positions == null || this.positions.Length < size) { |
|||
this.positions = new Vector2d[size]; |
|||
} |
|||
} |
|||
|
|||
public void setBounds(Rect bounds) { |
|||
this._bounds = bounds; |
|||
} |
|||
|
|||
public TextBlob make() { |
|||
var result = new TextBlob(this._text, this._textOffset, |
|||
this._size, this.positions, this._bounds, this._style); |
|||
this.positions = null; |
|||
return result; |
|||
} |
|||
} |
|||
} |
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
public class TabStops { |
|||
int _tabWidth = int.MaxValue; |
|||
|
|||
Font _font; |
|||
|
|||
int _fontSize; |
|||
|
|||
const int kTabSpaceCount = 4; |
|||
|
|||
List<int> _stops = new List<int>(); |
|||
|
|||
public void set(List<int> stops, int tabWidth) { |
|||
this._stops.Clear(); |
|||
if (stops != null) { |
|||
this._stops.AddRange(stops); |
|||
} |
|||
|
|||
this._tabWidth = tabWidth; |
|||
} |
|||
|
|||
public void setFont(Font font, int size) { |
|||
if (this._font != font || this._fontSize != size) { |
|||
this._tabWidth = int.MaxValue; |
|||
} |
|||
|
|||
this._font = font; |
|||
this._fontSize = size; |
|||
} |
|||
|
|||
public float nextTab(float widthSoFar) { |
|||
for (int i = 0; i < this._stops.Count; i++) { |
|||
if (this._stops[i] > widthSoFar) { |
|||
return this._stops[i]; |
|||
} |
|||
} |
|||
|
|||
if (this._tabWidth == int.MaxValue) { |
|||
this._font.RequestCharactersInTexture(" ", this._fontSize); |
|||
CharacterInfo characterInfo; |
|||
this._font.GetCharacterInfo(' ', out characterInfo, this._fontSize); |
|||
this._tabWidth = characterInfo.advance * kTabSpaceCount; |
|||
} |
|||
|
|||
if (this._tabWidth == 0) { |
|||
return widthSoFar; |
|||
} |
|||
|
|||
return (float) (Math.Floor(widthSoFar / this._tabWidth + 1) * this._tabWidth); |
|||
} |
|||
} |
|||
|
|||
public class Candidate { |
|||
public int offset; |
|||
public int pre; |
|||
public double preBreak; |
|||
public float penalty; |
|||
|
|||
public double postBreak; |
|||
public int preSpaceCount; |
|||
public int postSpaceCount; |
|||
} |
|||
|
|||
public class LineInfo { |
|||
public int start; |
|||
public double width; |
|||
} |
|||
const float ScoreInfty = float.MaxValue; |
|||
const float ScoreDesperate = 1e10f; |
|||
StyledRuns _runs; |
|||
string _textBuf; |
|||
int _textOffset; |
|||
int _textLength; |
|||
List<float> _charWidths = new List<float>(); |
|||
List<int> _breaks = new List<int>(); |
|||
List<float> _widths = new List<float>(); |
|||
WordBreaker _wordBreaker = new WordBreaker(); |
|||
double _width = 0.0; |
|||
double _preBreak; |
|||
double _lineWidth; |
|||
int _lastBreak; |
|||
int _bestBreak; |
|||
float _bestScore; |
|||
int _spaceCount; |
|||
TabStops _tabStops; |
|||
int mFirstTabIndex; |
|||
List<Candidate> _candidates = new List<Candidate>(); |
|||
public Vector2d[] _characterPositions; |
|||
public double[] _characterWidth; |
|||
string _text; |
|||
double _width; |
|||
int _lineStart; |
|||
int _wordStart; |
|||
int _spaceCount = 0; |
|||
int tabCount = 4; |
|||
double _lineLength; |
|||
public int computeBreaks() { |
|||
int nCand = this._candidates.Count; |
|||
if (nCand > 0 && (nCand == 1 || this._lastBreak != nCand - 1)) { |
|||
var cand = this._candidates[this._candidates.Count - 1]; |
|||
this._pushBreak(cand.offset, (float) (cand.postBreak - this._preBreak)); |
|||
} |
|||
List<LineInfo> _lines; |
|||
return this._breaks.Count; |
|||
} |
|||
public void setup(string text, StyledRuns runs, double width, Vector2d[] characterPositions, |
|||
double[] characterWidth) { |
|||
this._text = text; |
|||
this._runs = runs; |
|||
this._characterPositions = characterPositions; |
|||
this._characterWidth = characterWidth; |
|||
this._width = width; |
|||
public List<int> getBreaks() { |
|||
return this._breaks; |
|||
public List<LineInfo> getLines() { |
|||
return this._lines; |
|||
public void resize(int size) { |
|||
if (this._charWidths.Count < size) { |
|||
this._charWidths.AddRange(Enumerable.Repeat(0.0f, size - this._charWidths.Count)); |
|||
} |
|||
public void doBreak(int blockStart, int blockEnd) { |
|||
this._lines = new List<LineInfo>(); |
|||
this._lineStart = blockStart; |
|||
this._wordStart = blockStart; |
|||
public void setText(string text, int textOffset, int textLength) { |
|||
this._textBuf = text; |
|||
this._textOffset = textOffset; |
|||
this._textLength = textLength; |
|||
this._wordBreaker.setText(this._textBuf, textOffset, textLength); |
|||
this._wordBreaker.next(); |
|||
this._candidates.Clear(); |
|||
Candidate can = new Candidate { |
|||
offset = 0, postBreak = 0, preBreak = 0, postSpaceCount = 0, preSpaceCount = 0, pre = 0 |
|||
}; |
|||
this._candidates.Add(can); |
|||
this._lastBreak = 0; |
|||
this._bestBreak = 0; |
|||
this._bestScore = ScoreInfty; |
|||
this._preBreak = 0; |
|||
this.mFirstTabIndex = int.MaxValue; |
|||
} |
|||
double offsetX = 0.0; |
|||
var runIterator = this._runs.iterator(); |
|||
for (var charIndex = blockStart; charIndex < blockEnd; charIndex++) { |
|||
runIterator.nextTo(charIndex); |
|||
var run = runIterator.run; |
|||
var font = FontManager.instance.getOrCreate(run.style.fontFamily).font; |
|||
public void setLineWidth(float lineWidth) { |
|||
this._lineWidth = lineWidth; |
|||
} |
|||
var style = run.style; |
|||
var charInfo = new CharacterInfo(); |
|||
public float addStyleRun(TextStyle style, int start, int end) { |
|||
float width = 0.0f; |
|||
if (style != null) { |
|||
width = Layout.measureText(this._width - this._preBreak, this._textBuf, |
|||
start + this._textOffset, end - start, style, |
|||
this._charWidths, start, this._tabStops); |
|||
} |
|||
if (this._text[charIndex] == '\t') { |
|||
this._spaceCount++; |
|||
var font = FontManager.instance.getOrCreate(style.fontFamily).font; |
|||
int current = this._wordBreaker.current(); |
|||
int afterWord = start; |
|||
int lastBreak = start; |
|||
font.GetCharacterInfo(' ', out charInfo, |
|||
style.UnityFontSize, style.UnityFontStyle); |
|||
double tabSize = charInfo.advance * this.tabCount; |
|||
var newX = Math.Floor(((offsetX / tabSize) + 1) * tabSize); |
|||
if (newX > this._width && this._lineStart != charIndex) { |
|||
this._characterWidth[charIndex] = tabSize; |
|||
this.makeLine(charIndex, charIndex); |
|||
} |
|||
else { |
|||
this._characterWidth[charIndex] = newX - offsetX; |
|||
this._characterPositions[charIndex].x = offsetX; |
|||
} |
|||
double lastBreakWidth = this._width; |
|||
double postBreak = this._width; |
|||
int postSpaceCount = this._spaceCount; |
|||
offsetX = this._characterPositions[charIndex].x + this._characterWidth[charIndex]; |
|||
} |
|||
else if (this._text[charIndex] == ' ') { |
|||
font.GetCharacterInfo(this._text[charIndex], out charInfo, style.UnityFontSize, |
|||
run.style.UnityFontStyle); |
|||
this._spaceCount++; |
|||
this._characterPositions[charIndex].x = offsetX; |
|||
this._characterWidth[charIndex] = charInfo.advance; |
|||
offsetX = this._characterPositions[charIndex].x + this._characterWidth[charIndex]; |
|||
// todo no wrap in space ?
|
|||
for (int i = start; i < end; i++) { |
|||
char c = this._textBuf[i + this._textOffset]; |
|||
if (c == '\t') { |
|||
this._width = this._preBreak + this._tabStops.nextTab((float) (this._width - this._preBreak)); |
|||
if (this.mFirstTabIndex == int.MaxValue) { |
|||
this.mFirstTabIndex = i; |
|||
} |
|||
font.GetCharacterInfo(this._text[charIndex], out charInfo, style.UnityFontSize, |
|||
run.style.UnityFontStyle); |
|||
if (this._spaceCount > 0 || blockStart == charIndex) { |
|||
this._wordStart = charIndex; |
|||
if (LayoutUtils.isWordSpace(c)) { |
|||
this._spaceCount += 1; |
|||
this._characterPositions[charIndex].x = offsetX; |
|||
this._characterWidth[charIndex] = charInfo.advance; |
|||
this._width += this._charWidths[i]; |
|||
if (!LayoutUtils.isLineEndSpace(c)) { |
|||
postBreak = this._width; |
|||
postSpaceCount = this._spaceCount; |
|||
afterWord = i + 1; |
|||
} |
|||
} |
|||
if (offsetX + charInfo.advance > this._width && this._lineStart != charIndex) { |
|||
if (this._lineStart == this._wordStart) { |
|||
this.makeLine(charIndex, charIndex); |
|||
this._wordStart = charIndex; |
|||
} |
|||
else { |
|||
this.makeLine(this._wordStart, charIndex); |
|||
} |
|||
if (i + 1 == current) { |
|||
int wordStart = this._wordBreaker.wordStart(); |
|||
int wordEnd = this._wordBreaker.wordEnd(); |
|||
if (style != null || current == end || this._charWidths[current] > 0) { |
|||
this._addWordBreak(current, this._width, postBreak, this._spaceCount, postSpaceCount, 0); |
|||
offsetX = this._characterPositions[charIndex].x + this._characterWidth[charIndex]; |
|||
this._spaceCount = 0; |
|||
lastBreak = current; |
|||
lastBreakWidth = this._width; |
|||
current = this._wordBreaker.next(); |
|||
this.makeLine(blockEnd, blockEnd); |
|||
return width; |
|||
} |
|||
|
|||
public void finish() { |
|||
this._wordBreaker.finish(); |
|||
this._width = 0; |
|||
this._candidates.Clear(); |
|||
this._widths.Clear(); |
|||
this._breaks.Clear(); |
|||
this._textBuf = null; |
|||
public List<float> getWidths() { |
|||
return this._widths; |
|||
} |
|||
void makeLine(int end, int last) { |
|||
Debug.Assert(this._lineStart < end); |
|||
Debug.Assert(end <= last); |
|||
this._lines.Add(new LineInfo() { |
|||
start = this._lineStart, |
|||
width = this._characterPositions[end - 1].x + this._characterWidth[end - 1], |
|||
}); |
|||
this._lineStart = end; |
|||
public void setTabStops(TabStops tabStops) { |
|||
this._tabStops = tabStops; |
|||
} |
|||
if (end >= this._characterPositions.Length) { |
|||
return; |
|||
void _addWordBreak(int offset, double preBreak, double postBreak, int preSpaceCount, int postSpaceCount, |
|||
float penalty) { |
|||
Candidate cand = new Candidate(); |
|||
double width = this._candidates[this._candidates.Count - 1].preBreak; |
|||
if (postBreak - width > this._lineWidth) { |
|||
int i = this._candidates[this._candidates.Count - 1].offset; |
|||
width += this._charWidths[i++]; |
|||
for (; i < offset; i++) { |
|||
float w = this._charWidths[i]; |
|||
if (w > 0) { |
|||
cand.offset = i; |
|||
cand.preBreak = width; |
|||
cand.postBreak = width; |
|||
cand.preSpaceCount = postSpaceCount; |
|||
cand.preSpaceCount = postSpaceCount; |
|||
cand.penalty = ScoreDesperate; |
|||
this._addCandidate(cand); |
|||
width += w; |
|||
} |
|||
} |
|||
var offset = new Vector2d(-this._characterPositions[end].x, 0); |
|||
this._characterPositions[end].x = 0; |
|||
if (end < last) { |
|||
Paragraph.offsetCharacters(offset, this._characterPositions, end + 1, last + 1); |
|||
cand.offset = offset; |
|||
cand.preBreak = preBreak; |
|||
cand.postBreak = postBreak; |
|||
cand.penalty = penalty; |
|||
cand.preSpaceCount = preSpaceCount; |
|||
cand.preSpaceCount = postSpaceCount; |
|||
this._addCandidate(cand); |
|||
} |
|||
|
|||
|
|||
void _addCandidate(Candidate cand) { |
|||
int candIndex = this._candidates.Count; |
|||
this._candidates.Add(cand); |
|||
if (cand.postBreak - this._preBreak > this._lineWidth) { |
|||
this._pushGreedyBreak(); |
|||
} |
|||
|
|||
if (cand.penalty <= this._bestScore) { |
|||
this._bestBreak = candIndex; |
|||
this._bestScore = cand.penalty; |
|||
} |
|||
|
|||
void _pushGreedyBreak() { |
|||
var bestCandidate = this._candidates[this._bestBreak]; |
|||
this._pushBreak(bestCandidate.offset, (float) (bestCandidate.postBreak - this._preBreak)); |
|||
this._bestScore = ScoreInfty; |
|||
this._lastBreak = this._bestBreak; |
|||
this._preBreak = bestCandidate.preBreak; |
|||
} |
|||
|
|||
void _pushBreak(int offset, float width) { |
|||
this._breaks.Add(offset); |
|||
this._widths.Add(width); |
|||
} |
|||
} |
|||
} |
|
|||
using Unity.UIWidgets.animation; |
|||
using Unity.UIWidgets.async; |
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.ui; |
|||
using Unity.UIWidgets.widgets; |
|||
|
|||
namespace Unity.UIWidgets.material { |
|||
public class Scrollbar : StatefulWidget { |
|||
public Scrollbar( |
|||
Key key = null, |
|||
Widget child = null) : base(key: key) { |
|||
this.child = child; |
|||
} |
|||
|
|||
public readonly Widget child; |
|||
|
|||
public override State createState() { |
|||
return new _ScrollbarState(); |
|||
} |
|||
} |
|||
|
|||
public class _ScrollbarState : TickerProviderStateMixin<Scrollbar> { |
|||
public ScrollbarPainter _materialPainter; |
|||
public TextDirection _textDirection; |
|||
public Color _themeColor; |
|||
|
|||
public AnimationController _fadeoutAnimationController; |
|||
public Animation<double> _FadeoutOpacityAnimation; |
|||
public Timer _fadeoutTimer; |
|||
|
|||
public override void initState() { |
|||
base.initState(); |
|||
this._fadeoutAnimationController = new AnimationController( |
|||
vsync: this, |
|||
duration: ScrollbarUtils._kScrollbarFadeDuration |
|||
); |
|||
this._FadeoutOpacityAnimation = new CurvedAnimation( |
|||
parent: this._fadeoutAnimationController, |
|||
curve: Curves.fastOutSlowIn |
|||
); |
|||
} |
|||
|
|||
public override void didChangeDependencies() { |
|||
base.didChangeDependencies(); |
|||
|
|||
ThemeData theme = Theme.of(this.context); |
|||
|
|||
this._themeColor = theme.highlightColor.withOpacity(1.0); |
|||
this._textDirection = Directionality.of(this.context); |
|||
this._materialPainter = this._BuildMaterialScrollbarPainter(); |
|||
} |
|||
|
|||
public ScrollbarPainter _BuildMaterialScrollbarPainter() { |
|||
return new ScrollbarPainter( |
|||
color: this._themeColor, |
|||
textDirection: this._textDirection, |
|||
thickness: ScrollbarUtils._kScrollbarThickness, |
|||
fadeoutOpacityAnimation: this._FadeoutOpacityAnimation |
|||
); |
|||
} |
|||
|
|||
bool _handleScrollNotification(ScrollNotification notification) { |
|||
if (notification is ScrollUpdateNotification || notification is OverscrollNotification) { |
|||
if (this._fadeoutAnimationController.status != AnimationStatus.forward) { |
|||
this._fadeoutAnimationController.forward(); |
|||
} |
|||
|
|||
this._materialPainter.update(notification.metrics, notification.metrics.axisDirection); |
|||
this._fadeoutTimer?.cancel(); |
|||
|
|||
this._fadeoutTimer = Window.instance.run(ScrollbarUtils._kScrollbarTimeToFade, () => { |
|||
this._fadeoutAnimationController.reverse(); |
|||
this._fadeoutTimer = null; |
|||
}); |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
public override void dispose() { |
|||
this._fadeoutAnimationController.dispose(); |
|||
this._fadeoutTimer?.cancel(); |
|||
this._materialPainter?.dispose(); |
|||
|
|||
base.dispose(); |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
return new NotificationListener<ScrollNotification>( |
|||
onNotification: this._handleScrollNotification, |
|||
child: new RepaintBoundary( |
|||
child: new CustomPaint( |
|||
foregroundPainter: this._materialPainter, |
|||
child: new RepaintBoundary( |
|||
child: this.widget.child |
|||
) |
|||
) |
|||
) |
|||
); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: d8341e3dbe41a48c1b05857eb0d0f7d9 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.gestures; |
|||
using Unity.UIWidgets.rendering; |
|||
using Unity.UIWidgets.ui; |
|||
|
|||
namespace Unity.UIWidgets.widgets { |
|||
public interface CustomPainter : Listenable { |
|||
void paint(Canvas canvas, Size size); |
|||
|
|||
bool shouldRepaint(CustomPainter oldDelegate); |
|||
|
|||
bool hitTest(Offset position); |
|||
} |
|||
|
|||
public abstract class AbstractCustomPainter : CustomPainter { |
|||
public AbstractCustomPainter(Listenable repaint = null) { |
|||
this._repaint = repaint; |
|||
} |
|||
|
|||
readonly Listenable _repaint; |
|||
|
|||
public void addListener(VoidCallback listener) { |
|||
this._repaint?.addListener(listener); |
|||
} |
|||
|
|||
public void removeListener(VoidCallback listener) { |
|||
this._repaint?.removeListener(listener); |
|||
} |
|||
|
|||
public abstract void paint(Canvas canvas, Size size); |
|||
|
|||
public abstract bool shouldRepaint(CustomPainter oldDelegate); |
|||
|
|||
public virtual bool hitTest(Offset position) { |
|||
return true; |
|||
} |
|||
|
|||
public override string ToString() { |
|||
return $"{Diagnostics.describeIdentity(this)}({this._repaint?.ToString() ?? ""})"; |
|||
} |
|||
} |
|||
|
|||
public class RenderCustomPaint : RenderProxyBox { |
|||
public RenderCustomPaint( |
|||
CustomPainter painter = null, |
|||
CustomPainter foregroundPainter = null, |
|||
Size preferredSize = null, |
|||
bool isComplex = false, |
|||
bool willChange = false, |
|||
RenderBox child = null |
|||
) : base(child) { |
|||
preferredSize = preferredSize ?? Size.zero; |
|||
this.preferredSize = preferredSize; |
|||
this._painter = painter; |
|||
this._foregroundPainter = foregroundPainter; |
|||
this.isComplex = isComplex; |
|||
this.willChange = willChange; |
|||
} |
|||
|
|||
CustomPainter _painter; |
|||
|
|||
public CustomPainter painter { |
|||
get { return this._painter; } |
|||
set { |
|||
if (this._painter == value) { |
|||
return; |
|||
} |
|||
|
|||
CustomPainter oldPainter = this._painter; |
|||
this._painter = value; |
|||
this._didUpdatePainter(this._painter, oldPainter); |
|||
} |
|||
} |
|||
|
|||
CustomPainter _foregroundPainter; |
|||
|
|||
public CustomPainter foregroundPainter { |
|||
get { return this._foregroundPainter; } |
|||
set { |
|||
if (this._foregroundPainter == value) { |
|||
return; |
|||
} |
|||
|
|||
CustomPainter oldPainter = this._foregroundPainter; |
|||
this._foregroundPainter = value; |
|||
this._didUpdatePainter(this._foregroundPainter, oldPainter); |
|||
} |
|||
} |
|||
|
|||
void _didUpdatePainter(CustomPainter newPainter, CustomPainter oldPainter) { |
|||
if (newPainter == null) { |
|||
D.assert(oldPainter != null); |
|||
this.markNeedsPaint(); |
|||
} |
|||
else if (oldPainter == null || |
|||
newPainter.GetType() != oldPainter.GetType() || |
|||
newPainter.shouldRepaint(oldPainter)) { |
|||
this.markNeedsPaint(); |
|||
} |
|||
|
|||
if (this.attached) { |
|||
oldPainter?.removeListener(this.markNeedsPaint); |
|||
newPainter?.addListener(this.markNeedsPaint); |
|||
} |
|||
} |
|||
|
|||
Size _preferredSize; |
|||
|
|||
public Size preferredSize { |
|||
get { return this._preferredSize; } |
|||
set { |
|||
D.assert(value != null); |
|||
if (this.preferredSize == value) { |
|||
return; |
|||
} |
|||
|
|||
this._preferredSize = value; |
|||
this.markNeedsLayout(); |
|||
} |
|||
} |
|||
|
|||
public bool isComplex; |
|||
|
|||
public bool willChange; |
|||
|
|||
public override void attach(object owner) { |
|||
base.attach(owner); |
|||
this._painter?.addListener(this.markNeedsPaint); |
|||
this._foregroundPainter?.addListener(this.markNeedsPaint); |
|||
} |
|||
|
|||
public override void detach() { |
|||
this._painter?.removeListener(this.markNeedsPaint); |
|||
this._foregroundPainter?.removeListener(this.markNeedsPaint); |
|||
base.detach(); |
|||
} |
|||
|
|||
protected override bool hitTestChildren(HitTestResult result, Offset position) { |
|||
if (this._foregroundPainter != null && (this._foregroundPainter.hitTest(position))) { |
|||
return true; |
|||
} |
|||
|
|||
return base.hitTestChildren(result, position: position); |
|||
} |
|||
|
|||
|
|||
protected override bool hitTestSelf(Offset position) { |
|||
return this._painter != null && this._painter.hitTest(position); |
|||
} |
|||
|
|||
protected override void performResize() { |
|||
this.size = this.constraints.constrain(this.preferredSize); |
|||
} |
|||
|
|||
void _paintWithPainter(Canvas canvas, Offset offset, CustomPainter painter) { |
|||
int debugPreviousCanvasSaveCount = 0; |
|||
canvas.save(); |
|||
D.assert(() => { |
|||
debugPreviousCanvasSaveCount = canvas.getSaveCount(); |
|||
return true; |
|||
}); |
|||
if (offset != Offset.zero) { |
|||
canvas.translate(offset.dx, offset.dy); |
|||
} |
|||
|
|||
painter.paint(canvas, this.size); |
|||
D.assert(() => { |
|||
int debugNewCanvasSaveCount = canvas.getSaveCount(); |
|||
if (debugNewCanvasSaveCount > debugPreviousCanvasSaveCount) { |
|||
throw new UIWidgetsError( |
|||
$"{debugNewCanvasSaveCount - debugPreviousCanvasSaveCount} more " + |
|||
$"time{((debugNewCanvasSaveCount - debugPreviousCanvasSaveCount == 1) ? "" : "s")} " + |
|||
"than it called canvas.restore().\n" + |
|||
"This leaves the canvas in an inconsistent state and will probably result in a broken display.\n" + |
|||
"You must pair each call to save()/saveLayer() with a later matching call to restore()." |
|||
); |
|||
} |
|||
|
|||
if (debugNewCanvasSaveCount < debugPreviousCanvasSaveCount) { |
|||
throw new UIWidgetsError( |
|||
$"The {painter} custom painter called canvas.restore() " + |
|||
$"{debugPreviousCanvasSaveCount - debugNewCanvasSaveCount} more " + |
|||
$"time{(debugPreviousCanvasSaveCount - debugNewCanvasSaveCount == 1 ? "" : "s")} " + |
|||
"than it called canvas.save() or canvas.saveLayer().\n" + |
|||
"This leaves the canvas in an inconsistent state and will result in a broken display.\n" + |
|||
"You should only call restore() if you first called save() or saveLayer()." |
|||
); |
|||
} |
|||
|
|||
return debugNewCanvasSaveCount == debugPreviousCanvasSaveCount; |
|||
}); |
|||
canvas.restore(); |
|||
} |
|||
|
|||
public override void paint(PaintingContext context, Offset offset) { |
|||
if (this._painter != null) { |
|||
this._paintWithPainter(context.canvas, offset, this._painter); |
|||
this._setRasterCacheHints(context); |
|||
} |
|||
|
|||
base.paint(context, offset); |
|||
if (this._foregroundPainter != null) { |
|||
this._paintWithPainter(context.canvas, offset, this._foregroundPainter); |
|||
this._setRasterCacheHints(context); |
|||
} |
|||
} |
|||
|
|||
void _setRasterCacheHints(PaintingContext context) { |
|||
if (this.isComplex) { |
|||
context.setIsComplexHint(); |
|||
} |
|||
|
|||
if (this.willChange) { |
|||
context.setWillChangeHint(); |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: c6448cb8d72ed487788c11da26b61f54 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System.Collections.Generic; |
|||
using UnityEngine; |
|||
|
|||
namespace Unity.UIWidgets.ui { |
|||
public class Layout { |
|||
int _start; |
|||
int _count; |
|||
List<float> _advances = new List<float>(); |
|||
List<float> _positions = new List<float>(); |
|||
float _advance; |
|||
Rect _bounds; |
|||
string _text; |
|||
TabStops _tabStops; |
|||
|
|||
|
|||
public static float measureText(double offset, string buf, int start, int count, TextStyle style, |
|||
List<float> advances, int advanceOffset, TabStops tabStops) { |
|||
Layout layout = new Layout(); |
|||
layout.setTabStops(tabStops); |
|||
layout.doLayout(offset, buf, start, count, style); |
|||
if (advances != null) { |
|||
var layoutAdv = layout.getAdvances(); |
|||
for (int i = 0; i < count; i++) { |
|||
advances[i + advanceOffset] = layoutAdv[i]; |
|||
} |
|||
} |
|||
|
|||
return layout.getAdvance(); |
|||
} |
|||
|
|||
public void doLayout(double offset, string text, int start, int count, TextStyle style) { |
|||
this._text = text; |
|||
this._advances.Clear(); |
|||
this._positions.Clear(); |
|||
this._count = count; |
|||
var font = FontManager.instance.getOrCreate(style.fontFamily).font; |
|||
font.RequestCharactersInTexture(this._text.Substring(start, count), |
|||
style.UnityFontSize, |
|||
style.UnityFontStyle); |
|||
|
|||
this._advance = 0; |
|||
this._bounds = null; |
|||
for (int i = 0; i < count; i++) { |
|||
int charIndex = start + i; |
|||
var ch = text[charIndex]; |
|||
CharacterInfo characterInfo; |
|||
font.GetCharacterInfo(ch, out characterInfo, style.UnityFontSize, style.UnityFontStyle); |
|||
|
|||
var rect = Rect.fromLTRB(characterInfo.minX, -characterInfo.maxY, characterInfo.maxX, |
|||
-characterInfo.minY); |
|||
rect = rect.translate(this._advance, 0); |
|||
if (this._bounds == null) { |
|||
this._bounds = rect; |
|||
} |
|||
else { |
|||
this._bounds = this._bounds.expandToInclude(rect); |
|||
} |
|||
|
|||
this._positions.Add(this._advance); |
|||
float advance = characterInfo.advance; |
|||
if (ch == '\t') { |
|||
advance = this._tabStops.nextTab((float) (this._advance + offset)) - this._advance; |
|||
} |
|||
|
|||
this._advances.Add(advance); |
|||
this._advance += advance; |
|||
} |
|||
} |
|||
|
|||
public void setTabStops(TabStops tabStops) { |
|||
this._tabStops = tabStops; |
|||
} |
|||
|
|||
public int nGlyphs() { |
|||
return this._count; |
|||
} |
|||
|
|||
public List<float> getAdvances() { |
|||
return this._advances; |
|||
} |
|||
|
|||
public float getAdvance() { |
|||
return this._advance; |
|||
} |
|||
|
|||
public float getX(int index) { |
|||
return this._positions[index]; |
|||
} |
|||
|
|||
public float getY(int index) { |
|||
return 0; |
|||
} |
|||
|
|||
public float getCharAdvance(int index) { |
|||
return this._advances[index]; |
|||
} |
|||
|
|||
public Rect getBounds() { |
|||
return this._bounds; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 291468e4e150b495fa305f2d62b134e3 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
namespace Unity.UIWidgets.ui { |
|||
public static class LayoutUtils { |
|||
public const char CHAR_NBSP = '\u00A0'; |
|||
|
|||
public static bool isWordSpace(char ch) { |
|||
return ch == ' ' || ch == CHAR_NBSP; |
|||
} |
|||
|
|||
public static bool isLineEndSpace(char c) { |
|||
return c == '\n' || c == ' ' || c == 0x1680 || (0x2000 <= c && c <= 0x200A && c != 0x2007) || |
|||
c == 0x205F || c == 0x3000; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 1b1768a705ffe4cb7ab2638ac53c657e |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
namespace Unity.UIWidgets.ui { |
|||
public class WordBreaker { |
|||
public const uint U16_SURROGATE_OFFSET = ((0xd800 << 10) + 0xdc00 - 0x10000); |
|||
string _text; |
|||
int _offset; |
|||
int _size; |
|||
int _current; |
|||
int _last; |
|||
int _scanOffset; |
|||
bool _inEmailOrUrl; |
|||
|
|||
|
|||
public int next() { |
|||
this._last = this._current; |
|||
this._detectEmailOrUrl(); |
|||
if (this._inEmailOrUrl) { |
|||
this._current = this._findNextBreakInEmailOrUrl(); |
|||
} |
|||
else { |
|||
this._current = this._findNextBreakNormal(); |
|||
} |
|||
|
|||
return this._current; |
|||
} |
|||
|
|||
public void setText(string data, int offset, int size) { |
|||
this._text = data; |
|||
this._offset = offset; |
|||
this._size = size; |
|||
this._last = 0; |
|||
this._current = 0; |
|||
this._scanOffset = 0; |
|||
this._inEmailOrUrl = false; |
|||
} |
|||
|
|||
public int current() { |
|||
return this._current; |
|||
} |
|||
|
|||
public int wordStart() { |
|||
if (this._inEmailOrUrl) { |
|||
return this._last; |
|||
} |
|||
|
|||
var result = this._last; |
|||
while (result < this._current) { |
|||
int ix = result; |
|||
uint c = nextCode(this._text, ref ix, this._current); |
|||
if (!LayoutUtils.isLineEndSpace((char) c)) { |
|||
break; |
|||
} |
|||
|
|||
result = ix; |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
public int wordEnd() { |
|||
if (this._inEmailOrUrl) { |
|||
return this._last; |
|||
} |
|||
|
|||
int result = this._current; |
|||
while (result > this._last) { |
|||
int ix = result; |
|||
uint ch = preCode(this._text, ref ix, this._last); |
|||
if (!LayoutUtils.isLineEndSpace((char) ch)) { |
|||
break; |
|||
} |
|||
|
|||
result = ix; |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
public int breakBadness() { |
|||
return (this._inEmailOrUrl && this._current < this._scanOffset) ? 1 : 0; |
|||
} |
|||
|
|||
public void finish() { |
|||
this._text = null; |
|||
} |
|||
|
|||
int _findNextBreakInEmailOrUrl() { |
|||
return 0; |
|||
} |
|||
|
|||
int _findNextBreakNormal() { |
|||
if (this._current == this._size) { |
|||
return -1; |
|||
} |
|||
|
|||
this._current++; |
|||
for (; this._current < this._size; ++this._current) { |
|||
char c = this._text[this._current + this._offset]; |
|||
if (LayoutUtils.isWordSpace(c) || c == '\t') { |
|||
return this._current; |
|||
} |
|||
} |
|||
|
|||
return this._current; |
|||
} |
|||
|
|||
void _detectEmailOrUrl() { |
|||
} |
|||
|
|||
static uint nextCode(string text, ref int index, int end) { |
|||
uint ch = text[index++]; |
|||
if (isLeadSurrogate(ch)) { |
|||
if (index < end && isTrailSurrogate(text[index])) { |
|||
char ch2 = text[index]; |
|||
index++; |
|||
ch = getSupplementary(ch, ch2); |
|||
} |
|||
} |
|||
|
|||
return ch; |
|||
} |
|||
|
|||
static uint preCode(string text, ref int index, int start) { |
|||
uint ch = text[--index]; |
|||
if (isTrailSurrogate(ch)) { |
|||
if (index > start && isLeadSurrogate(text[index - 1])) { |
|||
ch = getSupplementary(text[index - 1], ch); |
|||
--index; |
|||
} |
|||
} |
|||
|
|||
return ch; |
|||
} |
|||
|
|||
public static bool isLeadSurrogate(uint c) { |
|||
return ((c) & 0xfffffc00) == 0xd800; |
|||
} |
|||
|
|||
|
|||
public static bool isTrailSurrogate(uint c) { |
|||
return ((c) & 0xfffffc00) == 0xdc00; |
|||
} |
|||
|
|||
public static uint getSupplementary(uint lead, uint trail) { |
|||
return (char) (((uint) (lead) << 10) + (uint) (trail - U16_SURROGATE_OFFSET)); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 30b4907a8b76c4df9a243dcd8d3518fb |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using Unity.UIWidgets.animation; |
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.painting; |
|||
using Unity.UIWidgets.ui; |
|||
|
|||
namespace Unity.UIWidgets.widgets { |
|||
public class ScrollbarPainter : ChangeNotifier, CustomPainter { |
|||
public ScrollbarPainter( |
|||
Color color, |
|||
TextDirection textDirection, |
|||
double thickness, |
|||
Animation<double> fadeoutOpacityAnimation, |
|||
double mainAxisMargin = 0.0, |
|||
double crossAxisMargin = 0.0, |
|||
Radius radius = null, |
|||
double minLength = _kMinThumbExtent, |
|||
double minOverscrollLength = _kMinThumbExtent |
|||
) { |
|||
this.color = color; |
|||
this.textDirection = textDirection; |
|||
this.thickness = thickness; |
|||
this.fadeoutOpacityAnimation = fadeoutOpacityAnimation; |
|||
this.mainAxisMargin = mainAxisMargin; |
|||
this.crossAxisMargin = crossAxisMargin; |
|||
this.radius = radius; |
|||
this.minLength = minLength; |
|||
this.minOverscrollLength = minOverscrollLength; |
|||
fadeoutOpacityAnimation.addListener(this.notifyListeners); |
|||
} |
|||
|
|||
const double _kMinThumbExtent = 18.0; |
|||
|
|||
public Color color; |
|||
public TextDirection? textDirection; |
|||
public double thickness; |
|||
public Animation<double> fadeoutOpacityAnimation; |
|||
public double mainAxisMargin; |
|||
public double crossAxisMargin; |
|||
public Radius radius; |
|||
public double minLength; |
|||
public double minOverscrollLength; |
|||
|
|||
ScrollMetrics _lastMetrics; |
|||
AxisDirection? _lastAxisDirection; |
|||
|
|||
public void update(ScrollMetrics metrics, AxisDirection axisDirection) { |
|||
this._lastMetrics = metrics; |
|||
this._lastAxisDirection = axisDirection; |
|||
this.notifyListeners(); |
|||
} |
|||
|
|||
Paint _paint { |
|||
get { |
|||
var paint = new Paint(); |
|||
paint.color = this.color.withOpacity(this.color.opacity * this.fadeoutOpacityAnimation.value); |
|||
return paint; |
|||
} |
|||
} |
|||
|
|||
double _getThumbX(Size size) { |
|||
D.assert(this.textDirection != null); |
|||
switch (this.textDirection) { |
|||
case TextDirection.rtl: |
|||
return this.crossAxisMargin; |
|||
case TextDirection.ltr: |
|||
return size.width - this.thickness - this.crossAxisMargin; |
|||
} |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
void _paintVerticalThumb(Canvas canvas, Size size, double thumbOffset, double thumbExtent) { |
|||
Offset thumbOrigin = new Offset(this._getThumbX(size), thumbOffset); |
|||
Size thumbSize = new Size(this.thickness, thumbExtent); |
|||
Rect thumbRect = thumbOrigin & thumbSize; |
|||
if (this.radius == null) { |
|||
canvas.drawRect(thumbRect, this._paint); |
|||
} |
|||
else { |
|||
canvas.drawRRect(RRect.fromRectAndRadius(thumbRect, this.radius), this._paint); |
|||
} |
|||
} |
|||
|
|||
void _paintHorizontalThumb(Canvas canvas, Size size, double thumbOffset, double thumbExtent) { |
|||
Offset thumbOrigin = new Offset(thumbOffset, size.height - this.thickness); |
|||
Size thumbSize = new Size(thumbExtent, this.thickness); |
|||
Rect thumbRect = thumbOrigin & thumbSize; |
|||
if (this.radius == null) { |
|||
canvas.drawRect(thumbRect, this._paint); |
|||
} |
|||
else { |
|||
canvas.drawRRect(RRect.fromRectAndRadius(thumbRect, this.radius), this._paint); |
|||
} |
|||
} |
|||
|
|||
public delegate void painterDelegate(Canvas canvas, Size size, double thumbOffset, double thumbExtent); |
|||
|
|||
void _paintThumb( |
|||
double before, |
|||
double inside, |
|||
double after, |
|||
double viewport, |
|||
Canvas canvas, |
|||
Size size, |
|||
painterDelegate painter |
|||
) { |
|||
double thumbExtent = Math.Min(viewport, this.minOverscrollLength); |
|||
|
|||
if (before + inside + after > 0.0) { |
|||
double fractionVisible = inside / (before + inside + after); |
|||
thumbExtent = Math.Max( |
|||
thumbExtent, |
|||
viewport * fractionVisible - 2 * this.mainAxisMargin |
|||
); |
|||
|
|||
if (before != 0.0 && after != 0.0) { |
|||
thumbExtent = Math.Max( |
|||
this.minLength, |
|||
thumbExtent |
|||
); |
|||
} |
|||
else { |
|||
thumbExtent = Math.Max( |
|||
thumbExtent, |
|||
this.minLength * (((inside / viewport) - 0.8) / 0.2) |
|||
); |
|||
} |
|||
} |
|||
|
|||
double fractionPast = before / (before + after); |
|||
double thumbOffset = (before + after > 0.0) |
|||
? fractionPast * (viewport - thumbExtent - 2 * this.mainAxisMargin) + this.mainAxisMargin |
|||
: this.mainAxisMargin; |
|||
|
|||
painter(canvas, size, thumbOffset, thumbExtent); |
|||
} |
|||
|
|||
public override void dispose() { |
|||
this.fadeoutOpacityAnimation.removeListener(this.notifyListeners); |
|||
base.dispose(); |
|||
} |
|||
|
|||
|
|||
public void paint(Canvas canvas, Size size) { |
|||
if (this._lastAxisDirection == null |
|||
|| this._lastMetrics == null |
|||
|| this.fadeoutOpacityAnimation.value == 0.0) { |
|||
return; |
|||
} |
|||
|
|||
switch (this._lastAxisDirection) { |
|||
case AxisDirection.down: |
|||
this._paintThumb(this._lastMetrics.extentBefore(), this._lastMetrics.extentInside(), |
|||
this._lastMetrics.extentAfter(), size.height, canvas, size, this._paintVerticalThumb); |
|||
break; |
|||
case AxisDirection.up: |
|||
this._paintThumb(this._lastMetrics.extentAfter(), this._lastMetrics.extentInside(), |
|||
this._lastMetrics.extentBefore(), size.height, canvas, size, this._paintVerticalThumb); |
|||
break; |
|||
case AxisDirection.right: |
|||
this._paintThumb(this._lastMetrics.extentBefore(), this._lastMetrics.extentInside(), |
|||
this._lastMetrics.extentAfter(), size.width, canvas, size, this._paintHorizontalThumb); |
|||
break; |
|||
case AxisDirection.left: |
|||
this._paintThumb(this._lastMetrics.extentAfter(), this._lastMetrics.extentInside(), |
|||
this._lastMetrics.extentBefore(), size.width, canvas, size, this._paintHorizontalThumb); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
public bool hitTest(Offset position) { |
|||
return false; |
|||
} |
|||
|
|||
public bool shouldRepaint(CustomPainter oldRaw) { |
|||
if (oldRaw is ScrollbarPainter old) { |
|||
return this.color != old.color |
|||
|| this.textDirection != old.textDirection |
|||
|| this.thickness != old.thickness |
|||
|| this.fadeoutOpacityAnimation != old.fadeoutOpacityAnimation |
|||
|| this.mainAxisMargin != old.mainAxisMargin |
|||
|| this.crossAxisMargin != old.crossAxisMargin |
|||
|| this.radius != old.radius |
|||
|| this.minLength != old.minLength; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|
|||
%YAML 1.1 |
|||
%TAG !u! tag:unity3d.com,2011: |
|||
--- !u!29 &1 |
|||
OcclusionCullingSettings: |
|||
m_ObjectHideFlags: 0 |
|||
serializedVersion: 2 |
|||
m_OcclusionBakeSettings: |
|||
smallestOccluder: 5 |
|||
smallestHole: 0.25 |
|||
backfaceThreshold: 100 |
|||
m_SceneGUID: 00000000000000000000000000000000 |
|||
m_OcclusionCullingData: {fileID: 0} |
|||
--- !u!104 &2 |
|||
RenderSettings: |
|||
m_ObjectHideFlags: 0 |
|||
serializedVersion: 9 |
|||
m_Fog: 0 |
|||
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} |
|||
m_FogMode: 3 |
|||
m_FogDensity: 0.01 |
|||
m_LinearFogStart: 0 |
|||
m_LinearFogEnd: 300 |
|||
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} |
|||
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} |
|||
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} |
|||
m_AmbientIntensity: 1 |
|||
m_AmbientMode: 0 |
|||
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} |
|||
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} |
|||
m_HaloStrength: 0.5 |
|||
m_FlareStrength: 1 |
|||
m_FlareFadeSpeed: 3 |
|||
m_HaloTexture: {fileID: 0} |
|||
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} |
|||
m_DefaultReflectionMode: 0 |
|||
m_DefaultReflectionResolution: 128 |
|||
m_ReflectionBounces: 1 |
|||
m_ReflectionIntensity: 1 |
|||
m_CustomReflection: {fileID: 0} |
|||
m_Sun: {fileID: 0} |
|||
m_IndirectSpecularColor: {r: 0.44657898, g: 0.49641275, b: 0.5748174, a: 1} |
|||
m_UseRadianceAmbientProbe: 0 |
|||
--- !u!157 &3 |
|||
LightmapSettings: |
|||
m_ObjectHideFlags: 0 |
|||
serializedVersion: 11 |
|||
m_GIWorkflowMode: 0 |
|||
m_GISettings: |
|||
serializedVersion: 2 |
|||
m_BounceScale: 1 |
|||
m_IndirectOutputScale: 1 |
|||
m_AlbedoBoost: 1 |
|||
m_EnvironmentLightingMode: 0 |
|||
m_EnableBakedLightmaps: 1 |
|||
m_EnableRealtimeLightmaps: 1 |
|||
m_LightmapEditorSettings: |
|||
serializedVersion: 10 |
|||
m_Resolution: 2 |
|||
m_BakeResolution: 40 |
|||
m_AtlasSize: 1024 |
|||
m_AO: 0 |
|||
m_AOMaxDistance: 1 |
|||
m_CompAOExponent: 1 |
|||
m_CompAOExponentDirect: 0 |
|||
m_Padding: 2 |
|||
m_LightmapParameters: {fileID: 0} |
|||
m_LightmapsBakeMode: 1 |
|||
m_TextureCompression: 1 |
|||
m_FinalGather: 0 |
|||
m_FinalGatherFiltering: 1 |
|||
m_FinalGatherRayCount: 256 |
|||
m_ReflectionCompression: 2 |
|||
m_MixedBakeMode: 2 |
|||
m_BakeBackend: 1 |
|||
m_PVRSampling: 1 |
|||
m_PVRDirectSampleCount: 32 |
|||
m_PVRSampleCount: 500 |
|||
m_PVRBounces: 2 |
|||
m_PVRFilterTypeDirect: 0 |
|||
m_PVRFilterTypeIndirect: 0 |
|||
m_PVRFilterTypeAO: 0 |
|||
m_PVRFilteringMode: 1 |
|||
m_PVRCulling: 1 |
|||
m_PVRFilteringGaussRadiusDirect: 1 |
|||
m_PVRFilteringGaussRadiusIndirect: 5 |
|||
m_PVRFilteringGaussRadiusAO: 2 |
|||
m_PVRFilteringAtrousPositionSigmaDirect: 0.5 |
|||
m_PVRFilteringAtrousPositionSigmaIndirect: 2 |
|||
m_PVRFilteringAtrousPositionSigmaAO: 1 |
|||
m_ShowResolutionOverlay: 1 |
|||
m_LightingDataAsset: {fileID: 0} |
|||
m_UseShadowmask: 1 |
|||
--- !u!196 &4 |
|||
NavMeshSettings: |
|||
serializedVersion: 2 |
|||
m_ObjectHideFlags: 0 |
|||
m_BuildSettings: |
|||
serializedVersion: 2 |
|||
agentTypeID: 0 |
|||
agentRadius: 0.5 |
|||
agentHeight: 2 |
|||
agentSlope: 45 |
|||
agentClimb: 0.4 |
|||
ledgeDropHeight: 0 |
|||
maxJumpAcrossDistance: 0 |
|||
minRegionArea: 2 |
|||
manualCellSize: 0 |
|||
cellSize: 0.16666667 |
|||
manualTileSize: 0 |
|||
tileSize: 256 |
|||
accuratePlacement: 0 |
|||
debug: |
|||
m_Flags: 0 |
|||
m_NavMeshData: {fileID: 0} |
|||
--- !u!1 &288417894 |
|||
GameObject: |
|||
m_ObjectHideFlags: 0 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
serializedVersion: 6 |
|||
m_Component: |
|||
- component: {fileID: 288417898} |
|||
- component: {fileID: 288417897} |
|||
- component: {fileID: 288417896} |
|||
- component: {fileID: 288417895} |
|||
m_Layer: 5 |
|||
m_Name: Canvas |
|||
m_TagString: Untagged |
|||
m_Icon: {fileID: 0} |
|||
m_NavMeshLayer: 0 |
|||
m_StaticEditorFlags: 0 |
|||
m_IsActive: 1 |
|||
--- !u!114 &288417895 |
|||
MonoBehaviour: |
|||
m_ObjectHideFlags: 0 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_GameObject: {fileID: 288417894} |
|||
m_Enabled: 1 |
|||
m_EditorHideFlags: 0 |
|||
m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3} |
|||
m_Name: |
|||
m_EditorClassIdentifier: |
|||
m_IgnoreReversedGraphics: 1 |
|||
m_BlockingObjects: 0 |
|||
m_BlockingMask: |
|||
serializedVersion: 2 |
|||
m_Bits: 4294967295 |
|||
--- !u!114 &288417896 |
|||
MonoBehaviour: |
|||
m_ObjectHideFlags: 0 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_GameObject: {fileID: 288417894} |
|||
m_Enabled: 1 |
|||
m_EditorHideFlags: 0 |
|||
m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3} |
|||
m_Name: |
|||
m_EditorClassIdentifier: |
|||
m_UiScaleMode: 0 |
|||
m_ReferencePixelsPerUnit: 100 |
|||
m_ScaleFactor: 1 |
|||
m_ReferenceResolution: {x: 800, y: 600} |
|||
m_ScreenMatchMode: 0 |
|||
m_MatchWidthOrHeight: 0 |
|||
m_PhysicalUnit: 3 |
|||
m_FallbackScreenDPI: 96 |
|||
m_DefaultSpriteDPI: 96 |
|||
m_DynamicPixelsPerUnit: 1 |
|||
--- !u!223 &288417897 |
|||
Canvas: |
|||
m_ObjectHideFlags: 0 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_GameObject: {fileID: 288417894} |
|||
m_Enabled: 1 |
|||
serializedVersion: 3 |
|||
m_RenderMode: 0 |
|||
m_Camera: {fileID: 0} |
|||
m_PlaneDistance: 100 |
|||
m_PixelPerfect: 0 |
|||
m_ReceivesEvents: 1 |
|||
m_OverrideSorting: 0 |
|||
m_OverridePixelPerfect: 0 |
|||
m_SortingBucketNormalizedSize: 0 |
|||
m_AdditionalShaderChannelsFlag: 0 |
|||
m_SortingLayerID: 0 |
|||
m_SortingOrder: 0 |
|||
m_TargetDisplay: 0 |
|||
--- !u!224 &288417898 |
|||
RectTransform: |
|||
m_ObjectHideFlags: 0 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_GameObject: {fileID: 288417894} |
|||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} |
|||
m_LocalPosition: {x: 0, y: 0, z: 0} |
|||
m_LocalScale: {x: 0, y: 0, z: 0} |
|||
m_Children: |
|||
- {fileID: 1525809614} |
|||
m_Father: {fileID: 0} |
|||
m_RootOrder: 2 |
|||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} |
|||
m_AnchorMin: {x: 0, y: 0} |
|||
m_AnchorMax: {x: 0, y: 0} |
|||
m_AnchoredPosition: {x: 0, y: 0} |
|||
m_SizeDelta: {x: 0, y: 0} |
|||
m_Pivot: {x: 0, y: 0} |
|||
--- !u!1 &501956623 |
|||
GameObject: |
|||
m_ObjectHideFlags: 0 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
serializedVersion: 6 |
|||
m_Component: |
|||
- component: {fileID: 501956625} |
|||
- component: {fileID: 501956624} |
|||
m_Layer: 0 |
|||
m_Name: Directional Light |
|||
m_TagString: Untagged |
|||
m_Icon: {fileID: 0} |
|||
m_NavMeshLayer: 0 |
|||
m_StaticEditorFlags: 0 |
|||
m_IsActive: 1 |
|||
--- !u!108 &501956624 |
|||
Light: |
|||
m_ObjectHideFlags: 0 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_GameObject: {fileID: 501956623} |
|||
m_Enabled: 1 |
|||
serializedVersion: 8 |
|||
m_Type: 1 |
|||
m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} |
|||
m_Intensity: 1 |
|||
m_Range: 10 |
|||
m_SpotAngle: 30 |
|||
m_CookieSize: 10 |
|||
m_Shadows: |
|||
m_Type: 2 |
|||
m_Resolution: -1 |
|||
m_CustomResolution: -1 |
|||
m_Strength: 1 |
|||
m_Bias: 0.05 |
|||
m_NormalBias: 0.4 |
|||
m_NearPlane: 0.2 |
|||
m_Cookie: {fileID: 0} |
|||
m_DrawHalo: 0 |
|||
m_Flare: {fileID: 0} |
|||
m_RenderMode: 0 |
|||
m_CullingMask: |
|||
serializedVersion: 2 |
|||
m_Bits: 4294967295 |
|||
m_Lightmapping: 4 |
|||
m_LightShadowCasterMode: 0 |
|||
m_AreaSize: {x: 1, y: 1} |
|||
m_BounceIntensity: 1 |
|||
m_ColorTemperature: 6570 |
|||
m_UseColorTemperature: 0 |
|||
m_ShadowRadius: 0 |
|||
m_ShadowAngle: 0 |
|||
--- !u!4 &501956625 |
|||
Transform: |
|||
m_ObjectHideFlags: 0 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_GameObject: {fileID: 501956623} |
|||
m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} |
|||
m_LocalPosition: {x: 0, y: 3, z: 0} |
|||
m_LocalScale: {x: 1, y: 1, z: 1} |
|||
m_Children: [] |
|||
m_Father: {fileID: 0} |
|||
m_RootOrder: 1 |
|||
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} |
|||
--- !u!1 &522912515 |
|||
GameObject: |
|||
m_ObjectHideFlags: 0 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
serializedVersion: 6 |
|||
m_Component: |
|||
- component: {fileID: 522912518} |
|||
- component: {fileID: 522912517} |
|||
- component: {fileID: 522912516} |
|||
m_Layer: 0 |
|||
m_Name: EventSystem |
|||
m_TagString: Untagged |
|||
m_Icon: {fileID: 0} |
|||
m_NavMeshLayer: 0 |
|||
m_StaticEditorFlags: 0 |
|||
m_IsActive: 1 |
|||
--- !u!114 &522912516 |
|||
MonoBehaviour: |
|||
m_ObjectHideFlags: 0 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_GameObject: {fileID: 522912515} |
|||
m_Enabled: 1 |
|||
m_EditorHideFlags: 0 |
|||
m_Script: {fileID: 1077351063, guid: f70555f144d8491a825f0804e09c671c, type: 3} |
|||
m_Name: |
|||
m_EditorClassIdentifier: |
|||
m_HorizontalAxis: Horizontal |
|||
m_VerticalAxis: Vertical |
|||
m_SubmitButton: Submit |
|||
m_CancelButton: Cancel |
|||
m_InputActionsPerSecond: 10 |
|||
m_RepeatDelay: 0.5 |
|||
m_ForceModuleActive: 0 |
|||
--- !u!114 &522912517 |
|||
MonoBehaviour: |
|||
m_ObjectHideFlags: 0 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_GameObject: {fileID: 522912515} |
|||
m_Enabled: 1 |
|||
m_EditorHideFlags: 0 |
|||
m_Script: {fileID: -619905303, guid: f70555f144d8491a825f0804e09c671c, type: 3} |
|||
m_Name: |
|||
m_EditorClassIdentifier: |
|||
m_FirstSelected: {fileID: 0} |
|||
m_sendNavigationEvents: 1 |
|||
m_DragThreshold: 10 |
|||
--- !u!4 &522912518 |
|||
Transform: |
|||
m_ObjectHideFlags: 0 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_GameObject: {fileID: 522912515} |
|||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} |
|||
m_LocalPosition: {x: 0, y: 0, z: 0} |
|||
m_LocalScale: {x: 1, y: 1, z: 1} |
|||
m_Children: [] |
|||
m_Father: {fileID: 0} |
|||
m_RootOrder: 3 |
|||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} |
|||
--- !u!1 &1525809613 |
|||
GameObject: |
|||
m_ObjectHideFlags: 0 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
serializedVersion: 6 |
|||
m_Component: |
|||
- component: {fileID: 1525809614} |
|||
- component: {fileID: 1525809615} |
|||
- component: {fileID: 1525809616} |
|||
m_Layer: 5 |
|||
m_Name: GameObject |
|||
m_TagString: Untagged |
|||
m_Icon: {fileID: 0} |
|||
m_NavMeshLayer: 0 |
|||
m_StaticEditorFlags: 0 |
|||
m_IsActive: 1 |
|||
--- !u!224 &1525809614 |
|||
RectTransform: |
|||
m_ObjectHideFlags: 0 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_GameObject: {fileID: 1525809613} |
|||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} |
|||
m_LocalPosition: {x: 0, y: 0, z: 0} |
|||
m_LocalScale: {x: 1, y: 1, z: 1} |
|||
m_Children: [] |
|||
m_Father: {fileID: 288417898} |
|||
m_RootOrder: 0 |
|||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} |
|||
m_AnchorMin: {x: 0.5, y: 0.5} |
|||
m_AnchorMax: {x: 0.5, y: 0.5} |
|||
m_AnchoredPosition: {x: 0, y: 0} |
|||
m_SizeDelta: {x: 100, y: 100} |
|||
m_Pivot: {x: 0.5, y: 0.5} |
|||
--- !u!222 &1525809615 |
|||
CanvasRenderer: |
|||
m_ObjectHideFlags: 0 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_GameObject: {fileID: 1525809613} |
|||
m_CullTransparentMesh: 0 |
|||
--- !u!114 &1525809616 |
|||
MonoBehaviour: |
|||
m_ObjectHideFlags: 0 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_GameObject: {fileID: 1525809613} |
|||
m_Enabled: 1 |
|||
m_EditorHideFlags: 0 |
|||
m_Script: {fileID: 11500000, guid: c5c73cb2437bb4d369115d787656adf4, type: 3} |
|||
m_Name: |
|||
m_EditorClassIdentifier: |
|||
m_Material: {fileID: 0} |
|||
m_Color: {r: 1, g: 1, b: 1, a: 1} |
|||
m_RaycastTarget: 1 |
|||
m_OnCullStateChanged: |
|||
m_PersistentCalls: |
|||
m_Calls: [] |
|||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, |
|||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null |
|||
m_Texture: {fileID: 0} |
|||
m_UVRect: |
|||
serializedVersion: 2 |
|||
x: 0 |
|||
y: 0 |
|||
width: 1 |
|||
height: 1 |
|||
--- !u!1 &1713793689 |
|||
GameObject: |
|||
m_ObjectHideFlags: 0 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
serializedVersion: 6 |
|||
m_Component: |
|||
- component: {fileID: 1713793692} |
|||
- component: {fileID: 1713793691} |
|||
- component: {fileID: 1713793690} |
|||
m_Layer: 0 |
|||
m_Name: Main Camera |
|||
m_TagString: MainCamera |
|||
m_Icon: {fileID: 0} |
|||
m_NavMeshLayer: 0 |
|||
m_StaticEditorFlags: 0 |
|||
m_IsActive: 1 |
|||
--- !u!81 &1713793690 |
|||
AudioListener: |
|||
m_ObjectHideFlags: 0 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_GameObject: {fileID: 1713793689} |
|||
m_Enabled: 1 |
|||
--- !u!20 &1713793691 |
|||
Camera: |
|||
m_ObjectHideFlags: 0 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_GameObject: {fileID: 1713793689} |
|||
m_Enabled: 1 |
|||
serializedVersion: 2 |
|||
m_ClearFlags: 1 |
|||
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} |
|||
m_projectionMatrixMode: 1 |
|||
m_SensorSize: {x: 36, y: 24} |
|||
m_LensShift: {x: 0, y: 0} |
|||
m_GateFitMode: 2 |
|||
m_FocalLength: 50 |
|||
m_NormalizedViewPortRect: |
|||
serializedVersion: 2 |
|||
x: 0 |
|||
y: 0 |
|||
width: 1 |
|||
height: 1 |
|||
near clip plane: 0.3 |
|||
far clip plane: 1000 |
|||
field of view: 60 |
|||
orthographic: 0 |
|||
orthographic size: 5 |
|||
m_Depth: -1 |
|||
m_CullingMask: |
|||
serializedVersion: 2 |
|||
m_Bits: 4294967295 |
|||
m_RenderingPath: -1 |
|||
m_TargetTexture: {fileID: 0} |
|||
m_TargetDisplay: 0 |
|||
m_TargetEye: 3 |
|||
m_HDR: 1 |
|||
m_AllowMSAA: 1 |
|||
m_AllowDynamicResolution: 0 |
|||
m_ForceIntoRT: 0 |
|||
m_OcclusionCulling: 1 |
|||
m_StereoConvergence: 10 |
|||
m_StereoSeparation: 0.022 |
|||
--- !u!4 &1713793692 |
|||
Transform: |
|||
m_ObjectHideFlags: 0 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_GameObject: {fileID: 1713793689} |
|||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} |
|||
m_LocalPosition: {x: 0, y: 1, z: -10} |
|||
m_LocalScale: {x: 1, y: 1, z: 1} |
|||
m_Children: [] |
|||
m_Father: {fileID: 0} |
|||
m_RootOrder: 0 |
|||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} |
|
|||
fileFormatVersion: 2 |
|||
guid: 254fc2f80945542b191aff7ab8fda8cb |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System.Collections.Generic; |
|||
using Unity.UIWidgets.engine; |
|||
using Unity.UIWidgets.material; |
|||
using Unity.UIWidgets.painting; |
|||
using Unity.UIWidgets.ui; |
|||
using Unity.UIWidgets.widgets; |
|||
|
|||
namespace UIWidgetsSample { |
|||
public class ScrollbarCanvas : WidgetCanvas { |
|||
protected override Widget getWidget() { |
|||
return new Container( |
|||
decoration: new BoxDecoration( |
|||
border: Border.all(color: new Color(0xFFFFFF00)) |
|||
), |
|||
child: new Scrollbar( |
|||
child: new ListView( |
|||
children: new List<Widget> { |
|||
new Container(height: 40.0, child: new Text("0")), |
|||
new Container(height: 40.0, child: new Text("1")), |
|||
new Container(height: 40.0, child: new Text("2")), |
|||
new Container(height: 40.0, child: new Text("3")), |
|||
new Container(height: 40.0, child: new Text("4")), |
|||
new Container(height: 40.0, child: new Text("5")), |
|||
new Container(height: 40.0, child: new Text("6")), |
|||
new Container(height: 40.0, child: new Text("7")), |
|||
new Container(height: 40.0, child: new Text("8")), |
|||
new Container(height: 40.0, child: new Text("9")), |
|||
new Container(height: 40.0, child: new Text("10")), |
|||
new Container(height: 40.0, child: new Text("11")), |
|||
new Container(height: 40.0, child: new Text("12")), |
|||
new Container(height: 40.0, child: new Text("13")), |
|||
new Container(height: 40.0, child: new Text("14")), |
|||
new Container(height: 40.0, child: new Text("15")), |
|||
new Container(height: 40.0, child: new Text("16")), |
|||
new Container(height: 40.0, child: new Text("17")), |
|||
} |
|||
) |
|||
) |
|||
); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: c5c73cb2437bb4d369115d787656adf4 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.gestures; |
|||
using Unity.UIWidgets.rendering; |
|||
using Unity.UIWidgets.ui; |
|||
|
|||
namespace Unity.UIWidgets.widgets { |
|||
public abstract class CustomPainter : Listenable { |
|||
public CustomPainter(Listenable repaint = null) { |
|||
this._repaint = repaint; |
|||
} |
|||
|
|||
readonly Listenable _repaint; |
|||
|
|||
public void addListener(VoidCallback listener) { |
|||
this._repaint?.addListener(listener); |
|||
} |
|||
|
|||
public void removeListener(VoidCallback listener) { |
|||
this._repaint?.removeListener(listener); |
|||
} |
|||
|
|||
public abstract void paint(Canvas canvas, Size size); |
|||
|
|||
public abstract bool shouldRepaint(CustomPainter oldDelegate); |
|||
|
|||
public virtual bool hitTest(Offset position) { |
|||
return true; |
|||
} |
|||
|
|||
public override string ToString() { |
|||
return $"{Diagnostics.describeIdentity(this)}({this._repaint?.ToString() ?? ""})"; |
|||
} |
|||
} |
|||
|
|||
public class RenderCustomPaint : RenderProxyBox { |
|||
public RenderCustomPaint( |
|||
CustomPainter painter = null, |
|||
CustomPainter foregroundPainter = null, |
|||
Size preferredSize = null, |
|||
bool isComplex = false, |
|||
bool willChange = false, |
|||
RenderBox child = null |
|||
) : base(child) { |
|||
preferredSize = preferredSize ?? Size.zero; |
|||
this.preferredSize = preferredSize; |
|||
this._painter = painter; |
|||
this._foregroundPainter = foregroundPainter; |
|||
this.isComplex = isComplex; |
|||
this.willChange = willChange; |
|||
} |
|||
|
|||
CustomPainter _painter; |
|||
|
|||
public CustomPainter painter { |
|||
get { return this._painter; } |
|||
set { |
|||
if (this._painter == value) { |
|||
return; |
|||
} |
|||
|
|||
CustomPainter oldPainter = this._painter; |
|||
this._painter = value; |
|||
this._didUpdatePainter(this._painter, oldPainter); |
|||
} |
|||
} |
|||
|
|||
CustomPainter _foregroundPainter; |
|||
|
|||
public CustomPainter foregroundPainter { |
|||
get { return this._foregroundPainter; } |
|||
set { |
|||
if (this._foregroundPainter == value) { |
|||
return; |
|||
} |
|||
|
|||
CustomPainter oldPainter = this._foregroundPainter; |
|||
this._foregroundPainter = value; |
|||
this._didUpdatePainter(this._foregroundPainter, oldPainter); |
|||
} |
|||
} |
|||
|
|||
void _didUpdatePainter(CustomPainter newPainter, CustomPainter oldPainter) { |
|||
if (newPainter == null) { |
|||
D.assert(oldPainter != null); |
|||
this.markNeedsPaint(); |
|||
} |
|||
else if (oldPainter == null || |
|||
newPainter.GetType() != oldPainter.GetType() || |
|||
newPainter.shouldRepaint(oldPainter)) { |
|||
this.markNeedsPaint(); |
|||
} |
|||
|
|||
if (this.attached) { |
|||
oldPainter?.removeListener(this.markNeedsPaint); |
|||
newPainter?.addListener(this.markNeedsPaint); |
|||
} |
|||
} |
|||
|
|||
Size _preferredSize; |
|||
|
|||
public Size preferredSize { |
|||
get { return this._preferredSize; } |
|||
set { |
|||
D.assert(value != null); |
|||
if (this.preferredSize == value) { |
|||
return; |
|||
} |
|||
|
|||
this._preferredSize = value; |
|||
this.markNeedsLayout(); |
|||
} |
|||
} |
|||
|
|||
public bool isComplex; |
|||
|
|||
public bool willChange; |
|||
|
|||
public override void attach(object owner) { |
|||
base.attach(owner); |
|||
this._painter?.addListener(this.markNeedsPaint); |
|||
this._foregroundPainter?.addListener(this.markNeedsPaint); |
|||
} |
|||
|
|||
public override void detach() { |
|||
this._painter?.removeListener(this.markNeedsPaint); |
|||
this._foregroundPainter?.removeListener(this.markNeedsPaint); |
|||
base.detach(); |
|||
} |
|||
|
|||
protected override bool hitTestChildren(HitTestResult result, Offset position) { |
|||
if (this._foregroundPainter != null && (this._foregroundPainter.hitTest(position))) { |
|||
return true; |
|||
} |
|||
|
|||
return base.hitTestChildren(result, position: position); |
|||
} |
|||
|
|||
|
|||
protected override bool hitTestSelf(Offset position) { |
|||
return this._painter != null && this._painter.hitTest(position); |
|||
} |
|||
|
|||
protected override void performResize() { |
|||
this.size = this.constraints.constrain(this.preferredSize); |
|||
} |
|||
|
|||
void _paintWithPainter(Canvas canvas, Offset offset, CustomPainter painter) { |
|||
int debugPreviousCanvasSaveCount = 0; |
|||
canvas.save(); |
|||
D.assert(() => { |
|||
debugPreviousCanvasSaveCount = canvas.getSaveCount(); |
|||
return true; |
|||
}); |
|||
if (offset != Offset.zero) { |
|||
canvas.translate(offset.dx, offset.dy); |
|||
} |
|||
|
|||
painter.paint(canvas, this.size); |
|||
D.assert(() => { |
|||
int debugNewCanvasSaveCount = canvas.getSaveCount(); |
|||
if (debugNewCanvasSaveCount > debugPreviousCanvasSaveCount) { |
|||
throw new UIWidgetsError( |
|||
$"{debugNewCanvasSaveCount - debugPreviousCanvasSaveCount} more " + |
|||
$"time{((debugNewCanvasSaveCount - debugPreviousCanvasSaveCount == 1) ? "" : "s")} " + |
|||
"than it called canvas.restore().\n" + |
|||
"This leaves the canvas in an inconsistent state and will probably result in a broken display.\n" + |
|||
"You must pair each call to save()/saveLayer() with a later matching call to restore()." |
|||
); |
|||
} |
|||
|
|||
if (debugNewCanvasSaveCount < debugPreviousCanvasSaveCount) { |
|||
throw new UIWidgetsError( |
|||
$"The {painter} custom painter called canvas.restore() " + |
|||
$"{debugPreviousCanvasSaveCount - debugNewCanvasSaveCount} more " + |
|||
$"time{(debugPreviousCanvasSaveCount - debugNewCanvasSaveCount == 1 ? "" : "s")} " + |
|||
"than it called canvas.save() or canvas.saveLayer().\n" + |
|||
"This leaves the canvas in an inconsistent state and will result in a broken display.\n" + |
|||
"You should only call restore() if you first called save() or saveLayer()." |
|||
); |
|||
} |
|||
|
|||
return debugNewCanvasSaveCount == debugPreviousCanvasSaveCount; |
|||
}); |
|||
canvas.restore(); |
|||
} |
|||
|
|||
public override void paint(PaintingContext context, Offset offset) { |
|||
if (this._painter != null) { |
|||
this._paintWithPainter(context.canvas, offset, this._painter); |
|||
this._setRasterCacheHints(context); |
|||
} |
|||
|
|||
base.paint(context, offset); |
|||
if (this._foregroundPainter != null) { |
|||
this._paintWithPainter(context.canvas, offset, this._foregroundPainter); |
|||
this._setRasterCacheHints(context); |
|||
} |
|||
} |
|||
|
|||
void _setRasterCacheHints(PaintingContext context) { |
|||
if (this.isComplex) { |
|||
context.setIsComplexHint(); |
|||
} |
|||
|
|||
if (this.willChange) { |
|||
context.setWillChangeHint(); |
|||
} |
|||
} |
|||
} |
|||
} |
撰写
预览
正在加载...
取消
保存
Reference in new issue