diff --git a/src/main/java/de/deadlocker8/budgetmaster/icon/IconService.java b/src/main/java/de/deadlocker8/budgetmaster/icon/IconService.java index 3447e9e582e0f3f0aa8bbf23e17050917c3b80a8..86f9dd2b397f11eb8076b3ee999886ba969c660b 100644 --- a/src/main/java/de/deadlocker8/budgetmaster/icon/IconService.java +++ b/src/main/java/de/deadlocker8/budgetmaster/icon/IconService.java @@ -92,6 +92,11 @@ public class IconService implements Resettable return new Icon(imageByIdOptional.get()); } + if(fontColor != null && fontColor.isEmpty()) + { + fontColor = null; + } + if(builtinIconIdentifier != null && !builtinIconIdentifier.isEmpty()) { return new Icon(builtinIconIdentifier, fontColor); diff --git a/src/main/resources/languages/base_de.properties b/src/main/resources/languages/base_de.properties index 293d67b533a62c23f226b7e71a0f3992d60cb555..9122bb84ec40f27f57be45bab1bf55a3cbfc06b8 100644 --- a/src/main/resources/languages/base_de.properties +++ b/src/main/resources/languages/base_de.properties @@ -291,6 +291,7 @@ settings.search.itemsPerPage=Anzahl der Suchergebnisse pro Seite account.new.label.name=Name account.new.label.icon=Icon account.new.label.icon.fontcolor=Schriftfarbe +account.new.icon.fontcolor.clear=Automatische Schriftfarbe account.new.icon.placeholder=Vorschau anklicken, um ein Icon auszuwählen account.new.icon.upload.choose.file=Datei auswählen account.new.icon.upload=Hochladen diff --git a/src/main/resources/languages/base_en.properties b/src/main/resources/languages/base_en.properties index 5562c86ea2e060a61dd4a8be9bdaa80654796583..3a5dd6b74101aa5f30862af5c479c0de77ee5386 100644 --- a/src/main/resources/languages/base_en.properties +++ b/src/main/resources/languages/base_en.properties @@ -292,6 +292,7 @@ settings.search.itemsPerPage=Number of search results per page account.new.label.name=Name account.new.label.icon=Icon account.new.label.icon.fontcolor=Font color +account.new.icon.fontcolor.clear=Automatic font color account.new.icon.placeholder=Click preview to select an icon account.new.icon.upload.choose.file=Choose file account.new.icon.upload=Upload diff --git a/src/main/resources/static/css/style.css b/src/main/resources/static/css/style.css index b2c6f147434c5f6024c1cc342cffb93803587d85..ee21e1d185ae9847916bf5131bce590619163461 100644 --- a/src/main/resources/static/css/style.css +++ b/src/main/resources/static/css/style.css @@ -493,7 +493,7 @@ input[type="radio"]:checked + span::after, [type="radio"].with-gap:checked + spa height: 3px; } -#customColorPickerContainer > span{ +#customColorPickerContainer > span { color: black; line-height: 25px; } @@ -504,6 +504,10 @@ input[type="radio"]:checked + span::after, [type="radio"].with-gap:checked + spa justify-content: center; } +#buttonFontColorAuto { + margin-top: 3rem; +} + .invisible { opacity: 0; } diff --git a/src/main/resources/static/js/categories.js b/src/main/resources/static/js/categories.js index 0c9269104d59b30bc604fc70e9781267b28523be..0c32375b30f11d172760818c7e79a69825a5fe9c 100644 --- a/src/main/resources/static/js/categories.js +++ b/src/main/resources/static/js/categories.js @@ -66,7 +66,9 @@ function removeActive() function updateCustomColor(parent, color) { removeActive(); + addClass(parent, "category-color-active"); parent.style.backgroundColor = color.hex; document.getElementById("categoryColor").value = color.hex; + document.getElementById("item-icon-preview-background").style.backgroundColor = color.rgbaString; } diff --git a/src/main/resources/static/js/fontColorPicker.js b/src/main/resources/static/js/fontColorPicker.js index 1fef5add488924401068d51dfb1ea51ef019328d..5bd73df1495eb859ea6ac72b40b0d85a0add509b 100644 --- a/src/main/resources/static/js/fontColorPicker.js +++ b/src/main/resources/static/js/fontColorPicker.js @@ -21,6 +21,18 @@ $(document).ready(function() }); fontColorPicker.setColor(fontColorPickerParent.style.backgroundColor, true); + + $('#buttonFontColorAuto').click(function() + { + document.getElementById("fontColor").value = null; + + let backgroundColor = document.getElementById('item-icon-preview-background').style.backgroundColor; + let rgb = extractRGB(backgroundColor); + let appropriateColor = getAppropriateTextColor(rgb); + document.getElementById("item-icon-preview").style.color = appropriateColor; + + fontColorPicker.setColor(appropriateColor, true); + }); } }); @@ -30,3 +42,22 @@ function updateFontColor(parent, color) document.getElementById("fontColor").value = color.hex; document.getElementById("item-icon-preview").style.color = color.hex; } + +function extractRGB(rgbaString) +{ + return rgbaString.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+\.{0,1}\d*))?\)$/).slice(1, 4); +} + +function getAppropriateTextColor(colorRGB) +{ + // Counting the perceptive luminance - human eye favors green color... + let a = 1 - (0.299 * colorRGB[0] + 0.587 * colorRGB[1] + 0.114 * colorRGB[2]) / 255; + if(a < 0.5) + { + return '#000000'; + } + else + { + return '#FFFFFF' + } +} diff --git a/src/main/resources/static/js/main.js b/src/main/resources/static/js/main.js index 34b95cffacb231b75c76712123e1d0176d3fd45a..a72329d9522bef7c4b6049b4a13a63389e3673d1 100644 --- a/src/main/resources/static/js/main.js +++ b/src/main/resources/static/js/main.js @@ -110,14 +110,13 @@ function removeClass(element, className) function rgb2hex(rgb) { - rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); + let rgba = rgb.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+\.{0,1}\d*))?\)$/).slice(1); + let convertedParts = rgba.map((n, i) => (i === 3 ? Math.round(parseFloat(n) * 255) : parseFloat(n)) + .toString(16) + .padStart(2, '0') + .replace('NaN', '')); - function hex(x) - { - return ("0" + parseInt(x).toString(16)).slice(-2); - } - - return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]); + return '#' + convertedParts.join(''); } function validateLoginForm() diff --git a/src/main/resources/templates/categories/newCategory.ftl b/src/main/resources/templates/categories/newCategory.ftl index a44313c0ddd28441a7ef08802a24919c74808543..0569580845eeeb29ed7c7e08cf87285110acccae 100644 --- a/src/main/resources/templates/categories/newCategory.ftl +++ b/src/main/resources/templates/categories/newCategory.ftl @@ -87,8 +87,12 @@ <i class="material-icons prefix">palette</i> <label class="input-label" for="fontColorPickerContainer">${locale.getString("account.new.label.icon.fontcolor")}</label> - <div id="fontColorPickerContainer" class="valign-wrapper"> - <div id="fontColorPicker" style="background-color: ${category.getFontColor()}"></div> + <div class="center-align"> + <@header.buttonLink url='' icon='auto_fix_high' id='buttonFontColorAuto' localizationKey='account.new.icon.fontcolor.clear' noUrl=true/> + + <div id="fontColorPickerContainer" class="valign-wrapper"> + <div id="fontColorPicker" style="background-color: ${category.getFontColor()}"></div> + </div> </div> </div> </div>