Skip to content

Commit f1607a9

Browse files
committed
feat(measureview): Added the ability to .MeasureView() to measure eiter the content of the whole control for <input> and <img> HTML elements.
1 parent 27e31b8 commit f1607a9

File tree

7 files changed

+38
-22
lines changed

7 files changed

+38
-22
lines changed

src/Uno.UI.Runtime.WebAssembly/Xaml/UIElementWasmExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,9 @@ private static object RaiseHtmlCustomEventHandler(Delegate d, object sender, obj
220220
/// <remarks>
221221
/// Useful to implement .MeasureOverride() when the content size needs to be considered.
222222
/// </remarks>
223-
public static Size MeasureHtmlView(this UIElement element, Size availableSize)
223+
public static Size MeasureHtmlView(this UIElement element, Size availableSize, bool measureContent = true)
224224
{
225-
return element.MeasureView(availableSize);
225+
return element.MeasureView(availableSize, measureContent);
226226
}
227227

228228
/// <summary>

src/Uno.UI/UI/Xaml/UIElement.wasm.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ private static IEnumerable<string> GetClassesForType(Type type)
5252
}
5353
}
5454

55-
public Size MeasureView(Size availableSize)
55+
public Size MeasureView(Size availableSize, bool measureContent = true)
5656
{
57-
return Uno.UI.Xaml.WindowManagerInterop.MeasureView(HtmlId, availableSize);
57+
return Uno.UI.Xaml.WindowManagerInterop.MeasureView(HtmlId, availableSize, measureContent);
5858
}
5959

6060
internal Rect GetBBox()

src/Uno.UI/UI/Xaml/WindowManagerInterop.wasm.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -249,14 +249,15 @@ private struct WindowManagerSetPointerEventsParams
249249
#endregion
250250

