Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(FillStyle): Add controls for fill color and opacity for shapes #693

Merged
merged 30 commits into from
Aug 23, 2019
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
8d7a230
feat(fillstyle): add fill color/opacity controls
kwilson-bits Jul 19, 2019
7c75aa4
fix(fillstyle): fix how events are dispatched
kwilson-bits Jul 26, 2019
9108dbd
fix(fillstyle): fixes from code review
kwilson-bits Jul 26, 2019
fb122c6
fix(fillstyle): lint fix
kwilson-bits Jul 26, 2019
5700858
fix(fillstyle): consolidate multiple command files into fewer files
kwilson-bits Aug 6, 2019
c9db84c
fix(kml): export fill/stroke colors correctly for lines and polygons
Aug 6, 2019
7e4f07c
fix(fillstyle): hide the fill controls for points and lines
kwilson-bits Aug 7, 2019
a819e1d
fix(fillstyle): using existing functions for geometry checks
kwilson-bits Aug 12, 2019
bf5a9a7
fix(kml): reuse existing event and fix plugin creep into os
Aug 13, 2019
cc8e20d
test(feature): add tests for os.feature.getColor
Aug 13, 2019
d0e9016
fix(fillstyle): improvements from code review
kwilson-bits Aug 14, 2019
55bf63a
fix(fillstyle): code review, combine Feature command calls
kwilson-bits Aug 15, 2019
d65709f
fix(fillstyle): lint/compile fixes
kwilson-bits Aug 15, 2019
de6e81c
fix(fillstyle): fix upgrade, undo, and reset issues
kwilson-bits Aug 16, 2019
9494c11
fix(fillstyle): fix recursion headache with fill color
kwilson-bits Aug 16, 2019
ac95f63
refactor(style): remove user-facing references to stroke color/opacity
Aug 16, 2019
09c2e27
fix(fa): match fill color to base color when loading old feature actions
Aug 16, 2019
5d2e71f
fix(fill): reset fill opacity on command undo
Aug 17, 2019
f25409b
fix(fill): default KML fill color/opacity appropriately
Aug 17, 2019
73cf6d0
fix(fill): unlink opacity and fill opacity sliders
Aug 17, 2019
cfaef24
fix(color): fixed an error when the color picker was given an array
Aug 17, 2019
c2cade2
fix(label): revert label color when it matches feature color
Aug 19, 2019
8a8c847
fix(places): persist labels when quick adding places
Aug 19, 2019
0390ffd
Merge branch 'master' into 531-shape-fill-controls
Aug 19, 2019
7e32198
fix(places): unlink opacity/fill opacity sliders
Aug 19, 2019
d2bce3f
fix(places): ignore opacity when comparing color/label color
Aug 19, 2019
483da54
fix(opacity): revert to using layer opacity
Aug 19, 2019
60e997e
fix(state): remove fill opacity case
Aug 20, 2019
da62879
Merge branch 'master' into 531-shape-fill-controls
Aug 20, 2019
4905bf2
fix(style): use correct default image fill color
Aug 20, 2019
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
4 changes: 3 additions & 1 deletion src/os/command/feature/abstractfeaturestylecmd.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
goog.provide('os.command.AbstractFeatureStyle');

