From bffad0f017c52628ddcba862a54536bbbbeb6ab6 Mon Sep 17 00:00:00 2001 From: spilymp Date: Sun, 7 Mar 2021 15:42:38 +0100 Subject: [PATCH] version 1.0.0 - initial commit --- README.md | 17 +- css/milligram.min.css | 3 + css/style.css | 36 ++++ index.html | 323 ++++++++++++++++++++++++++++++++++ js/ibo_icon.js | 393 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 771 insertions(+), 1 deletion(-) create mode 100644 css/milligram.min.css create mode 100644 css/style.css create mode 100644 index.html create mode 100644 js/ibo_icon.js diff --git a/README.md b/README.md index e87df50..500c232 100644 --- a/README.md +++ b/README.md @@ -1 +1,16 @@ -# iob \ No newline at end of file +# IBO - Icon Builder for Odoo + +The provided [Configurator](https://spilymp.github.io/iob/) can be used to quickly and easily create new appicons in the style of the +appicons of the ERP system [Odoo](https://www.odoo.com/). + +But it is also possible to use the included js class elsewhere and create your own configurator based on it, for example. + +For this purpose, the class offers a few more parameters for individualization in addition to the options shown in the documentation section. + +## Documentation + +The basis of the configurator is a JavaScript class "IBO_ICON", which creates a canvas and "paints" the icon on it (see file [`/js/ibo_icon.js`](https://github.com/spilymp/iob/blob/main/js/ibo_icon.js)). +If the existing class is used directly by means of a script, additional parameters can be passed. +If this class is instantiated, various parameters can be passed to it. +If not, default values are used in each case. +For more information please visit the [Project Website](https://spilymp.github.io/iob/). \ No newline at end of file diff --git a/css/milligram.min.css b/css/milligram.min.css new file mode 100644 index 0000000..5e8955c --- /dev/null +++ b/css/milligram.min.css @@ -0,0 +1,3 @@ +*,*:after,*:before{box-sizing:inherit}html{box-sizing:border-box;font-size:62.5%}body{color:#606c76;font-family:'Roboto', 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;font-size:1.6em;font-weight:300;letter-spacing:.01em;line-height:1.6}blockquote{border-left:0.3rem solid #d1d1d1;margin-left:0;margin-right:0;padding:1rem 1.5rem}blockquote *:last-child{margin-bottom:0}.button,button,input[type='button'],input[type='reset'],input[type='submit']{background-color:#9b4dca;border:0.1rem solid #9b4dca;border-radius:.4rem;color:#fff;cursor:pointer;display:inline-block;font-size:1.1rem;font-weight:700;height:3.8rem;letter-spacing:.1rem;line-height:3.8rem;padding:0 3.0rem;text-align:center;text-decoration:none;text-transform:uppercase;white-space:nowrap}.button:focus,.button:hover,button:focus,button:hover,input[type='button']:focus,input[type='button']:hover,input[type='reset']:focus,input[type='reset']:hover,input[type='submit']:focus,input[type='submit']:hover{background-color:#606c76;border-color:#606c76;color:#fff;outline:0}.button[disabled],button[disabled],input[type='button'][disabled],input[type='reset'][disabled],input[type='submit'][disabled]{cursor:default;opacity:.5}.button[disabled]:focus,.button[disabled]:hover,button[disabled]:focus,button[disabled]:hover,input[type='button'][disabled]:focus,input[type='button'][disabled]:hover,input[type='reset'][disabled]:focus,input[type='reset'][disabled]:hover,input[type='submit'][disabled]:focus,input[type='submit'][disabled]:hover{background-color:#9b4dca;border-color:#9b4dca}.button.button-outline,button.button-outline,input[type='button'].button-outline,input[type='reset'].button-outline,input[type='submit'].button-outline{background-color:transparent;color:#9b4dca}.button.button-outline:focus,.button.button-outline:hover,button.button-outline:focus,button.button-outline:hover,input[type='button'].button-outline:focus,input[type='button'].button-outline:hover,input[type='reset'].button-outline:focus,input[type='reset'].button-outline:hover,input[type='submit'].button-outline:focus,input[type='submit'].button-outline:hover{background-color:transparent;border-color:#606c76;color:#606c76}.button.button-outline[disabled]:focus,.button.button-outline[disabled]:hover,button.button-outline[disabled]:focus,button.button-outline[disabled]:hover,input[type='button'].button-outline[disabled]:focus,input[type='button'].button-outline[disabled]:hover,input[type='reset'].button-outline[disabled]:focus,input[type='reset'].button-outline[disabled]:hover,input[type='submit'].button-outline[disabled]:focus,input[type='submit'].button-outline[disabled]:hover{border-color:inherit;color:#9b4dca}.button.button-clear,button.button-clear,input[type='button'].button-clear,input[type='reset'].button-clear,input[type='submit'].button-clear{background-color:transparent;border-color:transparent;color:#9b4dca}.button.button-clear:focus,.button.button-clear:hover,button.button-clear:focus,button.button-clear:hover,input[type='button'].button-clear:focus,input[type='button'].button-clear:hover,input[type='reset'].button-clear:focus,input[type='reset'].button-clear:hover,input[type='submit'].button-clear:focus,input[type='submit'].button-clear:hover{background-color:transparent;border-color:transparent;color:#606c76}.button.button-clear[disabled]:focus,.button.button-clear[disabled]:hover,button.button-clear[disabled]:focus,button.button-clear[disabled]:hover,input[type='button'].button-clear[disabled]:focus,input[type='button'].button-clear[disabled]:hover,input[type='reset'].button-clear[disabled]:focus,input[type='reset'].button-clear[disabled]:hover,input[type='submit'].button-clear[disabled]:focus,input[type='submit'].button-clear[disabled]:hover{color:#9b4dca}code{background:#f4f5f6;border-radius:.4rem;font-size:86%;margin:0 .2rem;padding:.2rem .5rem;white-space:nowrap}pre{background:#f4f5f6;border-left:0.3rem solid #9b4dca;overflow-y:hidden}pre>code{border-radius:0;display:block;padding:1rem 1.5rem;white-space:pre}hr{border:0;border-top:0.1rem solid #f4f5f6;margin:3.0rem 0}input[type='color'],input[type='date'],input[type='datetime'],input[type='datetime-local'],input[type='email'],input[type='month'],input[type='number'],input[type='password'],input[type='search'],input[type='tel'],input[type='text'],input[type='url'],input[type='week'],input:not([type]),textarea,select{-webkit-appearance:none;background-color:transparent;border:0.1rem solid #d1d1d1;border-radius:.4rem;box-shadow:none;box-sizing:inherit;height:3.8rem;padding:.6rem 1.0rem .7rem;width:100%}input[type='color']:focus,input[type='date']:focus,input[type='datetime']:focus,input[type='datetime-local']:focus,input[type='email']:focus,input[type='month']:focus,input[type='number']:focus,input[type='password']:focus,input[type='search']:focus,input[type='tel']:focus,input[type='text']:focus,input[type='url']:focus,input[type='week']:focus,input:not([type]):focus,textarea:focus,select:focus{border-color:#9b4dca;outline:0}select{background:url('data:image/svg+xml;utf8,') center right no-repeat;padding-right:3.0rem}select:focus{background-image:url('data:image/svg+xml;utf8,')}select[multiple]{background:none;height:auto}textarea{min-height:6.5rem}label,legend{display:block;font-size:1.6rem;font-weight:700;margin-bottom:.5rem}fieldset{border-width:0;padding:0}input[type='checkbox'],input[type='radio']{display:inline}.label-inline{display:inline-block;font-weight:normal;margin-left:.5rem}.container{margin:0 auto;max-width:112.0rem;padding:0 2.0rem;position:relative;width:100%}.row{display:flex;flex-direction:column;padding:0;width:100%}.row.row-no-padding{padding:0}.row.row-no-padding>.column{padding:0}.row.row-wrap{flex-wrap:wrap}.row.row-top{align-items:flex-start}.row.row-bottom{align-items:flex-end}.row.row-center{align-items:center}.row.row-stretch{align-items:stretch}.row.row-baseline{align-items:baseline}.row .column{display:block;flex:1 1 auto;margin-left:0;max-width:100%;width:100%}.row .column.column-offset-10{margin-left:10%}.row .column.column-offset-20{margin-left:20%}.row .column.column-offset-25{margin-left:25%}.row .column.column-offset-33,.row .column.column-offset-34{margin-left:33.3333%}.row .column.column-offset-40{margin-left:40%}.row .column.column-offset-50{margin-left:50%}.row .column.column-offset-60{margin-left:60%}.row .column.column-offset-66,.row .column.column-offset-67{margin-left:66.6666%}.row .column.column-offset-75{margin-left:75%}.row .column.column-offset-80{margin-left:80%}.row .column.column-offset-90{margin-left:90%}.row .column.column-10{flex:0 0 10%;max-width:10%}.row .column.column-20{flex:0 0 20%;max-width:20%}.row .column.column-25{flex:0 0 25%;max-width:25%}.row .column.column-33,.row .column.column-34{flex:0 0 33.3333%;max-width:33.3333%}.row .column.column-40{flex:0 0 40%;max-width:40%}.row .column.column-50{flex:0 0 50%;max-width:50%}.row .column.column-60{flex:0 0 60%;max-width:60%}.row .column.column-66,.row .column.column-67{flex:0 0 66.6666%;max-width:66.6666%}.row .column.column-75{flex:0 0 75%;max-width:75%}.row .column.column-80{flex:0 0 80%;max-width:80%}.row .column.column-90{flex:0 0 90%;max-width:90%}.row .column .column-top{align-self:flex-start}.row .column .column-bottom{align-self:flex-end}.row .column .column-center{align-self:center}@media (min-width: 40rem){.row{flex-direction:row;margin-left:-1.0rem;width:calc(100% + 2.0rem)}.row .column{margin-bottom:inherit;padding:0 1.0rem}}a{color:#9b4dca;text-decoration:none}a:focus,a:hover{color:#606c76}dl,ol,ul{list-style:none;margin-top:0;padding-left:0}dl dl,dl ol,dl ul,ol dl,ol ol,ol ul,ul dl,ul ol,ul ul{font-size:90%;margin:1.5rem 0 1.5rem 3.0rem}ol{list-style:decimal inside}ul{list-style:circle inside}.button,button,dd,dt,li{margin-bottom:1.0rem}fieldset,input,select,textarea{margin-bottom:1.5rem}blockquote,dl,figure,form,ol,p,pre,table,ul{margin-bottom:2.5rem}table{border-spacing:0;display:block;overflow-x:auto;text-align:left;width:100%}td,th{border-bottom:0.1rem solid #e1e1e1;padding:1.2rem 1.5rem}td:first-child,th:first-child{padding-left:0}td:last-child,th:last-child{padding-right:0}@media (min-width: 40rem){table{display:table;overflow-x:initial}}b,strong{font-weight:bold}p{margin-top:0}h1,h2,h3,h4,h5,h6{font-weight:300;letter-spacing:-.1rem;margin-bottom:2.0rem;margin-top:0}h1{font-size:4.6rem;line-height:1.2}h2{font-size:3.6rem;line-height:1.25}h3{font-size:2.8rem;line-height:1.3}h4{font-size:2.2rem;letter-spacing:-.08rem;line-height:1.35}h5{font-size:1.8rem;letter-spacing:-.05rem;line-height:1.5}h6{font-size:1.6rem;letter-spacing:0;line-height:1.4}img{max-width:100%}.clearfix:after{clear:both;content:' ';display:table}.float-left{float:left}.float-right{float:right} + +/*# sourceMappingURL=milligram.min.css.map */ \ No newline at end of file diff --git a/css/style.css b/css/style.css new file mode 100644 index 0000000..a15da5a --- /dev/null +++ b/css/style.css @@ -0,0 +1,36 @@ +body { + font-size: 18px; +} + +h1 { + margin: 1.5em 0 1.5em 0; +} + +h2 { + margin: 2em 0 1em 0; +} + +h3 { + margin: 1em 0 0.5em 0; +} + +.button { + padding: 0 2.5rem !important; +} + +.align-center { + text-align: center; +} + +label { + text-align: right; +} + +hr { + border: solid 1px #d2d2d2; + width : 100%; +} + +footer { + font-size: 0.8em; +} \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..3c17a2a --- /dev/null +++ b/index.html @@ -0,0 +1,323 @@ + + + + + + IBO - Icon Builder for Odoo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ +
+
+
+

IBO - Icon Builder for Odoo

+
+
+
+ +
+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+ +
+ +
+ +
+
+
+ +
+
+ +
+
+
+

Documentation

+
+
+
+
+

+ The configurator above can be used to quickly and easily create new appicons in the style of the + appicons of the ERP system Odoo. + + To set an icon you have to find and enter the corresponding css class. + Please check the corresponding page of the icon set for this purpose: +

+

+
+
+ +
+
+

Getting Started

+
+
+
+
+

+ It is also possible to use the class elsewhere and create your own configurator based on it, for + example. + For this purpose, the class offers a few more parameters for individualization in addition to the + options shown above. +

+
+
+
+
+

+ The basis of the configurator is a JavaScript class "IBO_ICON", which creates a canvas and "paints" + the icon on it. + If the existing class is used directly by means of a script, additional parameters can be passed. + If this class is instantiated, various parameters can be passed to it (see sample code block on the + right). + If not, default values are used in each case. +

+
+
+
+                        [...]
+let icon = new IBO_ICON({
+    'font_family': 'bootstrap-icons',
+    'icon_class': 'bi bi-droplet',
+});
+[...]
+                
+
+
+ +
+
+

+ The actual creation then takes place in the "draw" method. + The ID of an HTML element to which the created canvas is attached must be specified here as a + parameter. +

