Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ IMPORTANT NOTE: This version only works on CACTI 1.x++!
* issue#322: Refresh the bundled manual with current installation, upgrade, editor, image management and troubleshooting guides; retain the configuration and data-source references and repair documentation links
* issue#322: Update editor and map-management screenshots, including map creation, management, the viewer, hover graphs and Advanced settings; use compact previews with full-size links and refresh cached documentation assets
* feature#322: Add themed Docs access from the map heading and a Docs button after Rebuild All in map management, opening the bundled manual in a new tab
* feature#321: Group default link width and appearance controls under Link Appearance Defaults in Map Style, and clarify Default Link Capacity in Map Properties
* feature#321: Add Edge and Centre comment styles to Map Style, with an individual override and Use map default option in Link Properties
* feature#321: Add IN/OUT traffic-label positions to Map Style and per-link Advanced settings, with 75%/25% defaults and an option to restore inheritance; keep traffic-label and comment positions separate

--- 2.0 ---

Expand Down
13 changes: 11 additions & 2 deletions js/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -1312,6 +1312,11 @@ function prime_link_form(name) {
$('#link_hover').val(wmDecodeEditorUrl(mylink.overliburl));
$('#viastyle').val(mylink.viastyle);

$('#link_commentstyle').val(mylink.commentstylechoice);
$('#link_labelposmode').val(mylink.labelposmode);
$('#link_labelposin').val(mylink.labelposin);
$('#link_labelposout').val(mylink.labelposout);
$('#link_labelposmode').trigger('change');
$('#link_commentin').val(mylink.commentin);
$('#link_commentout').val(mylink.commentout);
$('#link_commentposin').val(mylink.commentposin);
Expand Down Expand Up @@ -1768,6 +1773,9 @@ function wmBuildLinkSections() {
dlg.find(fields).closest('tr').appendTo(table);
return panel;
}
$('#link_labelposmode').on('change.wmPositions', function() {
$('#link_labelposin,#link_labelposout').prop('disabled', $(this).val() !== 'custom');
});
var hovers = group('wm-link-hovers', wmEditorText.additionalGraphs, '#link_template,#link_picker');
dlg.find('.wm-link-section p').addClass('wm-link-group-hint').prependTo(hovers);
dlg.find('.wm-link-section').remove();
Expand All @@ -1777,7 +1785,8 @@ function wmBuildLinkSections() {
wmRenderLinkExtraGraphs();
$('#link_target_picker_rep').remove();
var advanced = group('wm-link-advanced', wmEditorText.advanced,
'#link_target,#link_infourl,#wm-link-primary-hover,#wm-link-extra-hover', wmEditorText.linkAdvancedHint);
'#link_labelposmode,#link_target,#link_infourl,#wm-link-primary-hover,#wm-link-extra-hover', wmEditorText.linkAdvancedHint);
$('#link_labelposmode').closest('tr').prependTo(advanced.find('table'));
var sourceRow = $('<tr></tr>').insertBefore($('#link_target').closest('tr'));
$('<td></td>').text(wmEditorText.chooseSource).appendTo(sourceRow);
var sourceActions = $('<div class="wm-link-source-actions"></div>').appendTo($('<td></td>').appendTo(sourceRow))
Expand All @@ -1800,7 +1809,7 @@ function wmBuildLinkSections() {
++wmInterfaceLookupGeneration;
wmSyncLinkHoverParts();
});
dlg.find('#viastyle,#link_width,#link_commentin,#link_commentout').closest('tr')
dlg.find('#viastyle,#link_width,#link_commentin,#link_commentout,#link_commentstyle').closest('tr')
.insertAfter($('#link_target_picker').closest('tr'));
$('#link_edit').appendTo(controls);
var help = dlg.find('.dlgHelp').attr('id', 'wm-link-full-help').insertAfter(sections).hide();
Expand Down
14 changes: 11 additions & 3 deletions lib/WeatherMapLink.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,8 @@ function CopyFrom(&$source) {
$this->$fld = $source->$fld;
}
}
// These describe this link's explicit editor choices, not inherited settings.
unset($this->hints['editor_commentstyle_override'], $this->hints['editor_labelpos_override']);
}

/**
Expand Down Expand Up @@ -935,7 +937,7 @@ function WriteConfig() {
$keyword = $param[1];

// $output .= "# For $keyword: ".$this->$field." vs ".$dd->$field."\n";
if ($this->$field != $dd->$field) {
if ($this->$field != $dd->$field || ($field === 'commentstyle' && !empty($this->hints['editor_commentstyle_override']))) {
if ($param[2] == CONFIG_TYPE_COLOR) {
$output .= TAB . "$keyword " . render_colour($this->$field) . EOL;
} elseif ($param[2] == CONFIG_TYPE_LITERAL) {
Expand Down Expand Up @@ -1027,7 +1029,7 @@ function WriteConfig() {
$comparison = $dd->labeloffset_in;
$comparison2 = $dd->labeloffset_out;

if ($this->labeloffset_in != $comparison || $this->labeloffset_out != $comparison2) {
if ($this->labeloffset_in != $comparison || $this->labeloffset_out != $comparison2 || !empty($this->hints['editor_labelpos_override'])) {
$output .= TAB . 'BWLABELPOS ' . $this->labeloffset_in . ' ' . $this->labeloffset_out . EOL;
}

Expand Down Expand Up @@ -1107,7 +1109,7 @@ function WriteConfig() {
foreach ($this->hints as $hintname=>$hint) {
// all hints for DEFAULT node are for writing
// only changed ones, or unique ones, otherwise
if (($this->name == 'DEFAULT') || (isset($dd->hints[$hintname]) && $dd->hints[$hintname] != $hint) || (!isset($dd->hints[$hintname]))) {
if (in_array($hintname, ['editor_commentstyle_override', 'editor_labelpos_override'], true) || ($this->name == 'DEFAULT') || (isset($dd->hints[$hintname]) && $dd->hints[$hintname] != $hint) || (!isset($dd->hints[$hintname]))) {
$output .= TAB . "SET $hintname $hint" . EOL;
}
}
Expand Down Expand Up @@ -1157,6 +1159,12 @@ function asJS() {
$js .= 'overlibheight:"' . $this->overlibheight . '", ';
$js .= 'overlibcaption:' . js_escape($this->overlibcaption[IN]) . ', ';

$base = $this->owner->links[$this->template];
$customStyle = !empty($this->hints['editor_commentstyle_override']) || $this->commentstyle !== $base->commentstyle;
$customPositions = !empty($this->hints['editor_labelpos_override']) || $this->labeloffset_in != $base->labeloffset_in || $this->labeloffset_out != $base->labeloffset_out;
Comment thread
TheWitness marked this conversation as resolved.
Resolved
$js .= 'commentstylechoice:' . js_escape($customStyle ? $this->commentstyle : 'default') . ', ';
$js .= 'labelposmode:' . js_escape($customPositions ? 'custom' : 'default') . ', ';
$js .= 'labelposin:' . (float)$this->labeloffset_in . ', labelposout:' . (float)$this->labeloffset_out . ', ';
$js .= 'commentin:' . js_escape($this->comments[IN]) . ', ';
$js .= 'commentposin:' . intval($this->commentoffset_in) . ', ';

Expand Down
19 changes: 8 additions & 11 deletions lib/editor.actions.php
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,8 @@ function setLinkProperties($mapfile) {
$map->links[$link_name]->commentoffset_in = intval(get_nfilter_request_var('link_commentposin'));
$map->links[$link_name]->commentoffset_out = intval(get_nfilter_request_var('link_commentposout'));

wm_link_apply_overrides($map, $map->links[$link_name], get_nfilter_request_var('link_commentstyle'), get_nfilter_request_var('link_labelposmode'), get_nfilter_request_var('link_labelposin'), get_nfilter_request_var('link_labelposout'));

$targets = preg_split('/\s+/', trim(get_nfilter_request_var('link_target')), -1, PREG_SPLIT_NO_EMPTY) ?: [];
$new_target_list = [];

Expand Down Expand Up @@ -539,16 +541,6 @@ function setMapProperties($mapfile) {
}


$inheritables = [
['link', 'width', 'map_linkdefaultwidth', 'float']
];

handle_inheritance($map, $inheritables);

$map->links['DEFAULT']->width = intval(get_nfilter_request_var('map_linkdefaultwidth'));

$map->links['DEFAULT']->add_note('my_width', get_filter_request_var('map_linkdefaultwidth'));

$bwin = get_nfilter_request_var('map_linkdefaultbwin');
$bwout = get_nfilter_request_var('map_linkdefaultbwout');

Expand Down Expand Up @@ -621,8 +613,13 @@ function setMapStyle($mapfile) {

handle_inheritance($map, $inheritables);

$width = get_nfilter_request_var('mapstyle_defaultwidth');
if (is_scalar($width) && is_numeric($width) && (float)$width > 0 && is_finite((float)$width)) {
wm_comment_update_default($map, 'width', (float)$width);
}
wm_link_apply_default_positions($map, get_nfilter_request_var('mapstyle_labelposin'), get_nfilter_request_var('mapstyle_labelposout'));
wm_comment_update_default($map, 'bwfont', wm_comment_resolve_font($map, get_nfilter_request_var('mapstyle_linkfont')));
wm_comment_apply_style($map, get_nfilter_request_var('mapstyle_commentfont'), null, isset_request_var('mapstyle_commentcurve') ? get_nfilter_request_var('mapstyle_commentcurve') : '0');
wm_comment_apply_style($map, get_nfilter_request_var('mapstyle_commentfont'), null, isset_request_var('mapstyle_commentcurve') ? get_nfilter_request_var('mapstyle_commentcurve') : '0', get_nfilter_request_var('mapstyle_commentstyle'));

if (!wm_editor_write_config($map, $mapfile)) return;
}
Expand Down
113 changes: 111 additions & 2 deletions lib/editor.comment-style.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ function wm_style_font_select($map, $name, $current) {
return '<select class="fontcombo" name="' . html_escape($name) . '" id="' . html_escape($name) . '">' . wm_style_font_options($map, $current) . '</select>';
}
/**
* Render the link comment font control.
* Render the link comment font, placement and curve controls.
*
* @param WeatherMap $map
*
Expand All @@ -148,6 +148,11 @@ function wm_comment_style_fields($map) {
$out = '<tr><td><label for="mapstyle_commentfont">' . html_escape(__('Link Comment Font', 'weathermap')) . '</label></td><td><select class="fontcombo" name="mapstyle_commentfont" id="mapstyle_commentfont">';
$out .= wm_style_font_options($map, $current);
$out .= '</select></td></tr>';
$out .= '<tr><td><label for="mapstyle_commentstyle">' . html_escape(__('Link Comment Style', 'weathermap')) . '</label></td><td><select name="mapstyle_commentstyle" id="mapstyle_commentstyle">';
foreach (['edge' => __('Edge', 'weathermap'), 'center' => __('Centre', 'weathermap')] as $value => $label) {
$out .= '<option value="' . $value . '"' . ($map->links['DEFAULT']->commentstyle === $value ? ' selected' : '') . '>' . html_escape($label) . '</option>';
}
$out .= '</select><br><small>' . html_escape(__('Edge places comments beside the link; Centre places them over the arrow.', 'weathermap')) . '</small></td></tr>';

$out .= '<tr><td><label for="mapstyle_commentcurve">' . html_escape(__('Link Comments', 'weathermap')) . '</label></td><td><label><input type="checkbox" name="mapstyle_commentcurve" id="mapstyle_commentcurve" value="1"' . (!empty($map->links['DEFAULT']->commentcurve) ? ' checked' : '') . '> ' . html_escape(__('Follow link curve', 'weathermap')) . '</label><br><small>' . html_escape(__('Uses a TrueType font. Tight bends or text longer than the link use straight text.', 'weathermap')) . '</small></td></tr>';

Expand Down Expand Up @@ -235,6 +240,12 @@ function wm_comment_update_default($map, $field, $new) {
if ($new === null) {
return;
}
// New layout controls follow templates; retain established font/colour behaviour.
if (in_array($field, ['commentstyle', 'width'], true)) {
$marker = $field === 'commentstyle' ? 'editor_commentstyle_override' : null;
wm_link_propagate_defaults($map, [$field => $new], $marker);
return;
}
$old = $map->links['DEFAULT']->$field;

if ($new == $old) {
Expand All @@ -251,19 +262,117 @@ function wm_comment_update_default($map, $field, $new) {
}
}
}
/**
* Follow changed template relationships, comparing values before any mutation.
* Included templates and explicit overrides stop propagation down their branch.
*/
function wm_link_propagate_defaults($map, $values, $marker = null) {
$previous = [];
$children = [];
foreach ($map->links as $name => $link) {
$children[$link->template ?? 'DEFAULT'][] = $name;
foreach ($values as $field => $value) {
$previous[$name][$field] = $link->$field;
}
}
if ($previous['DEFAULT'] == $values) return;

$pending = ['DEFAULT'];
$changed = ['DEFAULT' => true];
for ($i = 0; $i < count($pending); $i++) {
$parent = $pending[$i];
foreach ($values as $field => $value) {
$map->links[$parent]->$field = $value;
}
foreach ($children[$parent] ?? [] as $name) {
$link = $map->links[$name];
$inherits = $previous[$name] == $previous[$parent] && ($marker === null || empty($link->hints[$marker]));
if (isset($changed[$name]) || $name === ':: DEFAULT ::' || $link->defined_in !== $map->configfile || !$inherits) continue;
$changed[$name] = true;
$pending[] = $name;
}
}
}

/**
* Apply validated link comment style defaults.
*
* @param WeatherMap $map
* @param mixed $font
* @param mixed $colour
* @param mixed $curve
* @param mixed $style
*
* @return void
*/
function wm_comment_apply_style($map, $font, $colour, $curve = null) {
function wm_comment_apply_style($map, $font, $colour, $curve = null, $style = null) {
if (in_array($style, ['edge', 'center'], true)) {
wm_comment_update_default($map, 'commentstyle', $style);
}
if ($curve === '0' || $curve === '1') {
wm_comment_update_default($map, 'commentcurve', (int)$curve);
}
wm_comment_update_default($map, 'commentfont', wm_comment_resolve_font($map, $font));
wm_comment_update_default($map, 'commentfontcolour', wm_comment_resolve_colour($colour));
}

/** Render the map-wide traffic-label positions. */
function wm_link_position_fields($map) {
$link = $map->links['DEFAULT'];
return '<tr><td>' . html_escape(__('Traffic Label Positions', 'weathermap')) . '</td><td>' . wm_link_position_inputs('mapstyle', $link->labeloffset_in, $link->labeloffset_out) . '<br><small>' . html_escape(__('Positions along the link: 0% is the first node and 100% is the second. These move the traffic labels, not the comments.', 'weathermap')) . '</small></td></tr>';
}

/** Render labelled IN/OUT percentage inputs without rounding custom values. */
function wm_link_position_inputs($prefix, $in, $out) {
$html = '';
foreach (['in' => $in, 'out' => $out] as $direction => $value) {
$id = $prefix . '_labelpos' . $direction;
$label = $direction === 'in' ? __('IN', 'weathermap') : __('OUT', 'weathermap');
$html .= '<label for="' . $id . '">' . html_escape($label) . '</label> <input class="ui-state-default ui-corner-all" type="number" min="0" max="100" step="1" name="' . $id . '" id="' . $id . '" value="' . (int)$value . '" style="width: 5em;">% ';
}
return $html;
}

/** Render per-link controls; the editor moves the position row into Advanced. */
function wm_link_override_fields() {
$html = '<tr><td><label for="link_commentstyle">' . html_escape(__('Comment Style', 'weathermap')) . '</label></td><td><select id="link_commentstyle" name="link_commentstyle">';
foreach (['default' => __('Use map default', 'weathermap'), 'edge' => __('Edge', 'weathermap'), 'center' => __('Centre', 'weathermap')] as $value => $label) {
$html .= '<option value="' . $value . '">' . html_escape($label) . '</option>';
}
$html .= '</select><br><small>' . html_escape(__('Edge places comments beside the link; Centre places them over the arrow.', 'weathermap')) . '</small></td></tr>';
$html .= '<tr><td><label for="link_labelposmode">' . html_escape(__('Traffic Label Positions', 'weathermap')) . '</label></td><td><select id="link_labelposmode" name="link_labelposmode"><option value="default">' . html_escape(__('Use map default', 'weathermap')) . '</option><option value="custom">' . html_escape(__('Custom positions', 'weathermap')) . '</option></select><br>' . wm_link_position_inputs('link', 75, 25) . '<br><small>' . html_escape(__('Positions along the link: 0% is the first node and 100% is the second. These move the traffic labels, not the comments.', 'weathermap')) . '</small></td></tr>';
return $html;
}

/** Only whole percentages accepted by BWLABELPOS are valid. */
function wm_link_valid_position($value) {
return (is_int($value) || is_string($value)) && preg_match('/^\d{1,3}$/D', (string)$value) && (int)$value <= 100;
}

/** Update matching root defaults as a pair, preserving custom or included links. */
function wm_link_apply_default_positions($map, $in, $out) {
if (!wm_link_valid_position($in) || !wm_link_valid_position($out)) return;
wm_link_propagate_defaults($map, ['labeloffset_in' => (int)$in, 'labeloffset_out' => (int)$out], 'editor_labelpos_override');
}

/** Apply validated per-link overrides, or restore the inherited template values. */
function wm_link_apply_overrides($map, $link, $style, $mode, $in, $out) {
// Named templates retain their inheritance when restoring defaults.
$base = $map->links[$link->template];
if ($style === 'default') {
$link->commentstyle = $base->commentstyle;
unset($link->hints['editor_commentstyle_override']);
} elseif (in_array($style, ['edge', 'center'], true)) {
$link->commentstyle = $style;
$link->add_hint('editor_commentstyle_override', '1');
}
if ($mode === 'default') {
$link->labeloffset_in = $base->labeloffset_in;
$link->labeloffset_out = $base->labeloffset_out;
unset($link->hints['editor_labelpos_override']);
} elseif ($mode === 'custom' && wm_link_valid_position($in) && wm_link_valid_position($out)) {
$link->labeloffset_in = (int)$in;
$link->labeloffset_out = (int)$out;
$link->add_hint('editor_labelpos_override', '1');
}
}
2 changes: 1 addition & 1 deletion lib/editor.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -1118,7 +1118,7 @@ function getEditorJs() {
'primarySource' => __('Primary source — use "Use interface" at the top to change', 'weathermap'),
'choosePrimaryFirst' => __('Choose the primary traffic interface in the main form first.', 'weathermap'),
'chooseSource' => __('Add additional traffic sources', 'weathermap'),
'linkAdvancedHint' => __('Custom sources and URLs override the automatic interface setup. Leave these unchanged for a normal traffic link.', 'weathermap'),
'linkAdvancedHint' => __('Adjust traffic label positions, or use custom sources and URLs. Leave sources and URLs unchanged for a normal traffic link.', 'weathermap'),
'customSourcesChanged' => __('Custom traffic sources changed. Save to apply. Hover graphs and click destination are unchanged.', 'weathermap'),
'extraUrlsHint' => __('One additional image URL maximum. This is the same preview managed under Additional hover graphs.', 'weathermap'),
'trafficSources' => __('Traffic sources', 'weathermap'),
Expand Down
Loading