Themeconfig: improve icon badge expansion
This commit is contained in:
parent
add464f58f
commit
2b0b62fcfa
2 changed files with 77 additions and 48 deletions
|
@ -1,18 +1,6 @@
|
||||||
import {
|
import { Concat, DesugaringContext, DesugaringStep, Each, FirstOf, Fuse, On, SetDefault } from "./Conversion"
|
||||||
Concat,
|
|
||||||
DesugaringContext,
|
|
||||||
DesugaringStep,
|
|
||||||
Each,
|
|
||||||
FirstOf,
|
|
||||||
Fuse,
|
|
||||||
On,
|
|
||||||
SetDefault,
|
|
||||||
} from "./Conversion"
|
|
||||||
import { LayerConfigJson } from "../Json/LayerConfigJson"
|
import { LayerConfigJson } from "../Json/LayerConfigJson"
|
||||||
import {
|
import { MinimalTagRenderingConfigJson, TagRenderingConfigJson } from "../Json/TagRenderingConfigJson"
|
||||||
MinimalTagRenderingConfigJson,
|
|
||||||
TagRenderingConfigJson,
|
|
||||||
} from "../Json/TagRenderingConfigJson"
|
|
||||||
import { Utils } from "../../../Utils"
|
import { Utils } from "../../../Utils"
|
||||||
import RewritableConfigJson from "../Json/RewritableConfigJson"
|
import RewritableConfigJson from "../Json/RewritableConfigJson"
|
||||||
import SpecialVisualizations from "../../../UI/SpecialVisualizations"
|
import SpecialVisualizations from "../../../UI/SpecialVisualizations"
|
||||||
|
@ -36,7 +24,7 @@ import { ExpandTagRendering } from "./ExpandTagRendering"
|
||||||
class AddFiltersFromTagRenderings extends DesugaringStep<LayerConfigJson> {
|
class AddFiltersFromTagRenderings extends DesugaringStep<LayerConfigJson> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super(
|
super(
|
||||||
'Inspects all the tagRenderings. If some tagRenderings have the `filter` attribute set, introduce those filters. This step might introduce shorthand filter names, thus \'ExpandFilter\' should be run afterwards. Can be disabled with "#filter":"no-auto"',
|
"Inspects all the tagRenderings. If some tagRenderings have the `filter` attribute set, introduce those filters. This step might introduce shorthand filter names, thus 'ExpandFilter' should be run afterwards. Can be disabled with \"#filter\":\"no-auto\"",
|
||||||
["filter"],
|
["filter"],
|
||||||
"AddFiltersFromTagRenderings"
|
"AddFiltersFromTagRenderings"
|
||||||
)
|
)
|
||||||
|
@ -139,7 +127,7 @@ class DetectInline extends DesugaringStep<QuestionableTagRenderingConfigJson> {
|
||||||
if (json.freeform.inline === true) {
|
if (json.freeform.inline === true) {
|
||||||
context.err(
|
context.err(
|
||||||
"'inline' is set, but the rendering contains a special visualisation...\n " +
|
"'inline' is set, but the rendering contains a special visualisation...\n " +
|
||||||
spec[key]
|
spec[key]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
json = JSON.parse(JSON.stringify(json))
|
json = JSON.parse(JSON.stringify(json))
|
||||||
|
@ -238,20 +226,20 @@ export class AddQuestionBox extends DesugaringStep<LayerConfigJson> {
|
||||||
if (blacklisted?.length > 0 && used?.length > 0) {
|
if (blacklisted?.length > 0 && used?.length > 0) {
|
||||||
context.err(
|
context.err(
|
||||||
"The {questions()}-special rendering only supports either a blacklist OR a whitelist, but not both." +
|
"The {questions()}-special rendering only supports either a blacklist OR a whitelist, but not both." +
|
||||||
"\n Whitelisted: " +
|
"\n Whitelisted: " +
|
||||||
used.join(", ") +
|
used.join(", ") +
|
||||||
"\n Blacklisted: " +
|
"\n Blacklisted: " +
|
||||||
blacklisted.join(", ")
|
blacklisted.join(", ")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
for (const usedLabel of used) {
|
for (const usedLabel of used) {
|
||||||
if (!allLabels.has(usedLabel)) {
|
if (!allLabels.has(usedLabel)) {
|
||||||
context.err(
|
context.err(
|
||||||
"This layers specifies a special question element for label `" +
|
"This layers specifies a special question element for label `" +
|
||||||
usedLabel +
|
usedLabel +
|
||||||
"`, but this label doesn't exist.\n" +
|
"`, but this label doesn't exist.\n" +
|
||||||
" Available labels are " +
|
" Available labels are " +
|
||||||
Array.from(allLabels).join(", ")
|
Array.from(allLabels).join(", ")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
seen.add(usedLabel)
|
seen.add(usedLabel)
|
||||||
|
@ -265,8 +253,8 @@ export class AddQuestionBox extends DesugaringStep<LayerConfigJson> {
|
||||||
const question: QuestionableTagRenderingConfigJson = {
|
const question: QuestionableTagRenderingConfigJson = {
|
||||||
id: "leftover-questions",
|
id: "leftover-questions",
|
||||||
render: {
|
render: {
|
||||||
"*": `{questions( ,${Array.from(seen).join(";")})}`,
|
"*": `{questions( ,${Array.from(seen).join(";")})}`
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
json.tagRenderings.push(question)
|
json.tagRenderings.push(question)
|
||||||
}
|
}
|
||||||
|
@ -348,13 +336,13 @@ export class AddEditingElements extends DesugaringStep<LayerConfigJson> {
|
||||||
if (json.allowMove && !usedSpecialFunctions.has("move_button")) {
|
if (json.allowMove && !usedSpecialFunctions.has("move_button")) {
|
||||||
json.tagRenderings.push({
|
json.tagRenderings.push({
|
||||||
id: "move-button",
|
id: "move-button",
|
||||||
render: { "*": "{move_button()}" },
|
render: { "*": "{move_button()}" }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (json.deletion && !usedSpecialFunctions.has("delete_button")) {
|
if (json.deletion && !usedSpecialFunctions.has("delete_button")) {
|
||||||
json.tagRenderings.push({
|
json.tagRenderings.push({
|
||||||
id: "delete-button",
|
id: "delete-button",
|
||||||
render: { "*": "{delete_button()}" },
|
render: { "*": "{delete_button()}" }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,9 +357,9 @@ export class AddEditingElements extends DesugaringStep<LayerConfigJson> {
|
||||||
or: [
|
or: [
|
||||||
"__featureSwitchIsDebugging=true",
|
"__featureSwitchIsDebugging=true",
|
||||||
"mapcomplete-show_tags=full",
|
"mapcomplete-show_tags=full",
|
||||||
"mapcomplete-show_debug=yes",
|
"mapcomplete-show_debug=yes"
|
||||||
],
|
]
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
json.tagRenderings?.push(trc)
|
json.tagRenderings?.push(trc)
|
||||||
}
|
}
|
||||||
|
@ -479,10 +467,10 @@ export class RewriteSpecial extends DesugaringStep<TagRenderingConfigJson> {
|
||||||
private static convertIfNeeded(
|
private static convertIfNeeded(
|
||||||
input:
|
input:
|
||||||
| (object & {
|
| (object & {
|
||||||
special: {
|
special: {
|
||||||
type: string
|
type: string
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
| any,
|
| any,
|
||||||
context: ConversionContext
|
context: ConversionContext
|
||||||
): any {
|
): any {
|
||||||
|
@ -580,7 +568,7 @@ export class RewriteSpecial extends DesugaringStep<TagRenderingConfigJson> {
|
||||||
.map((nm) => RewriteSpecial.escapeStr(special[nm] ?? "", context))
|
.map((nm) => RewriteSpecial.escapeStr(special[nm] ?? "", context))
|
||||||
.join(",")
|
.join(",")
|
||||||
return {
|
return {
|
||||||
"*": `{${type}(${args})${clss}}`,
|
"*": `{${type}(${args})${clss}}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -678,11 +666,50 @@ class ExpandIconBadges extends DesugaringStep<PointRenderingConfigJson> {
|
||||||
}[] = []
|
}[] = []
|
||||||
|
|
||||||
for (let i = 0; i < badgesJson.length; i++) {
|
for (let i = 0; i < badgesJson.length; i++) {
|
||||||
const iconBadge: {
|
const iconBadge: string | ({
|
||||||
if: TagConfigJson
|
if: TagConfigJson
|
||||||
then: string | MinimalTagRenderingConfigJson
|
then: string | MinimalTagRenderingConfigJson
|
||||||
} = badgesJson[i]
|
}) = badgesJson[i]
|
||||||
const expanded = this._expand.convert(
|
|
||||||
|
|
||||||
|
if (typeof iconBadge === "string") {
|
||||||
|
|
||||||
|
const expanded: QuestionableTagRenderingConfigJson[] = this._expand.convert(
|
||||||
|
iconBadge,
|
||||||
|
context.enters("iconBadges", i)
|
||||||
|
)
|
||||||
|
|
||||||
|
for (const tr of expanded) {
|
||||||
|
const condition = tr.condition
|
||||||
|
for (const trElement of tr.mappings) {
|
||||||
|
const showIf = TagUtils.optimzeJson({
|
||||||
|
and: Utils.NoNull([condition,
|
||||||
|
{
|
||||||
|
or: Utils.NoNull([
|
||||||
|
trElement.alsoShowIf, trElement.if
|
||||||
|
])
|
||||||
|
}
|
||||||
|
])
|
||||||
|
})
|
||||||
|
if (showIf === true) {
|
||||||
|
context.warn("Dropping iconBadge that would be _always_ shown: " + (trElement.icon ?? trElement.then))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (showIf === false) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
iconBadges.push({
|
||||||
|
if: showIf,
|
||||||
|
then: trElement.icon ?? trElement.then
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
const expanded: QuestionableTagRenderingConfigJson[] = this._expand.convert(
|
||||||
<QuestionableTagRenderingConfigJson>iconBadge.then,
|
<QuestionableTagRenderingConfigJson>iconBadge.then,
|
||||||
context.enters("iconBadges", i)
|
context.enters("iconBadges", i)
|
||||||
)
|
)
|
||||||
|
@ -694,7 +721,7 @@ class ExpandIconBadges extends DesugaringStep<PointRenderingConfigJson> {
|
||||||
iconBadges.push(
|
iconBadges.push(
|
||||||
...expanded.map((resolved) => ({
|
...expanded.map((resolved) => ({
|
||||||
if: iconBadge.if,
|
if: iconBadge.if,
|
||||||
then: <MinimalTagRenderingConfigJson>resolved,
|
then: <MinimalTagRenderingConfigJson>resolved
|
||||||
}))
|
}))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -707,7 +734,7 @@ class PreparePointRendering extends Fuse<PointRenderingConfigJson> {
|
||||||
constructor(state: DesugaringContext, layer: LayerConfigJson) {
|
constructor(state: DesugaringContext, layer: LayerConfigJson) {
|
||||||
super(
|
super(
|
||||||
"Prepares point renderings by expanding 'icon' and 'iconBadges'." +
|
"Prepares point renderings by expanding 'icon' and 'iconBadges'." +
|
||||||
" A tagRendering from the host tagRenderings will be substituted in",
|
" A tagRendering from the host tagRenderings will be substituted in",
|
||||||
new On(
|
new On(
|
||||||
"marker",
|
"marker",
|
||||||
new Each(
|
new Each(
|
||||||
|
@ -834,7 +861,7 @@ export class AddRatingBadge extends DesugaringStep<LayerConfigJson> {
|
||||||
|
|
||||||
const specialVis: Exclude<RenderingSpecification, string>[] = <
|
const specialVis: Exclude<RenderingSpecification, string>[] = <
|
||||||
Exclude<RenderingSpecification, string>[]
|
Exclude<RenderingSpecification, string>[]
|
||||||
>ValidationUtils.getAllSpecialVisualisations(<any>json.tagRenderings).filter(
|
>ValidationUtils.getAllSpecialVisualisations(<any>json.tagRenderings).filter(
|
||||||
(rs) => typeof rs !== "string"
|
(rs) => typeof rs !== "string"
|
||||||
)
|
)
|
||||||
const funcs = new Set<string>(specialVis.map((rs) => rs.func.funcName))
|
const funcs = new Set<string>(specialVis.map((rs) => rs.func.funcName))
|
||||||
|
@ -870,7 +897,7 @@ export class AutoTitleIcon extends DesugaringStep<LayerConfigJson> {
|
||||||
}
|
}
|
||||||
return <TagRenderingConfigJson>{
|
return <TagRenderingConfigJson>{
|
||||||
id: "title_icon_auto_" + tr.id,
|
id: "title_icon_auto_" + tr.id,
|
||||||
mappings,
|
mappings
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -915,8 +942,8 @@ export class AutoTitleIcon extends DesugaringStep<LayerConfigJson> {
|
||||||
.enters("titleIcons", i)
|
.enters("titleIcons", i)
|
||||||
.warn(
|
.warn(
|
||||||
"TagRendering with id " +
|
"TagRendering with id " +
|
||||||
trId +
|
trId +
|
||||||
" does not have any icons, not generating an icon for this"
|
" does not have any icons, not generating an icon for this"
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -979,7 +1006,7 @@ export class PrepareLayer extends Fuse<LayerConfigJson> {
|
||||||
(layer) =>
|
(layer) =>
|
||||||
new Concat(
|
new Concat(
|
||||||
new ExpandTagRendering(state, layer, {
|
new ExpandTagRendering(state, layer, {
|
||||||
addToContext: options?.addTagRenderingsToContext ?? false,
|
addToContext: options?.addTagRenderingsToContext ?? false
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
|
|
@ -70,16 +70,18 @@ export default interface PointRenderingConfigJson {
|
||||||
* They will be added as a 25% height icon at the bottom right of the icon, with all the badges in a flex layout.
|
* They will be added as a 25% height icon at the bottom right of the icon, with all the badges in a flex layout.
|
||||||
*
|
*
|
||||||
* Note: strings are interpreted as icons, so layering and substituting is supported. You can use `circle:white;./my_icon.svg` to add a background circle
|
* Note: strings are interpreted as icons, so layering and substituting is supported. You can use `circle:white;./my_icon.svg` to add a background circle
|
||||||
|
* Alternatively, this can reuse a _tagRendering_ from another layer, e.g. one of the 'icons'-tagrenderings.
|
||||||
|
* See ExpandIconBadges on how this is handled
|
||||||
* group: hidden
|
* group: hidden
|
||||||
*/
|
*/
|
||||||
iconBadges?: {
|
iconBadges?: (string | {
|
||||||
if: TagConfigJson
|
if: TagConfigJson
|
||||||
/**
|
/**
|
||||||
* Badge to show
|
* Badge to show
|
||||||
* Type: icon
|
* Type: icon
|
||||||
*/
|
*/
|
||||||
then: string | MinimalTagRenderingConfigJson
|
then: string | MinimalTagRenderingConfigJson
|
||||||
}[]
|
})[]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* question: What size should the marker be on the map?
|
* question: What size should the marker be on the map?
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue