Allow to configure accent colors

This commit is contained in:
Raphael Michel
2018-11-13 12:56:52 +01:00
parent e523a4e610
commit 4e6f4716ec
8 changed files with 124 additions and 10 deletions

View File

@@ -483,6 +483,14 @@ Your {event} team"""))
'default': '#8E44B3',
'type': str
},
'theme_color_success': {
'default': '#50A167',
'type': str
},
'theme_color_danger': {
'default': '#D36060',
'type': str
},
'primary_font': {
'default': 'Open Sans',
'type': str

View File

@@ -5,6 +5,7 @@ from django import forms
from django.conf import settings
from django.core.exceptions import ValidationError
from django.forms.utils import from_current_timezone
from django.utils.deconstruct import deconstructible
from django.utils.html import conditional_escape
from django.utils.translation import ugettext_lazy as _
@@ -185,3 +186,44 @@ class SplitDateTimeField(forms.SplitDateTimeField):
result = datetime.datetime.combine(*data_list)
return from_current_timezone(result)
return None
@deconstructible
class ColorContrastValidator:
message = _('This color is too bright to allow for proper contrast when used for text on white ground.')
code = 'contrast'
def __init__(self, message=None, code=None):
if message is not None:
self.message = message
if code is not None:
self.code = code
def __call__(self, value):
# See https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
fg_color = [int(str(value)[1:3], 16), int(str(value)[1:3], 16), int(str(value)[1:3], 16)]
bg_color = [255, 255, 255]
fg_lum = [
(float(cc) / 255) / 12.92
if (float(cc) / 255) < 0.03928
else (((float(cc) / 255) + 0.055) / 1.055) ** 2.4
for cc in fg_color
]
bg_lum = [
(float(cc) / 255) / 12.92
if (float(cc) / 255) < 0.03928
else (((float(cc) / 255) + 0.055) / 1.055) ** 2.4
for cc in bg_color
]
fg_rel_lum = 0.2126 * fg_lum[0] + 0.7152 * fg_lum[1] + 0.0722 * fg_lum[2]
bg_rel_lum = 0.2126 * bg_lum[0] + 0.7152 * bg_lum[1] + 0.0722 * bg_lum[2]
contrast_ratio = (bg_rel_lum + 0.05) / (fg_rel_lum + 0.05)
if contrast_ratio < 1.4:
raise ValidationError(self.message, code=self.code)
def __eq__(self, other):
return (
isinstance(other, ColorContrastValidator) and
(self.message == other.message) and
(self.code == other.code)
)

View File

@@ -22,8 +22,9 @@ from pretix.base.models.event import EventMetaValue, SubEvent
from pretix.base.reldate import RelativeDateField, RelativeDateTimeField
from pretix.base.settings import PERSON_NAME_SCHEMES
from pretix.control.forms import (
ExtFileField, MultipleLanguagesWidget, SingleLanguageWidget, SlugWidget,
SplitDateTimeField, SplitDateTimePickerWidget,
ColorContrastValidator, ExtFileField, MultipleLanguagesWidget,
SingleLanguageWidget, SlugWidget, SplitDateTimeField,
SplitDateTimePickerWidget,
)
from pretix.multidomain.urlreverse import build_absolute_uri
from pretix.plugins.banktransfer.payment import BankTransfer
@@ -935,10 +936,37 @@ class MailSettingsForm(SettingsForm):
class DisplaySettingsForm(SettingsForm):
primary_color = forms.CharField(
label=_("Primary color"),
help_text=_("We strongly suggest to use a dark shade that has a good contrast for text on white ground."),
required=False,
validators=[
RegexValidator(regex='^#[0-9a-fA-F]{6}$',
message=_('Please enter the hexadecimal code of a color, e.g. #990000.'))
message=_('Please enter the hexadecimal code of a color, e.g. #990000.')),
ColorContrastValidator()
],
widget=forms.TextInput(attrs={'class': 'colorpickerfield'})
)
theme_color_success = forms.CharField(
label=_("Accent color for success"),
help_text=_("We strongly suggest to use a dark shade of green that has a good contrast for text on white "
"ground."),
required=False,
validators=[
RegexValidator(regex='^#[0-9a-fA-F]{6}$',
message=_('Please enter the hexadecimal code of a color, e.g. #990000.')),
ColorContrastValidator()
],
widget=forms.TextInput(attrs={'class': 'colorpickerfield'})
)
theme_color_danger = forms.CharField(
label=_("Accent color for errors"),
help_text=_("We strongly suggest to use a dark shade of red that has a good contrast for text on white "
"ground."),
required=False,
validators=[
RegexValidator(regex='^#[0-9a-fA-F]{6}$',
message=_('Please enter the hexadecimal code of a color, e.g. #990000.')),
ColorContrastValidator()
],
widget=forms.TextInput(attrs={'class': 'colorpickerfield'})
)

View File

@@ -10,7 +10,9 @@ from pretix.api.models import WebHook
from pretix.api.webhooks import get_all_webhook_events
from pretix.base.forms import I18nModelForm, SettingsForm
from pretix.base.models import Device, Organizer, Team
from pretix.control.forms import ExtFileField, MultipleLanguagesWidget
from pretix.control.forms import (
ColorContrastValidator, ExtFileField, MultipleLanguagesWidget,
)
from pretix.multidomain.models import KnownDomain
from pretix.presale.style import get_fonts
@@ -178,7 +180,33 @@ class OrganizerDisplaySettingsForm(SettingsForm):
required=False,
validators=[
RegexValidator(regex='^#[0-9a-fA-F]{6}$',
message=_('Please enter the hexadecimal code of a color, e.g. #990000.'))
message=_('Please enter the hexadecimal code of a color, e.g. #990000.')),
ColorContrastValidator()
],
widget=forms.TextInput(attrs={'class': 'colorpickerfield'})
)
theme_color_success = forms.CharField(
label=_("Accent color for success"),
help_text=_("We strongly suggest to use a dark shade of green that has a good contrast for text on white "
"ground."),
required=False,
validators=[
RegexValidator(regex='^#[0-9a-fA-F]{6}$',
message=_('Please enter the hexadecimal code of a color, e.g. #990000.')),
ColorContrastValidator()
],
widget=forms.TextInput(attrs={'class': 'colorpickerfield'})
)
theme_color_danger = forms.CharField(
label=_("Accent color for errors"),
help_text=_("We strongly suggest to use a dark shade of red that has a good contrast for text on white "
"ground."),
required=False,
validators=[
RegexValidator(regex='^#[0-9a-fA-F]{6}$',
message=_('Please enter the hexadecimal code of a color, e.g. #990000.')),
ColorContrastValidator()
],
widget=forms.TextInput(attrs={'class': 'colorpickerfield'})
)

View File

@@ -20,8 +20,10 @@
<fieldset>
<legend>{% trans "Shop design" %}</legend>
{% url "control:organizer.display" organizer=request.organizer.slug as org_url %}
{% propagated request.event org_url "primary_color" "primary_font" %}
{% propagated request.event org_url "primary_color" "primary_font" "theme_color_success" "theme_color_danger" %}
{% bootstrap_field form.primary_color layout="control" %}
{% bootstrap_field form.theme_color_success layout="control" %}
{% bootstrap_field form.theme_color_danger layout="control" %}
{% bootstrap_field form.primary_font layout="control" %}
{% endpropagated %}
</fieldset>

View File

@@ -23,6 +23,8 @@
{% endblocktrans %}
</p>
{% bootstrap_field form.primary_color layout="control" %}
{% bootstrap_field form.theme_color_success layout="control" %}
{% bootstrap_field form.theme_color_danger layout="control" %}
{% bootstrap_field form.primary_font layout="control" %}
</fieldset>
<div class="form-group submit-group">

View File

@@ -40,6 +40,10 @@ def compile_scss(object, file="main.scss", fonts=True):
sassrules = []
if object.settings.get('primary_color'):
sassrules.append('$brand-primary: {};'.format(object.settings.get('primary_color')))
if object.settings.get('theme_color_success'):
sassrules.append('$brand-success: {};'.format(object.settings.get('theme_color_success')))
if object.settings.get('theme_color_danger'):
sassrules.append('$brand-danger: {};'.format(object.settings.get('theme_color_danger')))
font = object.settings.get('primary_font')
if font != 'Open Sans' and fonts:

View File

@@ -18,10 +18,10 @@ $text-color: #222222;
$text-muted: #999999;
$brand-primary: #7f5a91 !default;
$brand-success: #50a167;
$brand-info: #5f9cd4;
$brand-warning: #ffb419;
$brand-danger: #d36060;
$brand-success: #50a167 !default;
$brand-info: #5f9cd4 !default;
$brand-warning: #ffb419 !default;
$brand-danger: #d36060 !default;
$btn-default-border: #CCCCCC;