Commit 29a93b8c authored by webchick's avatar webchick

#693504 by stBorchert, ksenzee, dixon_ | jarek, joachim, EvanDonovan,...

#693504 by stBorchert, ksenzee, dixon_ | jarek, joachim, EvanDonovan, eigentor, sun, dmitrig01, et al.: Added support to color.module for flexible color schemes and gradients, and removed hard-coded assumptions about Garland.
parent 7817a0a5
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
Drupal.behaviors.color = { Drupal.behaviors.color = {
attach: function (context, settings) { attach: function (context, settings) {
var i, colors, field_name;
// This behavior attaches by ID, so is only valid once on a page. // This behavior attaches by ID, so is only valid once on a page.
var form = $('#system-theme-settings .color-form', context).once('color'); var form = $('#system-theme-settings .color-form', context).once('color');
if (form.length == 0) { if (form.length == 0) {
...@@ -24,11 +25,23 @@ Drupal.behaviors.color = { ...@@ -24,11 +25,23 @@ Drupal.behaviors.color = {
} }
// Build a preview. // Build a preview.
$('#preview').once('color').append('<div id="gradient"></div>'); var height = [];
var gradient = $('#preview #gradient'); var width = [];
var h = parseInt(gradient.css('height'), 10) / 10; // Loop through all defined gradients.
for (i = 0; i < h; ++i) { for (i in settings.gradients) {
gradient.append('<div class="gradient-line"></div>'); // Add element to display the gradient.
$('#preview').once('color').append('<div id="gradient-' + i + '"></div>');
var gradient = $('#preview #gradient-' + i);
// Add height of current gradient to the list (divided by 10).
height.push(parseInt(gradient.css('height'), 10) / 10);
// Add width of current gradient to the list (divided by 10).
width.push(parseInt(gradient.css('width'), 10) / 10);
// Add rows (or columns for horizontal gradients).
// Each gradient line should have a height (or width for horizontal
// gradients) of 10px (because we divided the height/width by 10 above).
for (j = 0; j < (settings.gradients[i]['direction'] == 'vertical' ? height[i] : width[i]); ++j) {
gradient.append('<div class="gradient-line"></div>');
}
} }
// Fix preview background in IE6. // Fix preview background in IE6.
...@@ -39,13 +52,14 @@ Drupal.behaviors.color = { ...@@ -39,13 +52,14 @@ Drupal.behaviors.color = {
e.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image.substring(5, image.length - 2) + "')"; e.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image.substring(5, image.length - 2) + "')";
} }
// Set up colorscheme selector. // Set up colorScheme selector.
$('#edit-scheme', form).change(function () { $('#edit-scheme', form).change(function () {
var colors = this.options[this.selectedIndex].value; var schemes = settings.color.schemes, colorScheme = this.options[this.selectedIndex].value;
if (colors != '') { if (colorScheme != '' && schemes[colorScheme]) {
colors = colors.split(','); // Get colors of active scheme.
for (i in colors) { colors = schemes[colorScheme];
callback(inputs[i], colors[i], false, true); for (field_name in colors) {
callback($('#edit-palette-' + field_name), colors[field_name], false, true);
} }
preview(); preview();
} }
...@@ -56,29 +70,31 @@ Drupal.behaviors.color = { ...@@ -56,29 +70,31 @@ Drupal.behaviors.color = {
*/ */
function preview() { function preview() {
// Solid background. // Solid background.
$('#preview', form).css('backgroundColor', inputs[0].value); $('#preview', form).css('backgroundColor', $('#palette input[name="palette[base]"]', form).val());
// Text preview // Text preview
$('#text', form).css('color', inputs[4].value); $('#text', form).css('color', $('#palette input[name="palette[text]"]', form).val());
$('#text a, #text h2', form).css('color', inputs[1].value); $('#text a, #text h2', form).css('color', $('#palette input[name="palette[link]"]', form).val());
// Set up gradient. // Set up gradients if there are some.
var top = farb.unpack(inputs[2].value); var color_start, color_end;
var bottom = farb.unpack(inputs[3].value); for (i in settings.gradients) {
if (top && bottom) { color_start = farb.unpack($('#palette input[name="palette[' + settings.gradients[i]['colors'][0] + ']"]', form).val());
var delta = []; color_end = farb.unpack($('#palette input[name="palette[' + settings.gradients[i]['colors'][1] + ']"]', form).val());
for (i in top) { if (color_start && color_end) {
delta[i] = (bottom[i] - top[i]) / h; var delta = [];
} for (j in color_start) {
var accum = top; delta[j] = (color_end[j] - color_start[j]) / (settings.gradients[i]['vertical'] ? height[i] : width[i]);
// Render gradient lines.
$('#gradient > div', form).each(function () {
for (i in accum) {
accum[i] += delta[i];
} }
this.style.backgroundColor = farb.pack(accum); var accum = color_start;
}); // Render gradient lines.
$('#gradient-' + i + ' > div', form).each(function () {
for (j in accum) {
accum[j] += delta[j];
}
this.style.backgroundColor = farb.pack(accum);
});
}
} }
} }
...@@ -132,7 +148,8 @@ Drupal.behaviors.color = { ...@@ -132,7 +148,8 @@ Drupal.behaviors.color = {
/** /**
* Callback for Farbtastic when a new color is chosen. * Callback for Farbtastic when a new color is chosen.
*/ */
function callback(input, color, propagate, colorscheme) { function callback(input, color, propagate, colorScheme) {
var i, j, matched;
// Set background/foreground colors. // Set background/foreground colors.
$(input).css({ $(input).css({
backgroundColor: color, backgroundColor: color,
...@@ -140,20 +157,20 @@ Drupal.behaviors.color = { ...@@ -140,20 +157,20 @@ Drupal.behaviors.color = {
}); });
// Change input value. // Change input value.
if (input.value && input.value != color) { if ($(input).val() && $(input).val() != color) {
input.value = color; $(input).val(color);
// Update locked values. // Update locked values.
if (propagate) { if (propagate) {
var i = input.i; i = input.i;
for (j = i + 1; ; ++j) { for (j = i + 1; ; ++j) {
if (!locks[j - 1] || $(locks[j - 1]).is('.unlocked')) break; if (!locks[j - 1] || $(locks[j - 1]).is('.unlocked')) break;
var matched = shift_color(color, reference[input.key], reference[inputs[j].key]); matched = shift_color(color, reference[input.key], reference[inputs[j].key]);
callback(inputs[j], matched, false); callback(inputs[j], matched, false);
} }
for (j = i - 1; ; --j) { for (j = i - 1; ; --j) {
if (!locks[j] || $(locks[j]).is('.unlocked')) break; if (!locks[j] || $(locks[j]).is('.unlocked')) break;
var matched = shift_color(color, reference[input.key], reference[inputs[j].key]); matched = shift_color(color, reference[input.key], reference[inputs[j].key]);
callback(inputs[j], matched, false); callback(inputs[j], matched, false);
} }
...@@ -161,8 +178,8 @@ Drupal.behaviors.color = { ...@@ -161,8 +178,8 @@ Drupal.behaviors.color = {
preview(); preview();
} }
// Reset colorscheme selector. // Reset colorScheme selector.
if (!colorscheme) { if (!colorScheme) {
resetScheme(); resetScheme();
} }
} }
......
...@@ -128,12 +128,8 @@ function color_get_info($theme) { ...@@ -128,12 +128,8 @@ function color_get_info($theme) {
*/ */
function color_get_palette($theme, $default = FALSE) { function color_get_palette($theme, $default = FALSE) {
// Fetch and expand default palette. // Fetch and expand default palette.
$fields = array('base', 'link', 'top', 'bottom', 'text');
$info = color_get_info($theme); $info = color_get_info($theme);
$keys = array_keys($info['schemes']); $palette = $info['schemes']['default']['colors'];
foreach (explode(',', array_shift($keys)) as $k => $scheme) {
$palette[$fields[$k]] = $scheme;
}
// Load variable. // Load variable.
return $default ? $palette : variable_get('color_' . $theme . '_palette', $palette); return $default ? $palette : variable_get('color_' . $theme . '_palette', $palette);
...@@ -146,18 +142,39 @@ function color_scheme_form($complete_form, &$form_state, $theme) { ...@@ -146,18 +142,39 @@ function color_scheme_form($complete_form, &$form_state, $theme) {
$base = drupal_get_path('module', 'color'); $base = drupal_get_path('module', 'color');
$info = color_get_info($theme); $info = color_get_info($theme);
$info['schemes'][''] = array('title' => t('Custom'), 'colors' => array());
$color_sets = array();
$schemes = array();
foreach ($info['schemes'] as $key => $scheme) {
$color_sets[$key] = $scheme['title'];
$schemes[$key] = $scheme['colors'];
$schemes[$key] += $info['schemes']['default']['colors'];
}
// See if we're using a predefined scheme. // See if we're using a predefined scheme.
$current = implode(',', variable_get('color_' . $theme . '_palette', array()));
// Note: we use the original theme when the default scheme is chosen. // Note: we use the original theme when the default scheme is chosen.
$current = isset($info['schemes'][$current]) ? $current : ($current == '' ? reset($info['schemes']) : ''); $current_scheme = variable_get('color_' . $theme . '_palette', array());
foreach ($schemes as $key => $scheme) {
if ($current_scheme == $scheme) {
$scheme_name = $key;
break;
}
}
if (empty($scheme_name)) {
if (empty($current_scheme)) {
$scheme_name = 'default';
}
else {
$scheme_name = '';
}
}
// Add scheme selector. // Add scheme selector.
$info['schemes'][''] = t('Custom');
$form['scheme'] = array( $form['scheme'] = array(
'#type' => 'select', '#type' => 'select',
'#title' => t('Color set'), '#title' => t('Color set'),
'#options' => $info['schemes'], '#options' => $color_sets,
'#default_value' => $current, '#default_value' => $scheme_name,
'#attached' => array( '#attached' => array(
// Add Farbtastic color picker. // Add Farbtastic color picker.
'library' => array( 'library' => array(
...@@ -172,7 +189,11 @@ function color_scheme_form($complete_form, &$form_state, $theme) { ...@@ -172,7 +189,11 @@ function color_scheme_form($complete_form, &$form_state, $theme) {
$base . '/color.js', $base . '/color.js',
array( array(
'data' => array( 'data' => array(
'color' => array('reference' => color_get_palette($theme, TRUE)), 'color' => array(
'reference' => color_get_palette($theme, TRUE),
'schemes' => $schemes,
),
'gradients' => $info['gradients'],
), ),
'type' => 'setting', 'type' => 'setting',
), ),
...@@ -182,21 +203,17 @@ function color_scheme_form($complete_form, &$form_state, $theme) { ...@@ -182,21 +203,17 @@ function color_scheme_form($complete_form, &$form_state, $theme) {
// Add palette fields. // Add palette fields.
$palette = color_get_palette($theme); $palette = color_get_palette($theme);
$names = array( $names = $info['fields'];
'base' => t('Base color'),
'link' => t('Link color'),
'top' => t('Header top'),
'bottom' => t('Header bottom'),
'text' => t('Text color'),
);
$form['palette']['#tree'] = TRUE; $form['palette']['#tree'] = TRUE;
foreach ($palette as $name => $value) { foreach ($palette as $name => $value) {
$form['palette'][$name] = array( if (isset($names[$name])) {
'#type' => 'textfield', $form['palette'][$name] = array(
'#title' => $names[$name], '#type' => 'textfield',
'#default_value' => $value, '#title' => $names[$name],
'#size' => 8, '#default_value' => $value,
); '#size' => 8,
);
}
} }
$form['theme'] = array('#type' => 'value', '#value' => $theme); $form['theme'] = array('#type' => 'value', '#value' => $theme);
$form['info'] = array('#type' => 'value', '#value' => $info); $form['info'] = array('#type' => 'value', '#value' => $info);
...@@ -251,10 +268,12 @@ function color_scheme_form_submit($form, &$form_state) { ...@@ -251,10 +268,12 @@ function color_scheme_form_submit($form, &$form_state) {
// Resolve palette. // Resolve palette.
$palette = $form_state['values']['palette']; $palette = $form_state['values']['palette'];
if ($form_state['values']['scheme'] != '') { if ($form_state['values']['scheme'] != '') {
$scheme = explode(',', $form_state['values']['scheme']); foreach ($palette as $key => $color) {
foreach ($palette as $k => $color) { if (isset($info['schemes'][$form_state['values']['scheme']]['colors'][$key])) {
$palette[$k] = array_shift($scheme); $palette[$key] = $info['schemes'][$form_state['values']['scheme']]['colors'][$key];
}
} }
$palette += $info['schemes']['default']['colors'];
} }
// Make sure enough memory is available, if PHP's memory limit is compiled in. // Make sure enough memory is available, if PHP's memory limit is compiled in.
...@@ -450,7 +469,6 @@ function _color_save_stylesheet($file, $style, &$paths) { ...@@ -450,7 +469,6 @@ function _color_save_stylesheet($file, $style, &$paths) {
* Render images that match a given palette. * Render images that match a given palette.
*/ */
function _color_render_images($theme, &$info, &$paths, $palette) { function _color_render_images($theme, &$info, &$paths, $palette) {
// Prepare template image. // Prepare template image.
$source = $paths['source'] . '/' . $info['base_image']; $source = $paths['source'] . '/' . $info['base_image'];
$source = imagecreatefrompng($source); $source = imagecreatefrompng($source);
...@@ -466,10 +484,23 @@ function _color_render_images($theme, &$info, &$paths, $palette) { ...@@ -466,10 +484,23 @@ function _color_render_images($theme, &$info, &$paths, $palette) {
imagefilledrectangle($target, $fill[0], $fill[1], $fill[0] + $fill[2], $fill[1] + $fill[3], _color_gd($target, $palette[$color])); imagefilledrectangle($target, $fill[0], $fill[1], $fill[0] + $fill[2], $fill[1] + $fill[3], _color_gd($target, $palette[$color]));
} }
// Render gradient. // Render gradients.
for ($y = 0; $y < $info['gradient'][3]; ++$y) { foreach ($info['gradients'] as $gradient) {
$color = _color_blend($target, $palette['top'], $palette['bottom'], $y / ($info['gradient'][3] - 1)); // Get direction of the gradient.
imagefilledrectangle($target, $info['gradient'][0], $info['gradient'][1] + $y, $info['gradient'][0] + $info['gradient'][2], $info['gradient'][1] + $y + 1, $color); if (isset($gradient['direction']) && $gradient['direction'] == 'horizontal') {
// Horizontal gradient.
for ($x = 0; $x < $gradient['dimension'][2]; $x++) {
$color = _color_blend($target, $palette[$gradient['colors'][0]], $palette[$gradient['colors'][1]], $x / ($gradient['dimension'][2] - 1));
imagefilledrectangle($target, ($gradient['dimension'][0] + $x), $gradient['dimension'][1], ($gradient['dimension'][0] + $x + 1), ($gradient['dimension'][1] + $gradient['dimension'][3]), $color);
}
}
else {
// Vertical gradient.
for ($y = 0; $y < $gradient['dimension'][3]; $y++) {
$color = _color_blend($target, $palette[$gradient['colors'][0]], $palette[$gradient['colors'][1]], $y / ($gradient['dimension'][3] - 1));
imagefilledrectangle($target, $gradient['dimension'][0], $gradient['dimension'][1] + $y, $gradient['dimension'][0] + $gradient['dimension'][2], $gradient['dimension'][1] + $y + 1, $color);
}
}
} }
// Blend over template. // Blend over template.
......
...@@ -45,6 +45,18 @@ class ColorTestCase extends DrupalWebTestCase { ...@@ -45,6 +45,18 @@ class ColorTestCase extends DrupalWebTestCase {
$stylesheet_content = join("\n", file($stylesheets[0])); $stylesheet_content = join("\n", file($stylesheets[0]));
$matched = preg_match('/(.*color: #123456.*)/i', $stylesheet_content, $matches); $matched = preg_match('/(.*color: #123456.*)/i', $stylesheet_content, $matches);
$this->assertTrue($matched == 1, 'Make sure the color we changed is in the color stylesheet.'); $this->assertTrue($matched == 1, 'Make sure the color we changed is in the color stylesheet.');
$this->drupalGet('admin/appearance/settings/garland');
$this->assertResponse(200);
$edit['scheme'] = 'greenbeam';
$this->drupalPost('admin/appearance/settings/garland', $edit, t('Save configuration'));
$this->drupalGet('<front>');
$stylesheets = variable_get('color_' . $theme_key . '_stylesheets', array());
$stylesheet_content = join("\n", file($stylesheets[0]));
$matched = preg_match('/(.*color: #0c7a00.*)/i', $stylesheet_content, $matches);
$this->assertTrue($matched == 1, 'Make sure the color we changed is in the color stylesheet.');
} }
} }
...@@ -3,23 +3,160 @@ ...@@ -3,23 +3,160 @@
$info = array( $info = array(
// Available colors and color labels used in theme.
'fields' => array(
'base' => t('Base color'),
'link' => t('Link color'),
'top' => t('Header top'),
'bottom' => t('Header bottom'),
'text' => t('Text color'),
),
// Pre-defined color schemes. // Pre-defined color schemes.
'schemes' => array( 'schemes' => array(
'#0072b9,#027ac6,#2385c2,#5ab5ee,#494949' => t('Blue Lagoon (Default)'), 'default' => array(
'#464849,#2f416f,#2a2b2d,#5d6779,#494949' => t('Ash'), 'title' => t('Blue Lagoon (Default)'),
'#55c0e2,#000000,#085360,#007e94,#696969' => t('Aquamarine'), 'colors' => array(
'#d5b048,#6c420e,#331900,#971702,#494949' => t('Belgian Chocolate'), 'base' => '#0072b9',
'#3f3f3f,#336699,#6598cb,#6598cb,#000000' => t('Bluemarine'), 'link' => '#027ac6',
'#d0cb9a,#917803,#efde01,#e6fb2d,#494949' => t('Citrus Blast'), 'top' => '#2385c2',
'#0f005c,#434f8c,#4d91ff,#1a1575,#000000' => t('Cold Day'), 'bottom' => '#5ab5ee',
'#c9c497,#0c7a00,#03961e,#7be000,#494949' => t('Greenbeam'), 'text' => '#494949',
'#ffe23d,#a9290a,#fc6d1d,#a30f42,#494949' => t('Mediterrano'), ),
'#788597,#3f728d,#a9adbc,#d4d4d4,#707070' => t('Mercury'), ),
'#5b5fa9,#5b5faa,#0a2352,#9fa8d5,#494949' => t('Nocturnal'), 'ash' => array(
'#7db323,#6a9915,#b5d52a,#7db323,#191a19' => t('Olivia'), 'title' => t('Ash'),
'#12020b,#1b1a13,#f391c6,#f41063,#898080' => t('Pink Plastic'), 'colors' => array(
'#b7a0ba,#c70000,#a1443a,#f21107,#515d52' => t('Shiny Tomato'), 'base' => '#464849',
'#18583d,#1b5f42,#34775a,#52bf90,#2d2d2d' => t('Teal Top'), 'link' => '#2f416f',
'top' => '#2a2b2d',
'bottom' => '#5d6779',
),
),
'aquamarine' => array(
'title' => t('Aquamarine'),
'colors' => array(
'base' => '#55c0e2',
'link' => '#000000',
'text' => '#696969',
'top' => '#085360',
'bottom' => '#007e94',
),
),
'chocolate' => array(
'title' => t('Belgian Chocolate'),
'colors' => array(
'base' => '#d5b048',
'link' => '#6c420e',
'top' => '#331900',
'bottom' => '#971702',
),
),
'bluemarine' => array(
'title' => t('Bluemarine'),
'colors' => array(
'base' => '#3f3f3f',
'link' => '#336699',
'text' => '#000000',
'top' => '#6598cb',
'bottom' => '#6598cb',
),
),
'citrus' => array(
'title' => t('Citrus Blast'),
'colors' => array(
'base' => '#d0cb9a',
'link' => '#917803',
'top' => '#efde01',
'bottom' => '#e6fb2d',
),
),
'cold' => array(
'title' => t('Cold Day'),
'colors' => array(
'base' => '#0f005c',
'link' => '#434f8c',
'text' => '#000000',
'top' => '#4d91ff',
'bottom' => '#1a1575',
),
),
'greenbeam' => array(
'title' => t('Greenbeam'),
'colors' => array(
'base' => '#c9c497',
'link' => '#0c7a00',
'top' => '#03961e',
'bottom' => '#7be000',
),
),
'mediterrano' => array(
'title' => t('Mediterrano'),
'colors' => array(
'base' => '#ffe23d',
'link' => '#a9290a',
'top' => '#fc6d1d',
'bottom' => '#a30f42',
),
),
'mercury' => array(
'title' => t('Mercury'),
'colors' => array(
'base' => '#788597',
'link' => '#3f728d',
'top' => '#a9adbc',
'bottom' => '#d4d4d4',
'text' => '#707070',
),
),
'nocturnal' => array(
'title' => t('Nocturnal'),
'colors' => array(
'base' => '#5b5fa9',
'link' => '#5b5faa',
'top' => '#0a2352',
'bottom' => '#9fa8d5',
),
),
'olivia' => array(
'title' => t('Olivia'),
'colors' => array(
'base' => '#7db323',
'link' => '#6a9915',
'top' => '#b5d52a',
'bottom' => '#7db323',
'text' => '#191a19',
),
),
'pink_plastic' => array(
'title' => t('Pink Plastic'),
'colors' => array(
'base' => '#12020b',
'link' => '#1b1a13',
'top' => '#f391c6',
'bottom' => '#f41063',
'text' => '#898080',
),
),
'shiny_tomato' => array(
'title' => t('Shiny Tomato'),
'colors' => array(
'base' => '#b7a0ba',
'link' => '#c70000',
'top' => '#a1443a',
'bottom' => '#f21107',
'text' => '#515d52',
),
),
'teal_top' => array(
'title' => t('Teal Top'),
'colors' => array(
'base' => '#18583d',
'link' => '#1b5f42',
'top' => '#34775a',
'bottom' => '#52bf90',
'text' => '#2d2d2d',
),
),
), ),
// Images to copy over. // Images to copy over.
...@@ -35,8 +172,17 @@ ...@@ -35,8 +172,17 @@
'style.css', 'style.css',
), ),
// Coordinates of gradient (x, y, width, height). // Gradient definitions.
'gradient' => array(0, 37, 760, 121), 'gradients' => array(
array(
// (x, y, width, height).
'dimension' => array(0, 38, 760, 121),
// Direction of gradient ('vertical' or 'horizontal').
'direction' => 'vertical',
// Keys of colors to use for the gradient.
'colors' => array('top', 'bottom'),
),
),
// Color areas to fill (x, y, width, height). // Color areas to fill (x, y, width, height).
'fill' => array( 'fill' => array(
......
...@@ -6,10 +6,10 @@ ...@@ -6,10 +6,10 @@
max-width: 100%; max-width: 100%;
} }
#preview, #preview #img { #preview, #preview #img {
width: 596px; width: 600px;
height: 371px; height: 371px;
} }
#preview #gradient { #preview #gradient-0 {
position: absolute; position: absolute;
left: 0; left: 0;
right: 0; right: 0;
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
position: relative; position: relative;
z-index: 3; z-index: 3;
} }
#preview #gradient .gradient-line { #preview #gradient-0 .gradient-line {
height: 10px; height: 10px;
overflow: hidden; overflow: hidden;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment