summaryrefslogtreecommitdiff
path: root/addons/web/static/src
diff options
context:
space:
mode:
Diffstat (limited to 'addons/web/static/src')
-rw-r--r--addons/web/static/src/js/widgets/colorpicker.js78
-rw-r--r--addons/web/static/src/scss/colorpicker.scss68
-rw-r--r--addons/web/static/src/xml/colorpicker.xml60
3 files changed, 123 insertions, 83 deletions
diff --git a/addons/web/static/src/js/widgets/colorpicker.js b/addons/web/static/src/js/widgets/colorpicker.js
index 87a46e77a2f..6b17431259a 100644
--- a/addons/web/static/src/js/widgets/colorpicker.js
+++ b/addons/web/static/src/js/widgets/colorpicker.js
@@ -12,6 +12,8 @@ var ColorpickerWidget = Widget.extend({
xmlDependencies: ['/web/static/src/xml/colorpicker.xml'],
template: 'Colorpicker',
events: {
+ 'click': '_onClick',
+ 'keypress': '_onKeypress',
'mousedown .o_color_pick_area': '_onMouseDownPicker',
'mousedown .o_color_slider': '_onMouseDownSlider',
'mousedown .o_opacity_slider': '_onMouseDownOpacitySlider',
@@ -39,18 +41,22 @@ var ColorpickerWidget = Widget.extend({
this.sliderFlag = false;
this.opacitySliderFlag = false;
this.colorComponents = {};
-
- var self = this;
- var $body = $(document.body);
- $body.on('mousemove.colorpicker', _.throttle(function (ev) {
- self._onMouseMovePicker(ev);
- self._onMouseMoveSlider(ev);
- self._onMouseMoveOpacitySlider(ev);
- }, 10));
- $body.on('mouseup.colorpicker', _.throttle(function (ev) {
- self.pickerFlag = false;
- self.sliderFlag = false;
- self.opacitySliderFlag = false;
+ this.uniqueId = _.uniqueId('colorpicker');
+
+ // Needs to be bound on document to work in all possible cases.
+ const $document = $(document);
+ $document.on(`mousemove.${this.uniqueId}`, _.throttle((ev) => {
+ this._onMouseMovePicker(ev);
+ this._onMouseMoveSlider(ev);
+ this._onMouseMoveOpacitySlider(ev);
+ }, 50));
+ $document.on(`mouseup.${this.uniqueId}`, _.throttle((ev) => {
+ if (this.pickerFlag || this.sliderFlag || this.opacitySliderFlag) {
+ this._colorSelected();
+ }
+ this.pickerFlag = false;
+ this.sliderFlag = false;
+ this.opacitySliderFlag = false;
}, 10));
this.options = _.clone(options);
@@ -66,12 +72,17 @@ var ColorpickerWidget = Widget.extend({
this.$opacitySlider = this.$('.o_opacity_slider');
this.$opacitySliderPointer = this.$('.o_opacity_pointer');
+ const resizeObserver = new window.ResizeObserver(() => {
+ this._updateUI();
+ });
+ resizeObserver.observe(this.el);
+
var defaultColor = this.options.defaultColor || '#FF0000';
var rgba = ColorpickerWidget.convertCSSColorToRgba(defaultColor);
if (rgba) {
this._updateRgba(rgba.red, rgba.green, rgba.blue, rgba.opacity);
}
- this._updateUI();
+ this.previewActive = true;
return this._super.apply(this, arguments);
},
/**
@@ -79,7 +90,7 @@ var ColorpickerWidget = Widget.extend({
*/
destroy: function () {
this._super.apply(this, arguments);
- $(document.body).off('.colorpicker');
+ $(document).off(`.${this.uniqueId}`);
},
//--------------------------------------------------------------------------
@@ -207,6 +218,14 @@ var ColorpickerWidget = Widget.extend({
this._updateCssColor();
},
/**
+ * Trigger an event to annonce that the widget value has changed
+ *
+ * @private
+ */
+ _colorSelected: function () {
+ this.trigger_up('colorpicker_select', this.colorComponents);
+ },
+ /**
* Updates css color representation.
*
* @private
@@ -219,6 +238,9 @@ var ColorpickerWidget = Widget.extend({
_.extend(this.colorComponents,
{cssColor: ColorpickerWidget.convertRgbaToCSSColor(r, g, b, a)}
);
+ if (this.previewActive) {
+ this.trigger_up('colorpicker_preview', this.colorComponents);
+ }
},
//--------------------------------------------------------------------------
@@ -226,6 +248,26 @@ var ColorpickerWidget = Widget.extend({
//--------------------------------------------------------------------------
/**
+ * @private
+ * @param {Event} ev
+ */
+ _onKeypress: function (ev) {
+ if (ev.charCode === $.ui.keyCode.ENTER) {
+ if (ev.target.tagName === 'INPUT') {
+ this._onChangeInputs(ev);
+ }
+ ev.preventDefault();
+ this.trigger_up('enter_key_color_colorpicker');
+ }
+ },
+ /**
+ * @param {Event} ev
+ */
+ _onClick: function (ev) {
+ ev.originalEvent.__isColorpickerClick = true;
+ $(ev.target).find('> .o_opacity_pointer, > .o_slider_pointer, > .o_picker_pointer').addBack('.o_opacity_pointer, .o_slider_pointer, .o_picker_pointer').focus();
+ },
+ /**
* Updates color when the user starts clicking on the picker.
*
* @private
@@ -233,6 +275,7 @@ var ColorpickerWidget = Widget.extend({
*/
_onMouseDownPicker: function (ev) {
this.pickerFlag = true;
+ ev.preventDefault();
this._onMouseMovePicker(ev);
},
/**
@@ -265,6 +308,7 @@ var ColorpickerWidget = Widget.extend({
*/
_onMouseDownSlider: function (ev) {
this.sliderFlag = true;
+ ev.preventDefault();
this._onMouseMoveSlider(ev);
},
/**
@@ -293,6 +337,7 @@ var ColorpickerWidget = Widget.extend({
*/
_onMouseDownOpacitySlider: function (ev) {
this.opacitySliderFlag = true;
+ ev.preventDefault();
this._onMouseMoveOpacitySlider(ev);
},
/**
@@ -344,6 +389,7 @@ var ColorpickerWidget = Widget.extend({
break;
}
this._updateUI();
+ this._colorSelected();
},
});
@@ -598,7 +644,9 @@ const ColorpickerDialog = Dialog.extend({
*/
start: function () {
const proms = [this._super(...arguments)];
- this.colorPicker = new ColorpickerWidget(this, this.options);
+ this.colorPicker = new ColorpickerWidget(this, _.extend({
+ colorPreview: true,
+ }, this.options));
proms.push(this.colorPicker.appendTo(this.$el));
return Promise.all(proms);
},
diff --git a/addons/web/static/src/scss/colorpicker.scss b/addons/web/static/src/scss/colorpicker.scss
index ab8d2fb4a90..c53b31198d4 100644
--- a/addons/web/static/src/scss/colorpicker.scss
+++ b/addons/web/static/src/scss/colorpicker.scss
@@ -2,8 +2,8 @@
.o_colorpicker_widget {
.o_color_pick_area {
position: relative;
- width: 200px;
- height: 200px;
+ width: 79%;
+ height: 125px;
background-image: linear-gradient(to bottom, hsl(0, 0%, 100%) 0%, hsla(0, 0%, 100%, 0) 50%, hsla(0, 0%, 0%, 0) 50%, hsl(0, 0%, 0%) 100%),
linear-gradient(to right, hsl(0, 0%, 50%) 0%, hsla(0, 0%, 50%, 0) 100%);
cursor: crosshair;
@@ -18,14 +18,15 @@
}
.o_color_slider {
position: relative;
- width: 18px;
- height: 200px;
+ margin-left: 2.5%;
+ width: 4%;
+ height: 125px;
background: linear-gradient(#F00 0%, #FF0 16.66%, #0F0 33.33%, #0FF 50%, #00F 66.66%, #F0F 83.33%, #F00 100%);
cursor: pointer;
.o_slider_pointer {
- @include o-position-absolute($left: -4px);
- width: 23px;
+ @include o-position-absolute($left: -100%);
+ width: 300%;
height: 6px;
border: 1px solid white;
box-shadow: 0px 0px 2px 1px gray('600');
@@ -33,13 +34,14 @@
}
.o_opacity_slider {
position: relative;
- width: 18px;
- height: 200px;
+ margin-left: 5%;
+ width: 4%;
+ height: 125px;
cursor: pointer;
.o_opacity_pointer {
- @include o-position-absolute($left: -4px);
- width: 23px;
+ @include o-position-absolute($left: -100%);
+ width: 300%;
height: 6px;
border: 1px solid white;
box-shadow: 0px 0px 2px 1px gray('600');
@@ -52,34 +54,38 @@
background-image: url('/web_editor/static/src/img/transparent.png');
}
}
+
.o_color_picker_inputs {
+ padding-top: 3px;
+ font-size: 12px;
display: flex;
- flex-direction: column;
- & > .form-row {
- flex: 1;
- .col {
- display: flex;
- flex-direction: column;
- justify-content: space-around;
- }
- }
+
.o_color_preview_parent {
+ height: 20px;
+ width: 30px;
background-image: url('/web_editor/static/src/img/transparent.png');
+ .o_color_preview {
+ height: inherit;
+ display: block;
+ }
}
- .o_color_preview {
- padding: 0.375rem 1.2rem;
+ .o_hex_div {
+ width: 38%;
+ display: flex;
+ border: 1px solid;
+ margin-right: 2%;
}
- .form-group {
- margin-bottom: 0.3rem;
- label {
- margin-bottom: 0px;
- font-size: 0.7rem;
- font-weight: bold;
- }
+ .o_rgba_div {
+ width: 60%;
+ border: 1px solid;
+ display: flex;
}
- .form-control {
- height: 24px !important;
- font-weight: bold;
+ input {
+ width: 100%;
+ border: none;
+ height: 18px;
+ background-color: inherit;
+ color: inherit;
}
}
}
diff --git a/addons/web/static/src/xml/colorpicker.xml b/addons/web/static/src/xml/colorpicker.xml
index 957bef83146..7fb81da8711 100644
--- a/addons/web/static/src/xml/colorpicker.xml
+++ b/addons/web/static/src/xml/colorpicker.xml
@@ -3,44 +3,30 @@
<t t-name="Colorpicker">
<div class="o_colorpicker_widget">
- <div class="row">
- <div class="col-12">
- <div class="o_color_pick_area d-inline-block border">
- <div class="o_picker_pointer rounded-circle" />
- </div>
- <div class="o_color_slider d-inline-block ml-2 border">
- <div class="o_slider_pointer" />
- </div>
- <div class="o_opacity_slider d-inline-block ml-2 border" t-if="!widget.options.noTransparency">
- <div class="o_opacity_pointer" />
- </div>
+ <div class="o_color_pick_area d-inline-block border" t-att-style="widget.options.noTransparency ? 'width: 89%;' : None">
+ <div class="o_picker_pointer rounded-circle" tabindex="-1"/>
+ </div>
+ <div class="o_color_slider d-inline-block border">
+ <div class="o_slider_pointer" tabindex="-1"/>
+ </div>
+ <div class="o_opacity_slider d-inline-block border" t-if="!widget.options.noTransparency">
+ <div class="o_opacity_pointer" tabindex="-1"/>
+ </div>
+ <div class="o_color_picker_inputs">
+ <div t-if="widget.options.colorPreview" class="o_color_preview_parent">
+ <span class="rounded-0 o_color_preview"/>
+ </div>
+ <div class="o_hex_div"><input type="text" class="o_hex_input" data-color-method="hex" size="1"/>hex</div>
+ <div class="o_rgba_div">
+ <input type="text" class="o_red_input" data-color-method="rgb" size="1"/>
+ <input type="text" class="o_green_input" data-color-method="rgb" size="1"/>
+ <input type="text" class="o_blue_input" data-color-method="rgb" size="1"/>
+ <t t-if="!widget.options.noTransparency">
+ <input type="text" class="o_opacity_input" data-color-method="opacity" size="1"/>
+ RGBA
+ </t>
+ <t t-else="">RGB</t>
</div>
- <form class="col-12 o_color_picker_inputs">
- <div class="input-group">
- <div class="input-group-prepend">
- <span class="input-group-text rounded-0 o_color_preview" />
- </div>
- <input type="text" class="form-control o_hex_input" data-color-method="hex" />
- </div>
- <div class="form-row mt-2">
- <div class="col form-group">
- <label for="red">Red</label>
- <input type="text" class="form-control o_red_input" data-color-method="rgb" id="red" />
- </div>
- <div class="col form-group">
- <label for="green">Green</label>
- <input type="text" class="form-control o_green_input" data-color-method="rgb" id="green" />
- </div>
- <div class="col form-group">
- <label for="blue">Blue</label>
- <input type="text" class="form-control o_blue_input" data-color-method="rgb" id="blue" />
- </div>
- <div class="col form-group" t-if="!widget.options.noTransparency">
- <label for="opacity">Opacity %</label>
- <input type="text" class="form-control o_opacity_input" data-color-method="opacity" id="opacity" />
- </div>
- </div>
- </form>
</div>
</div>
</t>