251251
#region MeasureView
252-
internal static Size MeasureView(IntPtr htmlId, Size availableSize)
252+
internal static Size MeasureView(IntPtr htmlId, Size availableSize, bool measureContent)
253253
{
254254
if (UseJavascriptEval)
255255
{
256256
var w = double.IsInfinity(availableSize.Width) ? "null" : availableSize.Width.ToStringInvariant();
257257
var h = double.IsInfinity(availableSize.Height) ? "null" : availableSize.Height.ToStringInvariant();
258+
var mc = measureContent ? "true" : "false";
258259

259-
var command = "Uno.UI.WindowManager.current.measureView(" + htmlId + ", \"" + w + "\", \"" + h + "\");";
260+
var command = "Uno.UI.WindowManager.current.measureView(" + htmlId + ", \"" + w + "\", \"" + h + "\", " + mc + ");";
260261
var result = WebAssemblyRuntime.InvokeJS(command);
261262

262263
var parts = result.Split(';');
@@ -271,7 +272,8 @@ internal static Size MeasureView(IntPtr htmlId, Size availableSize)
271272
{
272273
HtmlId = htmlId,
273274
AvailableWidth = availableSize.Width,
274-
AvailableHeight = availableSize.Height
275+
AvailableHeight = availableSize.Height,
276+
MeasureContent = measureContent
275277
};
276278

277279
var ret = (WindowManagerMeasureViewReturn)TSInteropMarshaller.InvokeJS("Uno:measureViewNative", parms, typeof(WindowManagerMeasureViewReturn));
@@ -288,6 +290,7 @@ private struct WindowManagerMeasureViewParams
288290

289291
public double AvailableWidth;
290292
public double AvailableHeight;
293+
public bool MeasureContent;
291294
}
292295

293296
[TSInteropMessage]

src/Uno.UI/WasmScripts/Uno.UI.d.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,8 +497,9 @@ declare namespace Uno.UI {
497497
*
498498
* @param maxWidth string containing width in pixels. Empty string means infinite.
499499
* @param maxHeight string containing height in pixels. Empty string means infinite.
500+
* @param measureContent if we're interested by the content of the control (<img>'s image, <input>'s text...)
500501
*/
501-
measureView(viewId: string, maxWidth: string, maxHeight: string): string;
502+
measureView(viewId: string, maxWidth: string, maxHeight: string, measureContent?: boolean): string;
502503
/**
503504
* Use the Html engine to measure the element using specified constraints.
504505
*
@@ -1347,6 +1348,7 @@ declare class WindowManagerMeasureViewParams {
13471348
HtmlId: number;
13481349
AvailableWidth: number;
13491350
AvailableHeight: number;
1351+
MeasureContent: boolean;
13501352
static unmarshal(pData: number): WindowManagerMeasureViewParams;
13511353
}
13521354
declare class WindowManagerMeasureViewReturn {

src/Uno.UI/WasmScripts/Uno.UI.js

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,9 +1479,10 @@ var Uno;
14791479
*
14801480
* @param maxWidth string containing width in pixels. Empty string means infinite.
14811481
* @param maxHeight string containing height in pixels. Empty string means infinite.
1482+
* @param measureContent if we're interested by the content of the control (<img>'s image, <input>'s text...)
14821483
*/
1483-
measureView(viewId, maxWidth, maxHeight) {
1484-
const ret = this.measureViewInternal(Number(viewId), maxWidth ? Number(maxWidth) : NaN, maxHeight ? Number(maxHeight) : NaN);
1484+
measureView(viewId, maxWidth, maxHeight, measureContent = true) {
1485+
const ret = this.measureViewInternal(Number(viewId), maxWidth ? Number(maxWidth) : NaN, maxHeight ? Number(maxHeight) : NaN, measureContent);
14851486
return `${ret[0]};${ret[1]}`;
14861487
}
14871488
/**
@@ -1492,7 +1493,7 @@ var Uno;
14921493
*/
14931494
measureViewNative(pParams, pReturn) {
14941495
const params = WindowManagerMeasureViewParams.unmarshal(pParams);
1495-
const ret = this.measureViewInternal(params.HtmlId, params.AvailableWidth, params.AvailableHeight);
1496+
const ret = this.measureViewInternal(params.HtmlId, params.AvailableWidth, params.AvailableHeight, params.MeasureContent);
14961497
const ret2 = new WindowManagerMeasureViewReturn();
14971498
ret2.DesiredWidth = ret[0];
14981499
ret2.DesiredHeight = ret[1];
@@ -1507,7 +1508,7 @@ var Uno;
15071508
// +1 is added to take rounding/flooring into account
15081509
return [resultWidth + 1, resultHeight];
15091510
}
1510-
measureViewInternal(viewId, maxWidth, maxHeight) {
1511+
measureViewInternal(viewId, maxWidth, maxHeight, measureContent) {
15111512
const element = this.getView(viewId);
15121513
const elementStyle = element.style;
15131514
const elementClasses = element.className;
@@ -1533,12 +1534,12 @@ var Uno;
15331534
}
15341535
this.containerElement.appendChild(unconnectedRoot);
15351536
}
1536-
if (element instanceof HTMLImageElement) {
1537+
if (measureContent && element instanceof HTMLImageElement) {
15371538
elementStyle.cssText = unconstrainedStyleCssText;
15381539
const imgElement = element;
15391540
return [imgElement.naturalWidth, imgElement.naturalHeight];
15401541
}
1541-
else if (element instanceof HTMLInputElement) {
1542+
else if (measureContent && element instanceof HTMLInputElement) {
15421543
elementStyle.cssText = unconstrainedStyleCssText;
15431544
const inputElement = element;
15441545
cleanupUnconnectedRoot(this.containerElement);
@@ -1554,7 +1555,7 @@ var Uno;
15541555
// Take the width of the inner text, but keep the height of the input element.
15551556
return [textSize[0], inputSize[1]];
15561557
}
1557-
else if (element instanceof HTMLTextAreaElement) {
1558+
else if (measureContent && element instanceof HTMLTextAreaElement) {
15581559
const inputElement = element;
15591560
cleanupUnconnectedRoot(this.containerElement);
15601561
// Create a temporary element that will contain the input's content
@@ -2205,6 +2206,7 @@ var Windows;
22052206
throw new Error("A DragDropExtension has already been enabled");
22062207
}
22072208
DragDropExtension._dispatchDragDropArgs = pArgs;
2209+
DragDropExtension._nextDropId = 1;
22082210
DragDropExtension._current = new DragDropExtension();
22092211
}
22102212
static disable(pArgs) {
@@ -4975,6 +4977,9 @@ class WindowManagerMeasureViewParams {
49754977
{
49764978
ret.AvailableHeight = Number(Module.getValue(pData + 16, "double"));
49774979
}
4980+
{
4981+
ret.MeasureContent = Boolean(Module.getValue(pData + 24, "i32"));
4982+
}
49784983
return ret;
49794984
}
49804985
}

src/Uno.UI/ts/WindowManager.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1487,10 +1487,11 @@ namespace Uno.UI {
14871487
*
14881488
* @param maxWidth string containing width in pixels. Empty string means infinite.
14891489
* @param maxHeight string containing height in pixels. Empty string means infinite.
1490+
* @param measureContent if we're interested by the content of the control (<img>'s image, <input>'s text...)
14901491
*/
1491-
public measureView(viewId: string, maxWidth: string, maxHeight: string): string {
1492+
public measureView(viewId: string, maxWidth: string, maxHeight: string, measureContent: boolean = true): string {
14921493

1493-
const ret = this.measureViewInternal(Number(viewId), maxWidth ? Number(maxWidth) : NaN, maxHeight ? Number(maxHeight) : NaN);
1494+
const ret = this.measureViewInternal(Number(viewId), maxWidth ? Number(maxWidth) : NaN, maxHeight ? Number(maxHeight) : NaN, measureContent);
14941495

14951496
return `${ret[0]};${ret[1]}`;
14961497
}
@@ -1505,7 +1506,7 @@ namespace Uno.UI {
15051506

15061507
const params = WindowManagerMeasureViewParams.unmarshal(pParams);
15071508

1508-
const ret = this.measureViewInternal(params.HtmlId, params.AvailableWidth, params.AvailableHeight);
1509+
const ret = this.measureViewInternal(params.HtmlId, params.AvailableWidth, params.AvailableHeight, params.MeasureContent);
15091510

15101511
const ret2 = new WindowManagerMeasureViewReturn();
15111512
ret2.DesiredWidth = ret[0];
@@ -1531,7 +1532,7 @@ namespace Uno.UI {
15311532
return [resultWidth + 1, resultHeight];
15321533
}
15331534

1534-
private measureViewInternal(viewId: number, maxWidth: number, maxHeight: number): [number, number] {
1535+
private measureViewInternal(viewId: number, maxWidth: number, maxHeight: number, measureContent: boolean): [number, number] {
15351536
const element = this.getView(viewId) as HTMLElement;
15361537

15371538
const elementStyle = element.style;
@@ -1564,11 +1565,11 @@ namespace Uno.UI {
15641565
this.containerElement.appendChild(unconnectedRoot);
15651566
}
15661567

1567-
if (element instanceof HTMLImageElement) {
1568+
if (measureContent && element instanceof HTMLImageElement) {
15681569
elementStyle.cssText = unconstrainedStyleCssText;
15691570
const imgElement = element as HTMLImageElement;
15701571
return [imgElement.naturalWidth, imgElement.naturalHeight];
1571-
} else if (element instanceof HTMLInputElement) {
1572+
} else if (measureContent && element instanceof HTMLInputElement) {
15721573
elementStyle.cssText = unconstrainedStyleCssText;
15731574
const inputElement = element as HTMLInputElement;
15741575

@@ -1588,7 +1589,7 @@ namespace Uno.UI {
15881589

15891590
// Take the width of the inner text, but keep the height of the input element.
15901591
return [textSize[0], inputSize[1]];
1591-
} else if (element instanceof HTMLTextAreaElement) {
1592+
} else if (measureContent && element instanceof HTMLTextAreaElement) {
15921593
const inputElement = element;
15931594

15941595
cleanupUnconnectedRoot(this.containerElement);

src/Uno.UI/tsBindings/WindowManagerMeasureViewParams.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ class WindowManagerMeasureViewParams
55
public HtmlId : number;
66
public AvailableWidth : number;
77
public AvailableHeight : number;
8+
public MeasureContent : boolean;
89
public static unmarshal(pData:number) : WindowManagerMeasureViewParams
910
{
1011
const ret = new WindowManagerMeasureViewParams();
@@ -20,6 +21,10 @@ class WindowManagerMeasureViewParams
2021
{
2122
ret.AvailableHeight = Number(Module.getValue(pData + 16, "double"));
2223
}
24+
25+
{
26+
ret.MeasureContent = Boolean(Module.getValue(pData + 24, "i32"));
27+
}
2328
return ret;
2429
}
2530
}

0 commit comments

Comments
 (0)