summaryrefslogtreecommitdiff
path: root/addons/web/static/src
diff options
context:
space:
mode:
authorfja-odoo <fja@odoo.com>2020-04-16 14:00:41 +0000
committerfja-odoo <fja@odoo.com>2020-05-15 11:05:00 +0000
commit99910b526ed792235a778863b993d10cf4e77cd7 (patch)
treecda8b5a4bbe7a07d8b70c3a9fbfa3505871fdb63 /addons/web/static/src
parenta72c9adbe5e60ba178e431e42a81334f85786942 (diff)
[IMP] web, web_editor: integrate colorpicker in colorpalette
Stop using the colorpicker dialog in the colorpalette widget. Integrate the colorpicker widget in the colorpalette widget. Of course, the colorpicker behaviors are adapted so that no useless rerendering of the colorpalette is made on each value change. The 'reset color' button is now a button like the other colors, no need for a 'color_reset' event anymore. It is removed and replaced with a 'color_picked' event with color being an empty string. The clear button now also work on hover. Also, the topbar colorpalette for text and text background colors now has the exact same behaviour as the background colorpalette: adding color preview on hover. The colorpalette now also closes on 'enter' keypress. Part of https://github.com/odoo/odoo/pull/46088 task-2195313 closes odoo/odoo#46088 Related: odoo/enterprise#8696 Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
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>