New API, allwing color configuration (resolves #7) and Speed Provider Settings

This commit is contained in:
Manuel Vögele
2021-02-17 16:25:17 +01:00
parent 6ea03579b9
commit 75d59171d6
8 changed files with 514 additions and 96 deletions
+14 -2
View File
@@ -1,6 +1,18 @@
## In development ## In development
### Other ### New features
- Drag Ruler is now aware of good default values for the lancer game system (thanks to Grygon) - The color used to indicate speed ranges is now configurable
- The settings dialog has been reworked
### System compatibility
- Drag Ruler's Generic SpeedProvider is now aware of good default values for the lancer game system (thanks to Grygon)
### API changes
This release introduces a new API that is incompatible with the old API. The new API offers more flexibility for users and Speed Providers alike and allows to add new features in the future without breaking compatibility again. The old API will continue to function, but to profit from any of the features below Speed Providers need to switch to the new API. For more details check out the API documentation.
The following things have changed with the new API:
- Colors used by speed providers can now be changed by the user via configuration
- Speed Providers can now offer settings to the user that will be integrated into Drag Ruler's settings menu
## 1.2.2 ## 1.2.2
### Translation ### Translation
+39 -12
View File
@@ -1,10 +1,7 @@
{ {
"drag-ruler": { "drag-ruler": {
"genericSpeedProvider": {
"settings": { "settings": {
"alwaysShowSpeedForPCs": {
"name": "Show PC speed to everyone",
"hint": "If enabled the coloring based on actor speed for player characters will shown to everyone, even if they don't have observer permission for the character sheet."
},
"dashMultiplier": { "dashMultiplier": {
"name": "Dash Multiplier", "name": "Dash Multiplier",
"hint": "This can be used to give tokens a secondary speed during coloring of the measured path. Set it to 0 to disable the secondary speed." "hint": "This can be used to give tokens a secondary speed during coloring of the measured path. Set it to 0 to disable the secondary speed."
@@ -12,19 +9,49 @@
"speedAttribute": { "speedAttribute": {
"name": "Speed Attribute", "name": "Speed Attribute",
"hint": "The attribute that defines a token's walking speed. This is used during coloring of the measured path." "hint": "The attribute that defines a token's walking speed. This is used during coloring of the measured path."
}
},
"speeds": {
"walk": "walk",
"dash": "dash"
}
},
"settings": {
"alwaysShowSpeedForPCs": {
"name": "Show PC speed to everyone",
"hint": "If enabled the coloring based on actor speed for player characters will shown to everyone, even if they don't have observer permission for the character sheet."
},
"speedProviderSettings": {
"name": "Speed Provider Settings",
"hint": "The Speed Provider Settings contain all the game system specific settings.",
"button": "Speed Provider Settings",
"windowTitle": "Speed Provider Settings",
"headers": {
"speedProvider": "Speed Provider",
"speedProviderSettings": "Speed Provider specific settings"
},
"activeProvider": {
"name": "Currently active Speed Provider",
"hint": "The settings show below depend on the active speed provider. If the GM selects a different speed provider the available settings may change."
},
"noSettings": "This speed provider doesn't offer any configuration options.",
"color": {
"name": "Color for {colorName}",
"hint": "The color that will be used to color square that are within {colorName} range",
"unreachable": {
"name": "unreachable",
"hint": "The color for spaces that aren't reachable by the dragged token"
}
}, },
"speedProvider": { "speedProvider": {
"name": "Speed Settings Provider", "name": "Speed Settings Provider",
"hint": "Select who provides speed information for tokens duing coloring. Using a game system or module may provide more flexible coloring than sticking to the options provided by Drag Ruler.", "hint": "Select who provides speed information for tokens duing coloring. Drag Ruler offers a generic speed provider that provides basic functionality and should work for all game systems if configured correctly. More speed providers can be made available via game systems and installed modules. Selecting a different speed provider than the generic speed provider may offer a better integration into the rules of the game system you're using. The options below are dependent upon the speed provider selected here.",
"choices": { "choices": {
"module": "Module", "module": "Module {name}",
"native": "Drag Ruler", "native": "Generic",
"system": "System" "system": "System {name}"
}
} }
},
"staticFirstColor": {
"name": "Static First Color",
"hint": "Use a static color for the first movement range instead of the player color"
}, },
"swapSpacebarRightClick": { "swapSpacebarRightClick": {
"name": "Swap spacebar and right click", "name": "Swap spacebar and right click",
+3
View File
@@ -15,6 +15,9 @@
"esmodules": [ "esmodules": [
"src/main.js" "src/main.js"
], ],
"templates": [
"speed_provider_settings.html"
],
"languages": [ "languages": [
{ {
"lang": "en", "lang": "en",
+68 -16
View File
@@ -1,37 +1,60 @@
import {GenericSpeedProvider, SpeedProvider} from "./speed_provider.js"
import {settingsKey} from "./settings.js"
export const availableSpeedProviders = {} export const availableSpeedProviders = {}
export let currentSpeedProvider = undefined export let currentSpeedProvider = undefined
function register(module, type, speedProvider) { function register(module, type, speedProvider) {
const providerSetting = game.settings.settings.get("drag-ruler.speedProvider") const id = `${type}.${module.id}`
let providerInstance
if (speedProvider.prototype instanceof SpeedProvider) {
providerInstance = new speedProvider(id)
}
else {
speedProvider.id = id
providerInstance = speedProvider
}
setupProvider(providerInstance)
}
// Add the registered module to the settings entry function setupProvider(speedProvider) {
providerSetting.config = true if (speedProvider instanceof SpeedProvider) {
const moduleName = module.data.title const unreachableColor = {id: "unreachable", default: speedProvider.defaultUnreachableColor, name: "drag-ruler.settings.speedProviderSettings.color.unreachable.name"}
const typeTitle = game.i18n.localize(`drag-ruler.settings.speedProvider.choices.${type}`) for (const color of speedProvider.colors.concat([unreachableColor])) {
providerSetting.choices[`${type}.${module.id}`] = `${typeTitle} ${moduleName}` game.settings.register(settingsKey, `speedProviders.${speedProvider.id}.color.${color.id}`, {
availableSpeedProviders[`${type}.${module.id}`] = speedProvider config: false,
providerSetting.default = getDefaultSpeedProvider() scope: "client",
type: Number,
default: color.default,
})
}
for (const setting of speedProvider.settings) {
setting.config = false
game.settings.register(settingsKey, `speedProviders.${speedProvider.id}.setting.${setting.id}`, setting)
}
}
availableSpeedProviders[speedProvider.id] = speedProvider
game.settings.settings.get("drag-ruler.speedProvider").default = getDefaultSpeedProvider()
updateSpeedProvider() updateSpeedProvider()
} }
function getDefaultSpeedProvider() { export function getDefaultSpeedProvider() {
const providerSetting = game.settings.settings.get("drag-ruler.speedProvider") const providerIds = Object.keys(availableSpeedProviders)
const settingKeys = Object.keys(providerSetting.choices)
// Game systems take the highest precedence for the being the default // Game systems take the highest precedence for the being the default
const gameSystem = settingKeys.find(key => key.startsWith("system.")) const gameSystem = providerIds.find(key => key.startsWith("system."))
if (gameSystem) if (gameSystem)
return gameSystem return gameSystem
// If no game system is registered modules are next up. // If no game system is registered modules are next up.
// For lack of a method to select the best module we're just falling back to taking the next best module // For lack of a method to select the best module we're just falling back to taking the next best module
// settingKeys should always be sorted the same way so this should achive a stable default // settingKeys should always be sorted the same way so this should achive a stable default
const module = settingKeys.find(key => key.startsWith("module.")) const module = providerIds.find(key => key.startsWith("module."))
if (module) if (module)
return module return module
// If neither a game system or a module is found fall back to the native implementation // If neither a game system or a module is found fall back to the native implementation
return settingKeys[0] return providerIds[0]
} }
export function updateSpeedProvider() { export function updateSpeedProvider() {
@@ -40,8 +63,37 @@ export function updateSpeedProvider() {
currentSpeedProvider = availableSpeedProviders[configuredProvider] ?? availableSpeedProviders[game.settings.settings.get("drag-ruler.speedProvider").default] currentSpeedProvider = availableSpeedProviders[configuredProvider] ?? availableSpeedProviders[game.settings.settings.get("drag-ruler.speedProvider").default]
} }
export function setCurrentSpeedProvider(newSpeedProvider) { export function initApi() {
currentSpeedProvider = newSpeedProvider const genericSpeedProviderInstance = new GenericSpeedProvider("native")
setupProvider(genericSpeedProviderInstance)
}
export function getRangesFromSpeedProvider(token) {
try {
if (currentSpeedProvider instanceof Function)
return currentSpeedProvider(token, 0x00FF00)
const ranges = currentSpeedProvider.getRanges(token)
for (const range of ranges) {
range.color = game.settings.get(settingsKey, `speedProviders.${currentSpeedProvider.id}.color.${range.color}`)
}
return ranges
}
catch (e) {
console.error(e)
return []
}
}
export function getUnreachableColorFromSpeedProvider() {
if (currentSpeedProvider instanceof Function)
return 0xFF0000
try {
return game.settings.get(settingsKey, `speedProviders.${currentSpeedProvider.id}.color.unreachable`)
}
catch (e) {
console.error(e)
return 0xFF0000
}
} }
export function registerModule(moduleId, speedProvider) { export function registerModule(moduleId, speedProvider) {
+7 -25
View File
@@ -1,30 +1,28 @@
"use strict" "use strict"
import {availableSpeedProviders, currentSpeedProvider, registerModule, registerSystem, setCurrentSpeedProvider} from "./api.js" import {getRangesFromSpeedProvider, getUnreachableColorFromSpeedProvider, initApi, registerModule, registerSystem} from "./api.js"
import {getHexSizeSupportTokenGridCenter} from "./compatibility.js" import {getHexSizeSupportTokenGridCenter} from "./compatibility.js"
import {measure, moveTokens, onMouseMove} from "./foundry_imports.js" import {measure, moveTokens, onMouseMove} from "./foundry_imports.js"
import {registerSettings, settingsKey} from "./settings.js" import {registerSettings, settingsKey} from "./settings.js"
import {SpeedProvider} from "./speed_provider.js"
Hooks.once("init", () => { Hooks.once("init", () => {
registerSettings() registerSettings()
initApi()
hookTokenDragHandlers() hookTokenDragHandlers()
hookRulerFunctions() hookRulerFunctions()
hookKeyboardManagerFunctions() hookKeyboardManagerFunctions()
patchRulerHighlightMeasurement() patchRulerHighlightMeasurement()
availableSpeedProviders["native"] = nativeSpeedProvider
setCurrentSpeedProvider(nativeSpeedProvider)
window.dragRuler = { window.dragRuler = {
getColorForDistance, getColorForDistance,
registerModule, registerModule,
registerSystem registerSystem,
} }
}) })
Hooks.once("ready", () => { Hooks.once("ready", () => {
Hooks.callAll("dragRuler.ready") Hooks.callAll("dragRuler.ready", SpeedProvider)
}) })
Hooks.on("canvasReady", () => { Hooks.on("canvasReady", () => {
@@ -241,21 +239,6 @@ function strInsertAfter(haystack, needle, strToInsert) {
return haystack.slice(0, pos) + strToInsert + haystack.slice(pos) return haystack.slice(0, pos) + strToInsert + haystack.slice(pos)
} }
function nativeSpeedProvider(token, playercolor) {
const speedAttribute = game.settings.get(settingsKey, "speedAttribute")
if (!speedAttribute)
return []
const tokenSpeed = getProperty(token, speedAttribute)
if (tokenSpeed === undefined) {
console.warn(`Drag Ruler | The configured token speed attribute "${speedAttribute}" didn't return a speed value. To use colors based on drag distance set the setting to the correct value (or clear the box to disable this feature).`)
return []
}
const dashMultiplier = game.settings.get(settingsKey, "dashMultiplier")
if (!dashMultiplier)
return [{range: tokenSpeed, color: playercolor}]
return [{range: tokenSpeed, color: playercolor}, {range: tokenSpeed * dashMultiplier, color: 0xFFFF00}]
}
export function getColorForDistance(startDistance, subDistance=0) { export function getColorForDistance(startDistance, subDistance=0) {
if (!this.isDragRuler) if (!this.isDragRuler)
return this.color return this.color
@@ -266,15 +249,14 @@ export function getColorForDistance(startDistance, subDistance=0) {
return this.color return this.color
} }
const distance = startDistance + subDistance const distance = startDistance + subDistance
const firstColor = game.settings.get(settingsKey, "staticFirstColor") ? 0x00FF00 : this.color const ranges = getRangesFromSpeedProvider(this.draggedToken)
const ranges = currentSpeedProvider(this.draggedToken, firstColor)
if (ranges.length === 0) if (ranges.length === 0)
return this.color return this.color
const currentRange = ranges.reduce((minRange, currentRange) => { const currentRange = ranges.reduce((minRange, currentRange) => {
if (distance <= currentRange.range && currentRange.range < minRange.range) if (distance <= currentRange.range && currentRange.range < minRange.range)
return currentRange return currentRange
return minRange return minRange
}, {range: Infinity, color: 0xFF0000}) }, {range: Infinity, color: getUnreachableColorFromSpeedProvider()})
return currentRange.color return currentRange.color
} }
+181 -34
View File
@@ -1,5 +1,5 @@
import {updateSpeedProvider} from "./api.js"; import {availableSpeedProviders, getDefaultSpeedProvider, updateSpeedProvider} from "./api.js";
import {getDefaultDashMultiplier, getDefaultSpeedAttribute} from "./systems.js" import {SpeedProvider} from "./speed_provider.js"
export const settingsKey = "drag-ruler"; export const settingsKey = "drag-ruler";
@@ -24,42 +24,189 @@ export function registerSettings() {
// This setting will be modified by the api if modules register to it // This setting will be modified by the api if modules register to it
game.settings.register(settingsKey, "speedProvider", { game.settings.register(settingsKey, "speedProvider", {
name: "drag-ruler.settings.speedProvider.name",
hint: "drag-ruler.settings.speedProvider.hint",
scope: "world", scope: "world",
config: false, config: false,
type: Object, type: String,
choices: { default: getDefaultSpeedProvider(),
"native": game.i18n.localize("drag-ruler.settings.speedProvider.choices.native")
},
default: "native",
onChange: updateSpeedProvider, onChange: updateSpeedProvider,
}) })
game.settings.register(settingsKey, "speedAttribute", { game.settings.registerMenu(settingsKey, "speedProviderSettings", {
name: "drag-ruler.settings.speedAttribute.name", name: "drag-ruler.settings.speedProviderSettings.name",
hint: "drag-ruler.settings.speedAttribute.hint", hint: "drag-ruler.settings.speedProviderSettings.hint",
scope: "world", label: "drag-ruler.settings.speedProviderSettings.button",
config: true, icon: "fas fa-tachometer-alt",
type: String, type: SpeedProviderSettings,
default: getDefaultSpeedAttribute(), restricted: false,
})
game.settings.register(settingsKey, "dashMultiplier", {
name: "drag-ruler.settings.dashMultiplier.name",
hint: "drag-ruler.settings.dashMultiplier.hint",
scope: "world",
config: true,
type: Number,
default: getDefaultDashMultiplier(),
})
game.settings.register(settingsKey, "staticFirstColor", {
name: "drag-ruler.settings.staticFirstColor.name",
hint: "drag-ruler.settings.staticFirstColor.hint",
scope: "world",
config: true,
type: Boolean,
default: false,
}) })
} }
class SpeedProviderSettings extends FormApplication {
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
id: "drag-ruler-speed-provider-settings",
title: game.i18n.localize("drag-ruler.settings.speedProviderSettings.windowTitle"),
template: "modules/drag-ruler/templates/speed_provider_settings.html",
width: 600,
})
}
getData(options={}) {
const data = {}
data.isGM = game.user.isGM
const selectedProvider = game.settings.get(settingsKey, "speedProvider")
// Insert all speed providers into the template data
data.providers = Object.values(availableSpeedProviders).map(speedProvider => {
const provider = {}
provider.id = speedProvider.id
provider.hasSettings = speedProvider instanceof SpeedProvider
if (provider.hasSettings)
provider.settings = enumerateProviderSettings(speedProvider)
let dotPosition = provider.id.indexOf(".")
if (dotPosition === -1)
dotPosition = provider.id.length
const type = provider.id.substring(0, dotPosition)
const id = provider.id.substring(dotPosition + 1)
if (type === "native") {
provider.selectTitle = game.i18n.localize("drag-ruler.settings.speedProviderSettings.speedProvider.choices.native")
}
else {
let name
if (type === "module") {
name = game.modules.get(id).data.title
}
else {
name = game.system.data.title
}
provider.selectTitle = game.i18n.format(`drag-ruler.settings.speedProviderSettings.speedProvider.choices.${type}`, {name})
}
provider.isSelected = provider.id === selectedProvider
return provider
})
data.selectedProviderName = data.providers.find(provider => provider.isSelected).selectTitle
data.providerSelection = {
id: "speedProvider",
name: game.i18n.localize("drag-ruler.settings.speedProviderSettings.speedProvider.name"),
hint: game.i18n.localize("drag-ruler.settings.speedProviderSettings.speedProvider.hint"),
type: String,
choices: data.providers.reduce((choices, provider) => {
choices[provider.id] = provider.selectTitle
return choices
}, {}),
value: selectedProvider,
isCheckbox: false,
isSelect: true,
isRange: false,
}
return data
}
async _updateObject(event, formData) {
for (let [key, value] of Object.entries(formData)) {
// Check if this is color, convert the value to an integer
const splitKey = key.split(".", 3)
if (splitKey[0] !== "native")
splitKey.shift()
if (splitKey.length >= 2 && splitKey[1] == "color") {
value = parseInt(value.substring(1), 16)
}
// Don't change settings for speed providers that aren't currently active
if (key !== "speedProvider" && !key.startsWith(formData.speedProvider))
continue
// Get the key for the current setting
let setting
if (key === "speedProvider")
setting = "speedProvider"
else
setting = `speedProviders.${key}`
// Get the old setting value
const oldValue = game.settings.get(settingsKey, setting)
// Only update the setting if it has been changed (this leaves the default in place if it hasn't been touched)
if (value !== oldValue)
game.settings.set(settingsKey, setting, value)
}
// Activate the configured speed provider
updateSpeedProvider()
}
activateListeners(html) {
super.activateListeners(html)
html.find("select[name=speedProvider]").change(this.onSpeedProviderChange.bind(this))
}
onSpeedProviderChange(event) {
// Hide all module settings
document.querySelectorAll(".drag-ruler-provider-settings").forEach(element => element.style.display = "none")
// Show the settings block for the currently selected module
document.getElementById(`drag-ruler.provider.${event.currentTarget.value}`).style.display = ""
// Recalculate window height
this.element[0].style.height = null
this.position.height = undefined
}
}
function toDomHex(value) {
const hex = value.toString(16)
return "#" + "0".repeat(Math.max(0, 6 - hex.length)) + hex
}
function enumerateProviderSettings(provider) {
const colorSettings = []
const unreachableColor = {id: "unreachable", name: "drag-ruler.settings.speedProviderSettings.color.unreachable.name"}
// Resolve settings for the colors
for (const color of provider.colors.concat([unreachableColor])) {
// Localize the name, if avaliable. If no name is available use the id as name
const colorName = color.name ? game.i18n.localize(color.name) : color.id
let hint
if (color === unreachableColor)
hint = game.i18n.localize("drag-ruler.settings.speedProviderSettings.color.unreachable.hint")
else
hint = game.i18n.format("drag-ruler.settings.speedProviderSettings.color.hint", {colorName})
colorSettings.push({
id: `${provider.id}.color.${color.id}`,
name: game.i18n.format("drag-ruler.settings.speedProviderSettings.color.name", {colorName}),
hint: hint,
type: Number,
value: toDomHex(game.settings.get(settingsKey, `speedProviders.${provider.id}.color.${color.id}`)),
isCheckbox: false,
isSelect: false,
isRange: false,
isColor: true,
})
}
// Prepare regular settings
const settings = []
for (const setting of provider.settings) {
try {
if (setting.scope === "world" && !game.user.isGM)
continue
const s = duplicate(setting)
s.id = `${provider.id}.setting.${s.id}`
s.name = game.i18n.localize(s.name)
s.hint = game.i18n.localize(s.hint)
s.value = provider.getSetting(setting.id)
s.type = setting.type instanceof Function ? setting.type.name : "String"
s.isCheckbox = setting.type === Boolean
s.isSelect = s.choices !== undefined
s.isRange = (setting.type === Number) && s.range
s.isColor = false
settings.push(s)
}
catch (e) {
console.warn(`Drag Ruler | The following error occured while rendering setting "${setting.id}" of module/system "${this.id}. It won't be displayed.`)
console.error(e)
}
}
return settings.concat(colorSettings)
}
+132
View File
@@ -0,0 +1,132 @@
import {settingsKey} from "./settings.js"
import {getDefaultDashMultiplier, getDefaultSpeedAttribute} from "./systems.js"
/**
* Base class for all speed providers.
* If you want to offer a speed provider in your system/module you must derive this class.
* Each speed provider must at least implement
*/
export class SpeedProvider {
/**
* Returns an array of colors used by this speed provider. Each color corresponds to one speed that a token may have.
* Each color must be an object with the following properties:
* - id: A value that identfies the color. Must be unique for each color returned.
* - default: The color that is used to highlight that speed by default.
* - name: A user readable name for the speed represented by the color. This name is used in the color configuration dialog. Drag Ruler will attempt to localize this string using `game.i18n`
*
* Of these properties, id and defaultColor are required. name is optional, but it's recommended to set it
*
* Implementing this method is required for all speed providers
*/
get colors() {
throw new Error("A SpeedProvider must implement the colors function")
}
/**
* Returns an array of speeds that the token passed in the arguments this token can reach.
* Each range is an object that with the following properties:
* - range: A number indicating the distance that the token can travel with this speed
* - color: The id (as defined in the `colors` getter) of the color that should be used to represent this range
*
* Implementing this method is required for all speed providers
*/
getRanges(token) {
throw new Error("A SpeedProvider must implement the getRanges function")
}
/**
* Returns an array of configuration options for this module. The settings will be shown in the Speed Provider Settings of Drag Ruler.
* Each configuration option is an object that has the same attributes as a native foundry setting passed to `game.settings.register`,
* except for these exceptions:
* - id: A string that identifies the setting. Must be unique for each setting returned. This id will be used to fetch the setting.
* - config: This property is not supported by Drag Ruler module settings. Use foundries native settings instead if you need settings that don't show up in the configuration dialog.
*
* Implementing this method is optional and only needs to be done if you want to provide custom provider settings
*/
get settings() {
return []
}
/**
* Returns the default color for ranges that a token cannot reach.
*
* Implementing this method is optional and only needs to be done if you want to provide a custom default for that color.
*/
get defaultUnreachableColor() {
return 0xFF0000
}
/**
* Returns the value that is currently set for the setting registered with the provided settingId.
*
* This function shouldn't be overridden by speed provider implementations. It can be called to fetch speed provider specific settings.
*/
getSetting(settingId) {
try {
return game.settings.get(settingsKey, `speedProviders.${this.id}.setting.${settingId}`)
}
catch (e) {
if (this.settings.some(setting => setting.id === settingId)) {
throw e
}
throw new Error(`Drag Ruler | "${settingId}" is not a registered setting for "${this.id}". If you're the module/system developer, please add it to the return values of your Speed Providers "get settings()" function.`)
}
}
/**
* Constructs a new instance of he speed provider
*
* This function should neither be called or overridden by speed provider implementations
*/
constructor(id) {
this.id = id
}
}
export class GenericSpeedProvider extends SpeedProvider {
get colors() {
return [
{id: "walk", default: 0x00FF00, name: "drag-ruler.genericSpeedProvider.speeds.walk"},
{id: "dash", default: 0xFFFF00, name: "drag-ruler.genericSpeedProvider.speeds.dash"}
]
}
getRanges(token) {
const speedAttribute = this.getSetting("speedAttribute")
if (!speedAttribute)
return []
const tokenSpeed = getProperty(token, speedAttribute)
if (tokenSpeed === undefined) {
console.warn(`Drag Ruler (Generic Speed Provider) | The configured token speed attribute "${speedAttribute}" didn't return a speed value. To use colors based on drag distance set the setting to the correct value (or clear the box to disable this feature).`)
return []
}
const dashMultiplier = this.getSetting("dashMultiplier")
if (!dashMultiplier)
return [{range: tokenSpeed, color: playercolor}]
return [{range: tokenSpeed, color: "walk"}, {range: tokenSpeed * dashMultiplier, color: "dash"}]
}
get settings() {
return [
{
id: "speedAttribute",
name: "drag-ruler.genericSpeedProvider.settings.speedAttribute.name",
hint: "drag-ruler.genericSpeedProvider.settings.speedAttribute.hint",
scope: "world",
config: true,
type: String,
default: getDefaultSpeedAttribute(),
},
{
id: "dashMultiplier",
name: "drag-ruler.genericSpeedProvider.settings.dashMultiplier.name",
hint: "drag-ruler.genericSpeedProvider.settings.dashMultiplier.hint",
scope: "world",
config: true,
type: Number,
default: getDefaultDashMultiplier(),
}
]
}
}
+63
View File
@@ -0,0 +1,63 @@
{{! This partial is based on the foundry settings partial}}
{{#*inline "settingPartial"}}
<div class="form-group">
<label>{{this.name}}</label>
<div class="form-fields">
{{#if this.isCheckbox}}
<input type="checkbox" name="{{this.id}}" data-dtype="Boolean" {{checked this.value}} />
{{else if this.isSelect}}
<select name="{{this.id}}">
{{#select this.value}}
{{#each this.choices as |name k|}}
<option value="{{k}}">{{localize name}}</option>
{{/each}}
{{/select}}
</select>
{{else if this.isRange}}
<input type="range" name="{{this.id}}" data-dtype="Number" value="{{ this.value }}"
min="{{ this.range.min }}" max="{{ this.range.max }}" step="{{ this.range.step }}" />
<span class="range-value">{{this.value}}</span>
{{else if this.isColor}}
<input type="color" name="{{this.id}}" value="{{this.value}}" data-dtype="{{this.type}}" />
{{else}}
<input type="text" name="{{this.id}}" value="{{this.value}}" data-dtype="{{this.type}}" />
{{/if}}
</div>
<p class="notes">{{this.hint}}</p>
</div>
{{/inline}}
<form class="flexcol" autocomplete="off">
<section class="content">
<div class="settings-list">
<h2 class="module-header">{{localize "drag-ruler.settings.speedProviderSettings.headers.speedProvider"}}</h2>
{{#if this.isGM}}
{{#with this.providerSelection}}
{{> settingPartial}}
{{/with}}
{{else}}
<div class="form-group"><label>{{localize "drag-ruler.settings.speedProviderSettings.activeProvider.name"}}</label><div class="form-fields" style="justify-content: flex-start;"><b>{{this.selectedProviderName}}</b></div></div>
<p class="notes">{{localize "drag-ruler.settings.speedProviderSettings.activeProvider.hint"}}</p>
{{/if}}
<h2 class="module-header">{{localize "drag-ruler.settings.speedProviderSettings.headers.speedProviderSettings"}}</h2>
{{#each this.providers}}
<div class="drag-ruler-provider-settings" id="drag-ruler.provider.{{this.id}}" {{#unless this.isSelected}}style="display:none"{{/unless}}>
{{#if this.hasSettings}}
{{#each settings}}
{{> settingPartial}}
{{/each}}
{{else}}
<p>{{localize "drag-ruler.settings.speedProviderSettings.noSettings"}}</p>
{{/if}}
</div>
{{/each}}
</section>
<footer class="sheet-footer flexrow">
<button type="submit" name="submit">
<i class="far fa-save"></i> {{localize 'SETTINGS.Save'}}
</button>
</footer>
</form>