From 29cf49b3f620e0b9b7ae3bb626cd56a3db10ce5a Mon Sep 17 00:00:00 2001 From: Bas Date: Mon, 20 May 2024 22:04:07 +0200 Subject: [PATCH] Allow simple strings as column headers --- src/elements/controls/listview.ts | 51 ++++++++++++------- tests/elements/controls/listview.tests.ts | 61 +++++++++++++++++++++++ 2 files changed, 94 insertions(+), 18 deletions(-) diff --git a/src/elements/controls/listview.ts b/src/elements/controls/listview.ts index 9f5ddd5..63a0eda 100644 --- a/src/elements/controls/listview.ts +++ b/src/elements/controls/listview.ts @@ -10,7 +10,7 @@ import { ScaleType } from "@src/positional/parsing/scaleType"; import { Rectangle } from "@src/positional/rectangle"; import { Scale } from "@src/positional/scale"; import { round } from "@src/utilities/math"; -import { isUndefined } from "@src/utilities/type"; +import { isString, isUndefined } from "@src/utilities/type"; import { BuildOutput } from "@src/windows/buildOutput"; import { ParentControl } from "@src/windows/parentControl"; import { WidgetCreator } from "@src/windows/widgets/widgetCreator"; @@ -65,14 +65,14 @@ export interface ListViewParams extends ElementParams * If specified, will add header information above each column and optionally adds sorting. * @default undefined */ - columns?: Partial[] | ListViewColumnParams[]; + columns?: Partial[] | ListViewColumnParams[] | string[]; /** * Specifies the items within the listview, either as a single dimension array for * a single row or a multi-dimensional array for multiple columns per row. Can also * include seperator objects to divide the list into multiple sections. */ - items: Bindable; + items: Bindable; /** * Whether to allow scrolling horizontally, vertically, both, or neither. @@ -191,27 +191,42 @@ class ListViewControl extends Control implements Omit< let type = -1; let differentTypes = false; + let column: typeof columns[0]; + let parsedWidth: ParsedScale; + let parsedType: ScaleType; + for (let i = 0; i < count; i++) { - const column = columns[i]; - const tooltip = (column).tooltip; - const ratioWidth = (>column).ratioWidth; - const width = column.width; - const parsedWidth: ParsedScale = (isUndefined(width) && !isUndefined(ratioWidth)) - ? [ratioWidth, ScaleType.Weight] - : parseScaleOrFallback(width, defaultScale); - const parsedType = parsedWidth[1]; + column = columns[i]; - differentTypes ||= (type != parsedType && type != -1); - type = parsedType; + if (isString(column)) + { + // Parse simplified string column to OpenRCT2's ListViewColumn. + columns[i] = { header: column }; + parsedWidth = defaultScale; + } + else + { + const tooltip = (column).tooltip; + const ratioWidth = (>column).ratioWidth; + const width = column.width; - columWidths[i] = parsedWidth; + parsedWidth = (isUndefined(width) && !isUndefined(ratioWidth)) + ? [ratioWidth, ScaleType.Weight] + : parseScaleOrFallback(width, defaultScale); - // Rename tooltip property - if (tooltip) - { - (column).headerTooltip = tooltip; + // Rename tooltip property + if (tooltip) + { + (column).headerTooltip = tooltip; + } } + + parsedType = parsedWidth[1]; + columWidths[i] = parsedWidth; + + differentTypes ||= (type != parsedType && type != -1); + type = parsedType; } // If there is different width types, or there is percentile width, let the plugin handle calculation. diff --git a/tests/elements/controls/listview.tests.ts b/tests/elements/controls/listview.tests.ts index 8618c62..ae91456 100644 --- a/tests/elements/controls/listview.tests.ts +++ b/tests/elements/controls/listview.tests.ts @@ -85,6 +85,67 @@ test("Standard properties are set", t => t.deepEqual(items[2], [ "2.", "bottom entry" ]); }); +test("Simple column names get converted", t => +{ + const mock = Mock.ui(); + globalThis.ui = mock; + + const template = window({ + width: 100, height: 100, + content: [ + listview({ + columns: [ "First", "Second", "Third" ], + items: [ + [ "1.", "top entry" ], + { type: "seperator", text: "central entry" }, + [ "2.", "bottom entry" ] + ], + scrollbars: "vertical" + }) + ] + }); + + template.open(); + + const widget = mock.createdWindows[0].widgets[0] as ListViewWidget; + t.is(widget.type, "listview"); + t.is(widget.scrollbars, "vertical"); + t.true(widget.showColumnHeaders); + t.falsy(widget.selectedCell); + t.falsy(widget.canSelect); + t.falsy(widget.isStriped); + + const columns = widget.columns; + t.is(columns.length, 3); + + t.is(columns[0].header, "First"); + t.is(columns[0].ratioWidth, 1); + t.falsy(columns[0].headerTooltip); + t.falsy(columns[0].sortOrder); + t.falsy(columns[0].canSort); + t.falsy(columns[0].width); + t.falsy(columns[0].minWidth); + t.falsy(columns[0].maxWidth); + + t.is(columns[1].header, "Second"); + t.is(columns[1].ratioWidth, 1); + t.falsy(columns[1].headerTooltip); + t.falsy(columns[1].sortOrder); + t.falsy(columns[1].canSort); + t.falsy(columns[1].width); + t.falsy(columns[1].minWidth); + t.falsy(columns[1].maxWidth); + + t.is(columns[2].header, "Third"); + t.is(columns[2].ratioWidth, 1); + t.falsy(columns[2].headerTooltip); + t.falsy(columns[2].sortOrder); + t.falsy(columns[2].canSort); + t.falsy(columns[2].width); + t.falsy(columns[2].minWidth); + t.falsy(columns[2].maxWidth); +}); + test("Items is bindable", t => { const mock = Mock.ui();