+
+
+
+                        [...]
+icon.draw("icon");
+[...]
+                
+
+
+ +
+

Parameter

+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterValuesDescription
font_coloreg. "#ffffff"Hex color value for the text or symbol.
font_familyeg. "Font Awesome 5 Free"Font family for your text or symbol. Make sure the family is added to your page!
font_weighteg. "900"Font weight for your text or symbol.
icon_backgroundeg. "#9b4dca"Hex color value for the background of your icon.
icon_classeg. "fas fa-address-card"CSS class name of your symbol for the icon, the class will automatically try to finde + the corresponding unicode. If an unicode is set the class will be ignored.
icon_texteg. "Test"The text or symbol which should be displayed on the icon. Will be preferred over the + parameter "icon_class" if set.
icon_widtheg. "300"The width of your icon (in px), will also be the height of your icon.
odoo_version["11.0", "12.0", "13.0", "14.0"]The odoo version for which the icon should be generated.
+
+
+
+ + + + + \ No newline at end of file diff --git a/js/ibo_icon.js b/js/ibo_icon.js new file mode 100644 index 0000000..f506263 --- /dev/null +++ b/js/ibo_icon.js @@ -0,0 +1,393 @@ +/** + * Version: 1.0.0 + * + * Copyright (C) 2021 - spilymp (https://github.com/spilymp) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +class IBO_ICON { + + constructor(settings) { + + // set default parameter + this.font_color = "#ffffff"; + this.font_family = "Font Awesome 5 Free"; + this.font_weight = "900"; + this.icon_background = "#9b4dca"; + this.icon_class = "fas fa-address-card"; + this.icon_width = "300"; + this.odoo_version = "13.0"; + + // overwrite default parameter + if (settings != null) { + Object.assign(this, settings); + } + + // calculate default parameter if not set manually in settings + if (settings != null && !("font_size" in settings)) { + this.font_size = parseInt(this.icon_width) * 0.5; + } + if (settings != null && !("icon_text" in settings)) { + this.icon_text = this._getUnicode(this.icon_class) + } + + // set other non public settings + this._canvas = false; + this._ctx = false; + this._isFontLoaded = false; + } + + /** + * Central function to create the icon based on the parameters from the initialization (see Constructor). + * + * @param {*} element - ID of the HTML element to which the icon is attached in the form of a canvas element. + */ + draw(element) { + document.fonts.ready.then(() => this._draw(element)); + }; + + _draw(element) { + this._setUp(); + this._setBackground(); + this._setHardShadow(); + this._setTextWithShadow(); + this._setInlineShadow(); + this._setGradient(); + document.getElementById(element).appendChild(this.canvas); + } + + /** + * Set up canvas and get context + */ + _setUp() { + this.canvas = document.createElement("canvas"); + this.canvas.setAttribute("class", "ibo-icon-canvas"); + this.canvas.height = this.icon_width; + this.canvas.width = this.icon_width; + + this._ctx = this.canvas.getContext("2d"); + this._ctx.font = `normal ${this.font_weight} ${this.font_size}px "${this.font_family}"`; + } + + /** + * Draw background color + */ + _setBackground() { + let radius = this.icon_width * 0.047 + + this._ctx.beginPath(); + + switch (this.odoo_version) { + case "11.0": + this._ctx.rect(0, 0, this.icon_width, this.icon_width); + break; + case "12.0": + case "13.0": + case "14.0": + this._ctx.moveTo(radius, 0); + this._ctx.lineTo(this.icon_width - radius, 0); + this._ctx.arcTo(this.icon_width, 0, this.icon_width, radius, radius); + this._ctx.lineTo(this.icon_width, this.icon_width - radius); + this._ctx.arcTo(this.icon_width, this.icon_width, this.icon_width - radius, this.icon_width, radius); + this._ctx.lineTo(radius, this.icon_width); + this._ctx.arcTo(0, this.icon_width, 0, this.icon_width - radius, radius); + this._ctx.lineTo(0, radius); + this._ctx.arcTo(0, 0, this.icon_width - radius, 0, radius); + break; + default: + console.log("Not supported version selected."); + break; + } + this._ctx.clip(); + this._ctx.fillStyle = this.icon_background; + this._ctx.fill(); + } + + /** + * Helping function to draw text/symbols to the canvas. + * + * @param {*} text - the text or symbol which should be drawn to the canvas + * @param {*} color - the color of the text + * @param {*} centerX - text position on the x achsis of the canvas + * @param {*} centerY - text position on the y achsis of the canvas + */ + _setText(text, color, centerX, centerY, font_size) { + this._ctx.save(); + this._ctx.fillStyle = color; + this._ctx.font = `normal ${font_size}px "${this.font_family}"`; + this._ctx.textAlign = "center"; + this._ctx.textBaseline = "middle"; + this._ctx.fillText(`${text}`, centerX, centerY); + this._ctx.restore(); + } + + /** + * Shade, blend and convert a color. + * + * Credit to Pimp Trizkit (https://github.com/PimpTrizkit) + * Documentation see https://github.com/PimpTrizkit/PJs/wiki/12.-Shade,-Blend-and-Convert-a-Web-Color-(pSBC.js) + */ + _pSBC(p, c0, c1, l) { + let r, + g, + b, + P, + f, + t, + h, + i = parseInt, + m = Math.round, + a = typeof c1 == "string"; + if ( + typeof p != "number" || + p < -1 || + p > 1 || + typeof c0 != "string" || + (c0[0] != "r" && c0[0] != "#") || + (c1 && !a) + ) + return null; + if (!this.pSBCr) + this.pSBCr = d => { + let n = d.length, + x = {}; + if (n > 9) { + ([r, g, b, a] = d = d.split(",")), (n = d.length); + if (n < 3 || n > 4) return null; + (x.r = i(r[3] == "a" ? r.slice(5) : r.slice(4))), + (x.g = i(g)), + (x.b = i(b)), + (x.a = a ? parseFloat(a) : -1); + } else { + if (n == 8 || n == 6 || n < 4) return null; + if (n < 6) + d = + "#" + + d[1] + + d[1] + + d[2] + + d[2] + + d[3] + + d[3] + + (n > 4 ? d[4] + d[4] : ""); + d = i(d.slice(1), 16); + if (n == 9 || n == 5) + (x.r = (d >> 24) & 255), + (x.g = (d >> 16) & 255), + (x.b = (d >> 8) & 255), + (x.a = m((d & 255) / 0.255) / 1000); + else + (x.r = d >> 16), + (x.g = (d >> 8) & 255), + (x.b = d & 255), + (x.a = -1); + } + return x; + }; + (h = c0.length > 9), + (h = a ? (c1.length > 9 ? true : c1 == "c" ? !h : false) : h), + (f = this.pSBCr(c0)), + (P = p < 0), + (t = + c1 && c1 != "c" + ? this.pSBCr(c1) + : P + ? { r: 0, g: 0, b: 0, a: -1 } + : { r: 255, g: 255, b: 255, a: -1 }), + (p = P ? p * -1 : p), + (P = 1 - p); + if (!f || !t) return null; + if (l) + (r = m(P * f.r + p * t.r)), + (g = m(P * f.g + p * t.g)), + (b = m(P * f.b + p * t.b)); + else + (r = m((P * f.r ** 2 + p * t.r ** 2) ** 0.5)), + (g = m((P * f.g ** 2 + p * t.g ** 2) ** 0.5)), + (b = m((P * f.b ** 2 + p * t.b ** 2) ** 0.5)); + (a = f.a), + (t = t.a), + (f = a >= 0 || t >= 0), + (a = f ? (a < 0 ? t : t < 0 ? a : a * P + t * p) : 0); + if (h) + return ( + "rgb" + + (f ? "a(" : "(") + + r + + "," + + g + + "," + + b + + (f ? "," + m(a * 1000) / 1000 : "") + + ")" + ); + else + return ( + "#" + + (4294967296 + r * 16777216 + g * 65536 + b * 256 + (f ? m(a * 255) : 0)) + .toString(16) + .slice(1, f ? undefined : -2) + ); + }; + + _setHardShadow() { + for (let i = 0; i < (this.icon_width * (2 / 3)); i++) { + const tmp_width = (parseInt(this.icon_width) - 2 * i) / 2; + const tmp_height = (parseInt(this.icon_width) + 2 * i) / 2; + + this._setText( + this.icon_text, + this._pSBC(-0.4, this.icon_background), + tmp_width, + tmp_height, + this.font_size + ); + } + } + + /** + * Sets a lighter shadow that extends to the lower left corner of the icon. + */ + _setTextWithShadow() { + this._ctx.save(); + + switch (this.odoo_version) { + case "11.0": + break; + case "12.0": + case "13.0": + case "14.0": + this._ctx.shadowOffsetX = 0; + this._ctx.shadowOffsetY = this.icon_width * 0.02; + this._ctx.shadowBlur = 0; + this._ctx.shadowColor = "rgba(0, 0, 0, 0.4)"; + break; + default: + console.log("Not supported version selected."); + break; + } + + this._setText( + this.icon_text, + this.font_color, + parseInt(this.icon_width) / 2, + parseInt(this.icon_width) / 2, + this.font_size + ); + this._ctx.restore(); + } + + /** + * Sets an inward shadow for the top and bottom edges of the icon. + * Will only be displayed depending on the selected version. + */ + _setInlineShadow() { + switch (this.odoo_version) { + case "11.0": + break; + case "12.0": + case "13.0": + case "14.0": + let is_radius = this.icon_width * 0.047 + let is_height = this.icon_width * 0.015 + + this._ctx.save(); + this._ctx.globalAlpha = 0.4; + + // inner shadow bottom + this._ctx.fillStyle = "#282F33"; + this._ctx.beginPath(); + this._ctx.moveTo(is_radius - is_height, this.icon_width); + this._ctx.lineTo(this.icon_width - is_radius, this.icon_width); + this._ctx.arcTo(this.icon_width, this.icon_width, this.icon_width, this.icon_width - is_radius, is_radius); + this._ctx.lineTo(this.icon_width, this.icon_width - (is_radius + is_height)); + this._ctx.arcTo(this.icon_width, this.icon_width - is_height, this.icon_width - is_radius, this.icon_width - is_height, is_radius); + this._ctx.lineTo(is_radius, this.icon_width - is_height); + this._ctx.arcTo(0, this.icon_width - is_height, 0, this.icon_width - (is_radius + is_height), is_radius); + this._ctx.lineTo(0, this.icon_width - is_height); + this._ctx.arcTo(0, this.icon_width, is_radius - is_height, this.icon_width, is_radius); + this._ctx.fill(); + + // inner shadow top + this._ctx.fillStyle = "#FFFFFF"; + this._ctx.beginPath(); + this._ctx.moveTo(is_radius - is_height, 0); + this._ctx.lineTo(this.icon_width - is_radius, 0); + this._ctx.arcTo(this.icon_width, 0, this.icon_width, is_radius - is_height, is_radius); + this._ctx.lineTo(this.icon_width, is_radius + 2); + this._ctx.arcTo(this.icon_width, is_height, this.icon_width - is_radius, is_height, is_radius); + this._ctx.lineTo(is_radius, is_height); + this._ctx.arcTo(0, is_height, 0, is_radius + is_height, is_radius); + this._ctx.lineTo(0, is_radius); + this._ctx.arcTo(0, 0, is_radius - is_height, 0, is_radius); + this._ctx.fill(); + + this._ctx.restore(); + break; + default: + console.log("Not supported version selected."); + break; + } + } + + /** + * Puts a slight gradient over the icon. + * Will only be displayed depending on the selected version. + */ + _setGradient() { + switch (this.odoo_version) { + case "11.0": + break; + case "12.0": + case "13.0": + case "14.0": + this._ctx.save(); + this._ctx.globalAlpha = 0.2; + var gradient = this._ctx.createLinearGradient( + 0, + this.icon_width, + this.icon_width, + 0 + ); + gradient.addColorStop(0, "rgba(0,0,0,0)"); + gradient.addColorStop(1, "#FFFFFF"); + this._ctx.fillStyle = gradient; + this._ctx.fillRect(0, 0, this.icon_width, this.icon_width); + this._ctx.restore(); + break; + default: + console.log("Not supported version selected."); + break; + } + } + + /** + * Helper function to extract the corresponding symbol based on a given class. + * @param {*} clazzName - The CSS class from which the symbol should be extracted. + */ + _getUnicode(clazzName) { + let tempI = document.createElement('i'); + + tempI.className = clazzName; + document.body.appendChild(tempI); + + //let char = window.getComputedStyle(document.querySelector('.' + clazzName), ':before').getPropertyValue('content').replace(/'|"/g, ''); + let char = window.getComputedStyle(tempI, ':before').content.replace(/'|"/g, ''); + + tempI.remove(); + + return char; + } +} \ No newline at end of file