goog.require('goog.events.Event');
goog.require('os.action.EventType');
goog.require('os.command.AbstractStyle');
goog.require('os.command.ICommand');
goog.require('os.command.State');
Expand Down Expand Up @@ -67,7 +69,7 @@ os.command.AbstractFeatureStyle.prototype.applyValue = function(configs, value)
* @inheritDoc
*/
os.command.AbstractFeatureStyle.prototype.finish = function(configs) {
os.dispatcher.dispatchEvent(new goog.events.Event(plugin.file.kml.KMLNodeLayerUICtrl.UIEventType.REFRESH));
os.dispatcher.dispatchEvent(new goog.events.Event(os.action.EventType.REFRESH));
var feature = /** @type {ol.Feature} */ (this.getFeature());
var layer = os.MapContainer.getInstance().getLayer(this.layerId);
goog.asserts.assert(layer, 'layer must be defined');
Expand Down
116 changes: 98 additions & 18 deletions src/os/command/feature/featurecolorcmd.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
goog.provide('os.command.FeatureColor');

goog.require('os.command.AbstractFeatureStyle');
goog.require('os.command.style');
goog.require('os.events.PropertyChangeEvent');
goog.require('os.metrics');
goog.require('os.style');



Expand All @@ -13,13 +15,39 @@ goog.require('os.metrics');
* @param {string} layerId
* @param {string} featureId
* @param {Array<number>|string} color
* @param {(Array<number>|string)=} opt_oldColor
* @param {(Array<number>|string|null)=} opt_oldColor
* @param {os.command.style.ColorChangeType=} opt_changeMode
* @constructor
*/
os.command.FeatureColor = function(layerId, featureId, color, opt_oldColor) {
os.command.FeatureColor = function(layerId, featureId, color, opt_oldColor, opt_changeMode) {
/**
* The color change mode. Determines how the config color is set.
* @type {os.command.style.ColorChangeType}
* @protected
*/
this.changeMode = opt_changeMode || os.command.style.ColorChangeType.COMBINED;

// intentionally called after changeMode is set so getOldValue has the correct value
os.command.FeatureColor.base(this, 'constructor', layerId, featureId, color, opt_oldColor);
this.title = 'Change Feature Color';
this.metricKey = os.metrics.Layer.FEATURE_COLOR;

switch (this.changeMode) {
case os.command.style.ColorChangeType.FILL:
this.title = 'Change Feature Fill Color';
this.metricKey = os.metrics.Layer.FEATURE_FILL_COLOR;
this.defaultColor = os.command.FeatureColor.DEFAULT_FILL_COLOR;
break;
case os.command.style.ColorChangeType.STROKE:
this.title = 'Change Feature Color';
this.metricKey = os.metrics.Layer.FEATURE_COLOR;
this.defaultColor = os.command.FeatureColor.DEFAULT_COLOR;
break;
case os.command.style.ColorChangeType.COMBINED:
default:
this.title = 'Change Feature Color';
this.metricKey = os.metrics.Layer.FEATURE_COLOR;
this.defaultColor = os.command.FeatureColor.DEFAULT_COLOR;
break;
}

if (!color) {
var feature = /** @type {ol.Feature} */ (this.getFeature());
Expand Down Expand Up @@ -49,6 +77,13 @@ goog.inherits(os.command.FeatureColor, os.command.AbstractFeatureStyle);
os.command.FeatureColor.DEFAULT_COLOR = 'rgba(255,255,255,1)';


/**
* @type {string}
* @const
*/
os.command.FeatureColor.DEFAULT_FILL_COLOR = 'rgba(255,255,255,0)';


/**
* @inheritDoc
*/
Expand All @@ -59,14 +94,31 @@ os.command.FeatureColor.prototype.getOldValue = function() {
config = config[0];
}

return config ? os.style.getConfigColor(config) : os.command.FeatureColor.DEFAULT_COLOR;
var ret = this.defaultColor;

if (config) {
switch (this.changeMode) {
case os.command.style.ColorChangeType.FILL:
ret = os.style.getConfigColor(config, false, os.style.StyleField.FILL);
break;
case os.command.style.ColorChangeType.STROKE:
ret = os.style.getConfigColor(config, false, os.style.StyleField.STROKE);
break;
case os.command.style.ColorChangeType.COMBINED:
default:
ret = os.style.getConfigColor(config);
break;
}
}

return ret;
};


/**
* Gets the old label color
*
* @return {Array<number>|string|undefined}
* @return {Array<number>|string}
*/
os.command.FeatureColor.prototype.getLabelValue = function() {
var feature = /** @type {ol.Feature} */ (this.getFeature());
Expand All @@ -80,13 +132,46 @@ os.command.FeatureColor.prototype.getLabelValue = function() {
*/
os.command.FeatureColor.prototype.applyValue = function(configs, value) {
var color = os.style.toRgbaString(/** @type {string} */ (value));
for (var i = 0; i < configs.length; i++) {
os.style.setConfigColor(configs[i], color);
}

if (this.oldValue == this.getLabelValue()) {
this.applyLabelValue(configs, value);
// ignore opacity when comparing the label color to the current color
var labelColor = os.color.toHexString(this.getLabelValue());
var currentColor = os.color.toHexString(this.state === os.command.State.EXECUTING ? this.oldValue : this.value);

switch (this.changeMode) {
case os.command.style.ColorChangeType.FILL:
for (var i = 0; i < configs.length; i++) {
os.style.setFillColor(configs[i], color);
}
break;
case os.command.style.ColorChangeType.STROKE:
for (var i = 0; i < configs.length; i++) {
var fillColor = os.style.getConfigColor(configs[i], true, os.style.StyleField.FILL);

os.style.setConfigColor(configs[i], color);

if (fillColor) {
os.style.setFillColor(configs[i], fillColor);
}
}

// if the label color matches the style color, change it as well
if (labelColor == currentColor) {
this.applyLabelValue(configs, color);
}
break;
case os.command.style.ColorChangeType.COMBINED:
default:
for (var i = 0; i < configs.length; i++) {
os.style.setConfigColor(configs[i], color);
}

// if the label color matches the style color, change it as well
if (labelColor == currentColor) {
this.applyLabelValue(configs, color);
}
break;
}

os.command.FeatureColor.base(this, 'applyValue', configs, value);
};

Expand All @@ -112,14 +197,9 @@ os.command.FeatureColor.prototype.applyLabelValue = function(configs, value) {
*/
os.command.FeatureColor.prototype.finish = function(configs) {
// dispatch the color change event on the source for the histogram
var feature = /** @type {ol.Feature} */ (this.getFeature());
var source = /** @type {plugin.file.kml.KMLSource} */ (os.feature.getSource(feature));
var rootNode = source.getRootNode();
var children = rootNode.getChildren();
var feature = this.getFeature();

for (var i = 0; i < children.length; i++) { // update icon color
children[i].dispatchEvent(new os.events.PropertyChangeEvent('icons'));
}
feature.dispatchEvent(new os.events.PropertyChangeEvent('colors'));

os.command.FeatureColor.base(this, 'finish', configs);
};
142 changes: 114 additions & 28 deletions src/os/command/feature/featureopacitycmd.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
goog.provide('os.command.FeatureOpacity');

goog.require('goog.asserts');
goog.require('os.command.AbstractFeatureStyle');
goog.require('os.command.style');
goog.require('os.events.PropertyChangeEvent');
goog.require('os.metrics');
goog.require('os.ui');
goog.require('os.style');



Expand All @@ -13,59 +16,142 @@ goog.require('os.ui');
* @param {string} layerId
* @param {string} featureId
* @param {number} opacity
* @param {number=} opt_oldOpacity
* @param {number|null=} opt_oldOpacity
* @param {os.command.style.ColorChangeType=} opt_changeMode
* @constructor
*/
os.command.FeatureOpacity = function(layerId, featureId, opacity, opt_oldOpacity) {
os.command.FeatureOpacity.base(this, 'constructor', layerId, featureId, opacity, opt_oldOpacity);
this.title = 'Change Feature Opacity';
this.metricKey = os.metrics.Layer.FEATURE_OPACITY;
os.command.FeatureOpacity = function(layerId, featureId, opacity, opt_oldOpacity, opt_changeMode) {
goog.asserts.assert(opacity != null, 'opacity must be defined');

if (!opacity) {
var feature = /** @type {ol.Feature} */ (this.getFeature());
var config = /** @type {Object|undefined} */ (feature.get(os.style.StyleType.FEATURE));
/**
* The opacity change mode. Determines how the config opacity is set.
* @type {os.command.style.ColorChangeType}
* @protected
*/
this.changeMode = opt_changeMode || os.command.style.ColorChangeType.COMBINED;

if (config) {
if (goog.isArray(config)) {
config = config[0];
}
opacity = /** @type {number} */ (os.style.getConfigOpacityColor(config));
}
}
// intentionally called after changeMode is set so getOldValue has the correct value
os.command.FeatureOpacity.base(this, 'constructor', layerId, featureId, opacity, opt_oldOpacity);

this.value = opacity;
switch (this.changeMode) {
case os.command.style.ColorChangeType.FILL:
this.title = 'Change Feature Fill Opacity';
this.metricKey = os.metrics.Layer.FEATURE_FILL_OPACITY;
break;
case os.command.style.ColorChangeType.STROKE:
this.title = 'Change Feature Opacity';
this.metricKey = os.metrics.Layer.FEATURE_OPACITY;
break;
case os.command.style.ColorChangeType.COMBINED:
default:
this.title = 'Change Feature Opacity';
this.metricKey = os.metrics.Layer.FEATURE_OPACITY;
break;
}
};
goog.inherits(os.command.FeatureOpacity, os.command.AbstractFeatureStyle);


/**
* @type {number}
* @const
*/
os.command.FeatureOpacity.DEFAULT_OPACITY = 1;


/**
* @inheritDoc
*/
os.command.FeatureOpacity.prototype.getOldValue = function() {
var ret;
var feature = /** @type {ol.Feature} */ (this.getFeature());
var config = /** @type {Array<Object>|Object|undefined} */ (this.getFeatureConfigs(feature));
if (goog.isArray(config)) {
if (Array.isArray(config)) {
config = config[0];
}

return config ? os.style.getConfigOpacityColor(config) : os.command.FeatureOpacity.DEFAULT_OPACITY;
if (config) {
var color;
switch (this.changeMode) {
case os.command.style.ColorChangeType.FILL:
color = os.style.getConfigColor(config, true, os.style.StyleField.FILL);
ret = color && color.length === 4 ? color[3] : os.style.DEFAULT_FILL_ALPHA;
break;
case os.command.style.ColorChangeType.STROKE:
color = os.style.getConfigColor(config, true, os.style.StyleField.STROKE);
ret = color && color.length === 4 ? color[3] : os.style.DEFAULT_ALPHA;
break;
case os.command.style.ColorChangeType.COMBINED:
default:
color = os.style.getConfigColor(config, true);
ret = color && color.length === 4 ? color[3] : os.style.DEFAULT_ALPHA;
break;
}
}

return ret;
};


/**
* @inheritDoc
*/
os.command.FeatureOpacity.prototype.applyValue = function(configs, value) {
for (var i = 0; i < configs.length; i++) {
os.style.setConfigOpacityColor(configs[i], value);
var color;
var colorValue;
var i;

switch (this.changeMode) {
case os.command.style.ColorChangeType.FILL:
for (i = 0; i < configs.length; i++) {
color = os.style.getConfigColor(configs[i], true, os.style.StyleField.FILL) ||
os.style.getConfigColor(configs[i], true);

if (color) {
color[3] = value;
colorValue = os.style.toRgbaString(color);
os.style.setFillColor(configs[i], colorValue);
}
}
break;
case os.command.style.ColorChangeType.STROKE:
for (i = 0; i < configs.length; i++) {
color = os.style.getConfigColor(configs[i], true, os.style.StyleField.STROKE) ||
os.style.getConfigColor(configs[i], true);

if (color) {
var fillColor = os.style.getConfigColor(configs[i], true, os.style.StyleField.FILL);

color[3] = value;
colorValue = os.style.toRgbaString(color);
os.style.setConfigColor(configs[i], colorValue);

// preserve the original fill color when changing the stroke
if (fillColor) {
os.style.setFillColor(configs[i], fillColor);
}
}
}
break;
case os.command.style.ColorChangeType.COMBINED:
default:
for (i = 0; i < configs.length; i++) {
color = os.style.getConfigColor(configs[i], true);

if (color) {
color[3] = value;
colorValue = os.style.toRgbaString(color);
os.style.setConfigColor(configs[i], colorValue);
}
}
break;
}

os.command.FeatureOpacity.base(this, 'applyValue', configs, value);
};


/**
* @inheritDoc
*/
os.command.FeatureOpacity.prototype.finish = function(configs) {
// dispatch the color change event on the source for the histogram
var feature = this.getFeature();

feature.dispatchEvent(new os.events.PropertyChangeEvent('colors'));

os.command.FeatureOpacity.base(this, 'finish', configs);
};
12 changes: 12 additions & 0 deletions src/os/command/stylecommand.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
goog.provide('os.command.style');


/**
* Change types for color commands. Determines how color/opacity is set in style configs.
* @enum {string}
*/
os.command.style.ColorChangeType = {
COMBINED: 'combined',
FILL: 'fill',
STROKE: 'stroke'
};
Loading