Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
0.00% |
0 / 1 |
|
0.00% |
0 / 17 |
CRAP | |
0.00% |
0 / 1000 |
ctools_get_style_base | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 2 |
|||
ctools_get_style_bases | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 2 |
|||
ctools_get_style_base_types | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 5 |
|||
ctools_stylizer_print_style_icon | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 3 |
|||
theme_ctools_style_icon | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 10 |
|||
ctools_stylizer_add_css | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 10 |
|||
ctools_stylizer_build_style | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 29 |
|||
ctools_stylizer_cleanup_style | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 7 |
|||
ctools_stylizer_recursive_delete | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 13 |
|||
ctools_stylizer_get_settings_name | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 3 |
|||
ctools_stylizer_get_image_path | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 5 |
|||
ctools_stylizer_get_css_id | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 1 |
|||
ctools_stylizer_get_css_class | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 2 |
|||
ctools_stylizer_get_settings_cache | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 2 |
|||
ctools_stylizer_set_settings_cache | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 3 |
|||
ctools_stylizer_clear_settings_cache | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 3 |
|||
ctools_stylizer_edit_style | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 87 |
|||
ctools_stylizer_add_plugin_forms | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 15 |
|||
ctools_stylizer_edit_style_finish | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 6 |
|||
ctools_stylizer_edit_style_next | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 8 |
|||
ctools_stylizer_edit_style_cancel | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 4 |
|||
ctools_stylizer_edit_style_form_choose | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 32 |
|||
ctools_stylizer_edit_style_form_choose_submit | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 11 |
|||
ctools_stylizer_edit_style_form_default | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 42 |
|||
theme_ctools_stylizer_color_scheme_form | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 10 |
|||
theme_ctools_stylizer_preview_form | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 21 |
|||
ctools_stylizer_edit_style_form_default_validate | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 7 |
|||
ctools_stylizer_edit_style_form_default_submit | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 19 |
|||
ctools_stylizer_font_selector_form | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 203 |
|||
ctools_stylizer_font_selector_form_submit | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 2 |
|||
ctools_stylizer_font_apply_style | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 35 |
|||
ctools_stylizer_border_selector_form | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 32 |
|||
ctools_stylizer_border_selector_form_submit | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 2 |
|||
ctools_stylizer_border_apply_style | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 19 |
|||
ctools_stylizer_padding_selector_form | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 107 |
|||
ctools_stylizer_padding_selector_form_submit | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 2 |
|||
ctools_stylizer_padding_apply_style | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 17 |
|||
ctools_stylizer_image_processor | |
0.00% |
0 / 1 |
|
0.00% |
0 / 17 |
3306 | |
0.00% |
0 / 219 |
execute | |
0.00% |
0 / 1 |
90 | |
0.00% |
0 / 22 |
|||
log | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 5 |
|||
set_current_workspace | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 4 |
|||
command_new | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 11 |
|||
command_load | |
0.00% |
0 / 1 |
20 | |
0.00% |
0 / 13 |
|||
command_new_from | |
0.00% |
0 / 1 |
12 | |
0.00% |
0 / 10 |
|||
command_workspace | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 6 |
|||
command_merge_from | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 6 |
|||
command_merge_to | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 7 |
|||
command_merge_from_file | |
0.00% |
0 / 1 |
12 | |
0.00% |
0 / 11 |
|||
command_fill | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 3 |
|||
command_gradient | |
0.00% |
0 / 1 |
20 | |
0.00% |
0 / 12 |
|||
command_colorize | |
0.00% |
0 / 1 |
56 | |
0.00% |
0 / 21 |
|||
command_hue | |
0.00% |
0 / 1 |
72 | |
0.00% |
0 / 44 |
|||
command_slice | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 19 |
|||
new_image | |
0.00% |
0 / 1 |
20 | |
0.00% |
0 / 19 |
|||
merge | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 6 |
<?php | |
/** | |
* @file | |
* Create customized CSS and images from palettes created by user input. | |
*/ | |
/** | |
* Fetch metadata on a specific style_base plugin. | |
* | |
* @param $content type | |
* Name of a panel content type. | |
* | |
* @return | |
* An array with information about the requested stylizer style base. | |
*/ | |
function ctools_get_style_base($style_base) { | |
ctools_include('plugins'); | |
return ctools_get_plugins('stylizer', 'style_bases', $style_base); | |
} | |
/** | |
* Fetch metadata for all style_base plugins. | |
* | |
* @return | |
* An array of arrays with information about all available styleizer style bases. | |
*/ | |
function ctools_get_style_bases() { | |
ctools_include('plugins'); | |
return ctools_get_plugins('stylizer', 'style_bases'); | |
} | |
/** | |
* Fetch metadata about all of the style base types that are available. | |
*/ | |
function ctools_get_style_base_types() { | |
$types = array(); | |
foreach (module_implements('ctools_style_base_types') as $module) { | |
$types[$module] = module_invoke($module, 'ctools_style_base_types'); | |
} | |
return $types; | |
} | |
/** | |
* Render the icon for a style base. | |
*/ | |
function ctools_stylizer_print_style_icon($plugin, $print_title = TRUE) { | |
$file = $plugin['path'] . '/' . $plugin['icon']; | |
$title = $print_title ? $plugin['title'] : ''; | |
return theme('ctools_style_icon', array('image' => theme('image', array('path' => $file)), 'title' => $title)); | |
} | |
/** | |
* Theme the style icon image | |
*/ | |
function theme_ctools_style_icon($vars) { | |
$image = $vars['image']; | |
ctools_add_css('stylizer'); | |
ctools_add_js('stylizer'); | |
$output = '<div class="ctools-style-icon">'; | |
$output .= $vars['image']; | |
if ($vars['title']) { | |
$output .= '<div class="caption">' . $vars['title'] . '</div>'; | |
} | |
$output .= '</div>'; | |
return $output; | |
} | |
/** | |
* Add the necessary CSS for a stylizer plugin to the page. | |
* | |
* This will check to see if the images directory and the cached CSS | |
* exists and, if not, will regenerate everything needed. | |
*/ | |
function ctools_stylizer_add_css($plugin, $settings) { | |
if (!file_exists(ctools_stylizer_get_image_path($plugin, $settings, FALSE))) { | |
ctools_stylizer_build_style($plugin, $settings, TRUE); | |
return; | |
} | |
ctools_include('css'); | |
$filename = ctools_css_retrieve(ctools_stylizer_get_css_id($plugin, $settings)); | |
if (!$filename) { | |
ctools_stylizer_build_style($plugin, $settings, TRUE); | |
} | |
else { | |
drupal_add_css($filename); | |
} | |
} | |
/** | |
* Build the files for a stylizer given the proper settings. | |
*/ | |
function ctools_stylizer_build_style($plugin, $settings, $add_css = FALSE) { | |
$path = ctools_stylizer_get_image_path($plugin, $settings); | |
if (!$path) { | |
return; | |
} | |
$replacements = array(); | |
// Set up palette conversions | |
foreach ($settings['palette'] as $key => $color) { | |
$replacements['%' . $key ] = $color; | |
} | |
// Process image actions: | |
if (!empty($plugin['actions'])) { | |
$processor = new ctools_stylizer_image_processor; | |
$processor->execute($path, $plugin, $settings); | |
// @todo -- there needs to be an easier way to get at this. | |
// dsm($processor->message_log); | |
// Add filenames to our conversions. | |
} | |
// Convert and write the CSS file. | |
$css = file_get_contents($plugin['path'] . '/' . $plugin['css']); | |
// Replace %style keyword with our generated class name. | |
// @todo We need one more unique identifier I think. | |
$class = ctools_stylizer_get_css_class($plugin, $settings); | |
$replacements['%style'] = '.' . $class; | |
if (!empty($processor) && !empty($processor->paths)) { | |
foreach ($processor->paths as $file => $image) { | |
$replacements[$file] = file_create_url($image); | |
} | |
} | |
if (!empty($plugin['build']) && function_exists($plugin['build'])) { | |
$plugin['build']($plugin, $settings, $css, $replacements); | |
} | |
$css = strtr($css, $replacements); | |
ctools_include('css'); | |
$filename = ctools_css_store(ctools_stylizer_get_css_id($plugin, $settings), $css, FALSE); | |
if ($add_css) { | |
drupal_add_css($filename); | |
} | |
} | |
/** | |
* Clean up no longer used files. | |
* | |
* To prevent excess clutter in the files directory, this should be called | |
* whenever a style is going out of use. When being deleted, but also when | |
* the palette is being changed. | |
*/ | |
function ctools_stylizer_cleanup_style($plugin, $settings) { | |
ctools_include('css'); | |
$path = ctools_stylizer_get_image_path($plugin, $settings, FALSE); | |
if ($path) { | |
ctools_stylizer_recursive_delete($path); | |
} | |
ctools_css_clear(ctools_stylizer_get_css_id($plugin, $settings)); | |
} | |
/** | |
* Recursively delete all files and folders in the specified filepath, then | |
* delete the containing folder. | |
* | |
* Note that this only deletes visible files with write permission. | |
* | |
* @param string $path | |
* A filepath relative to file_directory_path. | |
*/ | |
function ctools_stylizer_recursive_delete($path) { | |
if (empty($path)) { | |
return; | |
} | |
$listing = $path . '/*'; | |
foreach (glob($listing) as $file) { | |
if (is_file($file) === TRUE) { | |
@unlink($file); | |
} | |
elseif (is_dir($file) === TRUE) { | |
ctools_stylizer_recursive_delete($file); | |
} | |
} | |
@rmdir($path); | |
} | |
/** | |
* Get a safe name for the settings. | |
* | |
* This uses an md5 of the palette if the name is temporary so | |
* that multiple temporary styles on the same page can coexist | |
* safely. | |
*/ | |
function ctools_stylizer_get_settings_name($settings) { | |
if ($settings['name'] != '_temporary') { | |
return $settings['name']; | |
} | |
return $settings['name'] . '-' . md5(serialize($settings['palette'])); | |
} | |
/** | |
* Get the path where images will be stored for a given style plugin and settings. | |
* | |
* This function will make sure the path exists. | |
*/ | |
function ctools_stylizer_get_image_path($plugin, $settings, $check = TRUE) { | |
$path = 'public://ctools/style/' . $settings['name'] . '/' . md5(serialize($settings['palette'])); | |
if (!file_prepare_directory($path, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) { | |
drupal_set_message(t('Unable to create CTools styles cache directory @path. Check the permissions on your files directory.', array('@path' => $path)), 'error'); | |
return; | |
} | |
return $path; | |
} | |
/** | |
* Get the id used to cache CSS for a given style plugin and settings. | |
*/ | |
function ctools_stylizer_get_css_id($plugin, $settings) { | |
return 'ctools-stylizer:' . $settings['name'] . ':' . md5(serialize($settings['palette'])); | |
} | |
/** | |
* Get the class to use for a stylizer plugin. | |
*/ | |
function ctools_stylizer_get_css_class($plugin, $settings) { | |
ctools_include('cleanstring'); | |
return ctools_cleanstring($plugin['name'] . '-' . ctools_stylizer_get_settings_name($settings)); | |
} | |
class ctools_stylizer_image_processor { | |
var $workspace = NULL; | |
var $name = NULL; | |
var $workspaces = array(); | |
var $message_log = array(); | |
var $error_log = array(); | |
function execute($path, $plugin, $settings) { | |
$this->path = $path; | |
$this->plugin = $plugin; | |
$this->settings = $settings; | |
$this->palette = $settings['palette']; | |
if (is_string($plugin['actions']) && function_exists($plugin['actions'])) { | |
$actions = $plugin['actions']($plugin, $settings); | |
} | |
else if (is_array($plugin['actions'])) { | |
$actions = $plugin['actions']; | |
} | |
if (!empty($actions) && is_array($actions)) { | |
foreach ($plugin['actions'] as $action) { | |
$command = 'command_' . array_shift($action); | |
if (method_exists($this, $command)) { | |
call_user_func_array(array($this, $command), $action); | |
} | |
} | |
} | |
// Clean up buffers. | |
foreach ($this->workspaces as $name => $workspace) { | |
imagedestroy($this->workspaces[$name]); | |
} | |
} | |
function log($message, $type = 'normal') { | |
$this->message_log[] = $message; | |
if ($type == 'error') { | |
$this->error_log[] = $message; | |
} | |
} | |
function set_current_workspace($workspace) { | |
$this->log("Set current workspace: $workspace"); | |
$this->workspace = &$this->workspaces[$workspace]; | |
$this->name = $workspace; | |
} | |
/** | |
* Create a new workspace. | |
*/ | |
function command_new($name, $width, $height) { | |
$this->log("New workspace: $name ($width x $height)"); | |
// Clean up if there was already a workspace there. | |
if (isset($this->workspaces[$name])) { | |
imagedestroy($this->workspaces[$name]); | |
} | |
$this->workspaces[$name] = imagecreatetruecolor($width, $height); | |
$this->set_current_workspace($name); | |
// Make sure the new workspace has a transparent color. | |
// Turn off transparency blending (temporarily) | |
imagealphablending($this->workspace, FALSE); | |
// Create a new transparent color for image | |
$color = imagecolorallocatealpha($this->workspace, 0, 0, 0, 127); | |
// Completely fill the background of the new image with allocated color. | |
imagefill($this->workspace, 0, 0, $color); | |
// Restore transparency blending | |
imagesavealpha($this->workspace, TRUE); | |
} | |
/** | |
* Create a new workspace a file. | |
* | |
* This will make the new workspace the current workspace. | |
*/ | |
function command_load($name, $file) { | |
$this->log("New workspace: $name (from $file)"); | |
if (!file_exists($file)) { | |
// Try it relative to the plugin | |
$file = $this->plugin['path'] . '/' . $file; | |
if (!file_exists($file)) { | |
$this->log("Unable to open $file"); | |
return; | |
} | |
} | |
// Clean up if there was already a workspace there. | |
if (isset($this->workspaces[$name])) { | |
imagedestroy($this->workspaces[$name]); | |
} | |
$this->workspaces[$name] = imagecreatefrompng($file); | |
$this->set_current_workspace($name); | |
} | |
/** | |
* Create a new workspace using the properties of an existing workspace | |
*/ | |
function command_new_from($name, $workspace) { | |
$this->log("New workspace: $name from existing $workspace"); | |
if (empty($this->workspaces[$workspace])) { | |
$this->log("Workspace $name does not exist.", 'error'); | |
return; | |
} | |
// Clean up if there was already a workspace there. | |
if (isset($this->workspaces[$name])) { | |
imagedestroy($this->workspaces[$name]); | |
} | |
$this->workspaces[$name] = $this->new_image($this->workspace[$workspace]); | |
$this->set_current_workspace($name); | |
} | |
/** | |
* Set the current workspace. | |
*/ | |
function command_workspace($name) { | |
$this->log("Set workspace: $name"); | |
if (empty($this->workspaces[$name])) { | |
$this->log("Workspace $name does not exist.", 'error'); | |
return; | |
} | |
$this->set_current_workspace($name); | |
} | |
/** | |
* Copy the contents of one workspace into the current workspace. | |
*/ | |
function command_merge_from($workspace, $x = 0, $y = 0) { | |
$this->log("Merge from: $workspace ($x, $y)"); | |
if (empty($this->workspaces[$workspace])) { | |
$this->log("Workspace $name does not exist.", 'error'); | |
return; | |
} | |
$this->merge($this->workspaces[$workspace], $this->workspace, $x, $y); | |
} | |
function command_merge_to($workspace, $x = 0, $y = 0) { | |
$this->log("Merge to: $workspace ($x, $y)"); | |
if (empty($this->workspaces[$workspace])) { | |
$this->log("Workspace $name does not exist.", 'error'); | |
return; | |
} | |
$this->merge($this->workspace, $this->workspaces[$workspace], $x, $y); | |
$this->set_current_workspace($workspace); | |
} | |
/** | |
* Blend an image into the current workspace. | |
*/ | |
function command_merge_from_file($file, $x = 0, $y = 0) { | |
$this->log("Merge from file: $file ($x, $y)"); | |
if (!file_exists($file)) { | |
// Try it relative to the plugin | |
$file = $this->plugin['path'] . '/' . $file; | |
if (!file_exists($file)) { | |
$this->log("Unable to open $file"); | |
return; | |
} | |
} | |
$source = imagecreatefrompng($file); | |
$this->merge($source, $this->workspace, $x, $y); | |
imagedestroy($source); | |
} | |
function command_fill($color, $x, $y, $width, $height) { | |
$this->log("Fill: $color ($x, $y, $width, $height)"); | |
imagefilledrectangle($this->workspace, $x, $y, $x + $width, $y + $height, _color_gd($this->workspace, $this->palette[$color])); | |
} | |
function command_gradient($from, $to, $x, $y, $width, $height, $direction = 'down') { | |
$this->log("Gradient: $from to $to ($x, $y, $width, $height) $direction"); | |
if ($direction == 'down') { | |
for ($i = 0; $i < $height; ++$i) { | |
$color = _color_blend($this->workspace, $this->palette[$from], $this->palette[$to], $i / ($height - 1)); | |
imagefilledrectangle($this->workspace, $x, $y + $i, $x + $width, $y + $i + 1, $color); | |
} | |
} | |
else { | |
for ($i = 0; $i < $width; ++$i) { | |
$color = _color_blend($this->workspace, $this->palette[$from], $this->palette[$to], $i / ($width - 1)); | |
imagefilledrectangle($this->workspace, $x + $i, $y, $x + $i + 1, $y + $height, $color); | |
} | |
} | |
} | |
/** | |
* Colorize the current workspace with the given location. | |
* | |
* This uses simple color blending to colorize the image. | |
* | |
* @todo it is possible that this colorize could allow different methods for | |
* determining how to blend colors? | |
*/ | |
function command_colorize($color, $x = NULL, $y = NULL, $width = NULL, $height = NULL) { | |
if (!isset($x)) { | |
$whole_image = TRUE; | |
$x = $y = 0; | |
$width = imagesx($this->workspace); | |
$height = imagesy($this->workspace); | |
} | |
$this->log("Colorize: $color ($x, $y, $width, $height)"); | |
$c = _color_unpack($this->palette[$color]); | |
imagealphablending($this->workspace, FALSE); | |
imagesavealpha($this->workspace, TRUE); | |
// If PHP 5 use the nice imagefilter which is faster. | |
if (!empty($whole_image) && version_compare(phpversion(), '5.2.5', '>=') && function_exists('imagefilter')) { | |
imagefilter($this->workspace, IMG_FILTER_COLORIZE, $c[0], $c[1], $c[2]); | |
} | |
else { | |
// Otherwise we can do it the brute force way. | |
for ($j = 0; $j < $height; $j++) { | |
for ($i = 0; $i < $width; $i++) { | |
$current = imagecolorsforindex($this->workspace, imagecolorat($this->workspace, $i, $j)); | |
$new_index = imagecolorallocatealpha($this->workspace, $c[0], $c[1], $c[2], $current['alpha']); | |
imagesetpixel($this->workspace, $i, $j, $new_index); | |
} | |
} | |
} | |
} | |
/** | |
* Colorize the current workspace with the given location. | |
* | |
* This uses a color replacement algorithm that retains luminosity but | |
* turns replaces all color with the specified color. | |
*/ | |
function command_hue($color, $x = NULL, $y = NULL, $width = NULL, $height = NULL) { | |
if (!isset($x)) { | |
$whole_image = TRUE; | |
$x = $y = 0; | |
$width = imagesx($this->workspace); | |
$height = imagesy($this->workspace); | |
} | |
$this->log("Hue: $color ($x, $y, $width, $height)"); | |
list($red, $green, $blue) = _color_unpack($this->palette[$color]); | |
// We will create a monochromatic palette based on the input color | |
// which will go from black to white. | |
// Input color luminosity: this is equivalent to the position of the | |
// input color in the monochromatic palette | |
$luminosity_input = round(255 * ($red + $green + $blue) / 765); // 765 = 255 * 3 | |
// We fill the palette entry with the input color at itscorresponding position | |
$palette[$luminosity_input]['red'] = $red; | |
$palette[$luminosity_input]['green'] = $green; | |
$palette[$luminosity_input]['blue'] = $blue; | |
// Now we complete the palette, first we'll do it to the black, and then to | |
// the white. | |
// From input to black | |
$steps_to_black = $luminosity_input; | |
// The step size for each component | |
if ($steps_to_black) { | |
$step_size_red = $red / $steps_to_black; | |
$step_size_green = $green / $steps_to_black; | |
$step_size_blue = $blue / $steps_to_black; | |
for ($i = $steps_to_black; $i >= 0; $i--) { | |
$palette[$steps_to_black-$i]['red'] = $red - round($step_size_red * $i); | |
$palette[$steps_to_black-$i]['green'] = $green - round($step_size_green * $i); | |
$palette[$steps_to_black-$i]['blue'] = $blue - round($step_size_blue * $i); | |
} | |
} | |
// From input to white | |
$steps_to_white = 255 - $luminosity_input; | |
if ($steps_to_white) { | |
$step_size_red = (255 - $red) / $steps_to_white; | |
$step_size_green = (255 - $green) / $steps_to_white; | |
$step_size_blue = (255 - $blue) / $steps_to_white; | |
} | |
else { | |
$step_size_red=$step_size_green=$step_size_blue=0; | |
} | |
// The step size for each component | |
for ($i = ($luminosity_input + 1); $i <= 255; $i++) { | |
$palette[$i]['red'] = $red + round($step_size_red * ($i - $luminosity_input)); | |
$palette[$i]['green'] = $green + round($step_size_green * ($i - $luminosity_input)); | |
$palette[$i]['blue']= $blue + round($step_size_blue * ($i - $luminosity_input)); | |
} | |
// Go over the specified area of the image and update the colors. | |
for ($j = $x; $j < $height; $j++) { | |
for ($i = $y; $i < $width; $i++) { | |
$color = imagecolorsforindex($this->workspace, imagecolorat($this->workspace, $i, $j)); | |
$luminosity = round(255 * ($color['red'] + $color['green'] + $color['blue']) / 765); | |
$new_color = imagecolorallocatealpha($this->workspace, $palette[$luminosity]['red'], $palette[$luminosity]['green'], $palette[$luminosity]['blue'], $color['alpha']); | |
imagesetpixel($this->workspace, $i, $j, $new_color); | |
} | |
} | |
} | |
/** | |
* Take a slice out of the current workspace and save it as an image. | |
*/ | |
function command_slice($file, $x = NULL, $y = NULL, $width = NULL, $height = NULL) { | |
if (!isset($x)) { | |
$x = $y = 0; | |
$width = imagesx($this->workspace); | |
$height = imagesy($this->workspace); | |
} | |
$this->log("Slice: $file ($x, $y, $width, $height)"); | |
$base = basename($file); | |
$image = $this->path . '/' . $base; | |
$slice = $this->new_image($this->workspace, $width, $height); | |
imagecopy($slice, $this->workspace, 0, 0, $x, $y, $width, $height); | |
// Make sure alphas are saved: | |
imagealphablending($slice, FALSE); | |
imagesavealpha($slice, TRUE); | |
// Save image. | |
$temp_name = drupal_tempnam('temporary://', 'file'); | |
imagepng($slice, drupal_realpath($temp_name)); | |
file_unmanaged_move($temp_name, $image); | |
imagedestroy($slice); | |
// Set standard file permissions for webserver-generated files | |
@chmod(realpath($image), 0664); | |
$this->paths[$file] = $image; | |
} | |
/** | |
* Prepare a new image for being copied or worked on, preserving transparency. | |
*/ | |
function &new_image(&$source, $width = NULL, $height = NULL) { | |
if (!isset($width)) { | |
$width = imagesx($source); | |
} | |
if (!isset($height)) { | |
$height = imagesy($source); | |
} | |
$target = imagecreatetruecolor($width, $height); | |
imagealphablending($target, FALSE); | |
imagesavealpha($target, TRUE); | |
$transparency_index = imagecolortransparent($source); | |
// If we have a specific transparent color | |
if ($transparency_index >= 0) { | |
// Get the original image's transparent color's RGB values | |
$transparent_color = imagecolorsforindex($source, $transparency_index); | |
// Allocate the same color in the new image resource | |
$transparency_index = imagecolorallocate($target, $transparent_color['red'], $transparent_color['green'], $transparent_color['blue']); | |
// Completely fill the background of the new image with allocated color. | |
imagefill($target, 0, 0, $transparency_index); | |
// Set the background color for new image to transparent | |
imagecolortransparent($target, $transparency_index); | |
} | |
// Always make a transparent background color for PNGs that don't have one allocated already | |
else { | |
// Create a new transparent color for image | |
$color = imagecolorallocatealpha($target, 0, 0, 0, 127); | |
// Completely fill the background of the new image with allocated color. | |
imagefill($target, 0, 0, $color); | |
} | |
return $target; | |
} | |
/** | |
* Merge two images together, preserving alpha transparency. | |
*/ | |
function merge(&$from, &$to, $x, $y) { | |
// Blend over template. | |
$width = imagesx($from); | |
$height = imagesy($from); | |
// Re-enable alpha blending to make sure transparency merges. | |
imagealphablending($to, TRUE); | |
imagecopy($to, $from, $x, $y, 0, 0, $width, $height); | |
imagealphablending($to, FALSE); | |
} | |
} | |
/** | |
* Get the cached changes to a given task handler. | |
*/ | |
function ctools_stylizer_get_settings_cache($name) { | |
ctools_include('object-cache'); | |
return ctools_object_cache_get('ctools_stylizer_settings', $name); | |
} | |
/** | |
* Store changes to a task handler in the object cache. | |
*/ | |
function ctools_stylizer_set_settings_cache($name, $settings) { | |
ctools_include('object-cache'); | |
ctools_object_cache_set('ctools_stylizer_settings', $name, $settings); | |
} | |
/** | |
* Remove an item from the object cache. | |
*/ | |
function ctools_stylizer_clear_settings_cache($name) { | |
ctools_include('object-cache'); | |
ctools_object_cache_clear('ctools_stylizer_settings', $name); | |
} | |
/** | |
* Add a new style of the specified type. | |
*/ | |
function ctools_stylizer_edit_style(&$info, $js, $step = NULL) { | |
$name = '::new'; | |
$form_info = array( | |
'id' => 'ctools_stylizer_edit_style', | |
'path' => $info['path'], | |
'show trail' => TRUE, | |
'show back' => TRUE, | |
'show return' => FALSE, | |
'next callback' => 'ctools_stylizer_edit_style_next', | |
'finish callback' => 'ctools_stylizer_edit_style_finish', | |
'return callback' => 'ctools_stylizer_edit_style_finish', | |
'cancel callback' => 'ctools_stylizer_edit_style_cancel', | |
'forms' => array( | |
'choose' => array( | |
'form id' => 'ctools_stylizer_edit_style_form_choose', | |
), | |
), | |
); | |
if (empty($info['settings'])) { | |
$form_info['order'] = array( | |
'choose' => t('Select base style'), | |
); | |
if (empty($step)) { | |
$step = 'choose'; | |
} | |
if ($step != 'choose') { | |
$cache = ctools_stylizer_get_settings_cache($name); | |
if (!$cache) { | |
$output = t('Missing settings cache.'); | |
if ($js) { | |
return ctools_modal_form_render($form_state, $output); | |
} | |
else { | |
return $output; | |
} | |
} | |
if (!empty($cache['owner settings'])) { | |
$info['owner settings'] = $cache['owner settings']; | |
} | |
$settings = $cache['settings']; | |
} | |
else { | |
$settings = array( | |
'name' => '_temporary', | |
'style_base' => NULL, | |
'palette' => array(), | |
); | |
ctools_stylizer_clear_settings_cache($name); | |
} | |
$op = 'add'; | |
} | |
else { | |
$cache = ctools_stylizer_get_settings_cache($info['settings']['name']); | |
if (!empty($cache)) { | |
if (!empty($cache['owner settings'])) { | |
$info['owner settings'] = $cache['owner settings']; | |
} | |
$settings = $cache['settings']; | |
} | |
else { | |
$settings = $info['settings']; | |
} | |
$op = 'edit'; | |
} | |
if (!empty($info['op'])) { | |
// Allow this to override. Necessary to allow cloning properly. | |
$op = $info['op']; | |
} | |
$plugin = NULL; | |
if (!empty($settings['style_base'])) { | |
$plugin = ctools_get_style_base($settings['style_base']); | |
$info['type'] = $plugin['type']; | |
ctools_stylizer_add_plugin_forms($form_info, $plugin, $op); | |
} | |
else { | |
// This is here so the 'finish' button does not show up, and because | |
// we don't have the selected style we don't know what the next form(s) | |
// will be. | |
$form_info['order']['next'] = t('Configure style'); | |
} | |
if (count($form_info['order']) < 2 || $step == 'choose') { | |
$form_info['show trail'] = FALSE; | |
} | |
$form_state = array( | |
'module' => $info['module'], | |
'type' => $info['type'], | |
'owner info' => &$info, | |
'base_style_plugin' => $plugin, | |
'name' => $name, | |
'step' => $step, | |
'settings' => $settings, | |
'ajax' => $js, | |
'op' => $op, | |
); | |
if (!empty($info['modal'])) { | |
$form_state['modal'] = TRUE; | |
$form_state['title'] = $info['modal']; | |
$form_state['modal return'] = TRUE; | |
} | |
ctools_include('wizard'); | |
$output = ctools_wizard_multistep_form($form_info, $step, $form_state); | |
if (!empty($form_state['complete'])) { | |
$info['complete'] = TRUE; | |
$info['settings'] = $form_state['settings']; | |
} | |
if ($js && !$output && !empty($form_state['clicked_button']['#next'])) { | |
// We have to do a separate redirect here because the formula that adds | |
// stuff to the wizard after being chosen hasn't happened. The wizard | |
// tried to go to the next step which did not exist. | |
return ctools_stylizer_edit_style($info, $js, $form_state['clicked_button']['#next']); | |
} | |
if ($js) { | |
return ctools_modal_form_render($form_state, $output); | |
} | |
else { | |
return $output; | |
} | |
} | |
/** | |
* Add wizard forms specific to a style base plugin. | |
* | |
* The plugin can store forms either as a simple 'edit form' | |
* => 'form callback' or if it needs the more complicated wizard | |
* functionality, it can set 'forms' and 'order' with values suitable | |
* for the wizard $form_info array. | |
* | |
* @param &$form_info | |
* The form info to modify. | |
* @param $plugin | |
* The plugin to use. | |
* @param $op | |
* Either 'add' or 'edit' so we can get the right forms. | |
*/ | |
function ctools_stylizer_add_plugin_forms(&$form_info, $plugin, $op) { | |
if (empty($plugin['forms'])) { | |
if ($op == 'add' && isset($plugin['add form'])) { | |
$id = $plugin['add form']; | |
} | |
else if (isset($plugin['edit form'])) { | |
$id = $plugin['edit form']; | |
} | |
else { | |
$id = 'ctools_stylizer_edit_style_form_default'; | |
} | |
$form_info['forms']['settings'] = array( | |
'form id' => $id, | |
); | |
$form_info['order']['settings'] = t('Settings'); | |
} | |
else { | |
$form_info['forms'] += $plugin['forms']; | |
$form_info['order'] += $plugin['order']; | |
} | |
} | |
/** | |
* Callback generated when the add style process is finished. | |
*/ | |
function ctools_stylizer_edit_style_finish(&$form_state) { | |
$form_state['complete'] = TRUE; | |
ctools_stylizer_clear_settings_cache($form_state['name']); | |
if (isset($form_state['settings']['old_settings'])) { | |
unset($form_state['settings']['old_settings']); | |
} | |
} | |
/** | |
* Callback generated when the 'next' button is clicked. | |
*/ | |
function ctools_stylizer_edit_style_next(&$form_state) { | |
$form_state['form_info']['path'] = str_replace('%name', $form_state['name'], $form_state['form_info']['path']); | |
$form_state['redirect'] = ctools_wizard_get_path($form_state['form_info'], $form_state['clicked_button']['#next']); | |
// Update the cache with changes. | |
$cache = array('settings' => $form_state['settings']); | |
if (!empty($form_state['owner info']['owner settings'])) { | |
$cache['owner settings'] = $form_state['owner info']['owner settings']; | |
} | |
ctools_stylizer_set_settings_cache($form_state['name'], $cache); | |
} | |
/** | |
* Callback generated when the 'cancel' button is clicked. | |
* | |
* We might have some temporary data lying around. We must remove it. | |
*/ | |
function ctools_stylizer_edit_style_cancel(&$form_state) { | |
if (!empty($form_state['name'])) { | |
ctools_stylizer_clear_settings_cache($form_state['name']); | |
} | |
} | |
/** | |
* Choose which plugin to use to create a new style. | |
*/ | |
function ctools_stylizer_edit_style_form_choose($form, &$form_state) { | |
$plugins = ctools_get_style_bases(); | |
$options = array(); | |
$categories = array(); | |
foreach ($plugins as $name => $plugin) { | |
if ($form_state['module'] == $plugin['module'] && $form_state['type'] == $plugin['type']) { | |
$categories[$plugin['category']] = $plugin['category']; | |
$unsorted_options[$plugin['category']][$name] = ctools_stylizer_print_style_icon($plugin, TRUE); | |
} | |
} | |
asort($categories); | |
foreach ($categories as $category) { | |
$options[$category] = $unsorted_options[$category]; | |
} | |
$form['style_base'] = array( | |
'#prefix' => '<div class="ctools-style-icons clearfix">', | |
'#suffix' => '</div>', | |
); | |
ctools_include('cleanstring'); | |
foreach ($options as $category => $radios) { | |
$cat = ctools_cleanstring($category); | |
$form['style_base'][$cat] = array( | |
'#prefix' => '<div class="ctools-style-category clearfix"><label>' . $category . '</label>', | |
'#suffix' => '</div>', | |
); | |
foreach ($radios as $key => $choice) { | |
// Generate the parents as the autogenerator does, so we will have a | |
// unique id for each radio button. | |
$form['style_base'][$cat][$key] = array( | |
'#type' => 'radio', | |
'#title' => $choice, | |
'#parents' => array('style_base'), | |
'#id' => drupal_clean_css_identifier('edit-style-base-' . $key), | |
'#return_value' => check_plain($key), | |
); | |
} | |
} | |
return $form; | |
} | |
function ctools_stylizer_edit_style_form_choose_submit($form, &$form_state) { | |
$form_state['settings']['style_base'] = $form_state['values']['style_base']; | |
// The 'next' form will show up as 'next' but that's not accurate now that | |
// we have a style. Figure out what next really is and update. | |
$plugin = ctools_get_style_base($form_state['settings']['style_base']); | |
if (empty($plugin['forms'])) { | |
$form_state['clicked_button']['#next'] = 'settings'; | |
} | |
else { | |
$forms = array_keys($form_info['forms']); | |
$form_state['clicked_button']['#next'] = array_shift($forms); | |
} | |
// Fill in the defaults for the settings. | |
if (!empty($plugin['defaults'])) { | |
// @todo allow a callback | |
$form_state['settings'] += $plugin['defaults']; | |
} | |
return $form; | |
} | |
/** | |
* The default stylizer style editing form. | |
* | |
* Even when not using this, styles should call through to this form in | |
* their own edit forms. | |
*/ | |
function ctools_stylizer_edit_style_form_default($form, &$form_state) { | |
ctools_add_js('stylizer'); | |
ctools_add_css('stylizer'); | |
drupal_add_library('system', 'farbtastic'); | |
$plugin = &$form_state['base_style_plugin']; | |
$settings = &$form_state['settings']; | |
$form['top box'] = array( | |
'#prefix' => '<div id="ctools-stylizer-top-box" class="clearfix">', | |
'#suffix' => '</div>', | |
); | |
$form['top box']['left'] = array( | |
'#prefix' => '<div id="ctools-stylizer-left-box">', | |
'#suffix' => '</div>', | |
); | |
$form['top box']['preview'] = array( | |
// We have a copy of the $form_state on $form because form theme functions | |
// do not get $form_state. | |
'#theme' => 'ctools_stylizer_preview_form', | |
'#form_state' => &$form_state, | |
); | |
$form['top box']['preview']['submit'] = array( | |
'#type' => 'submit', | |
'#value' => t('Preview'), | |
); | |
if (!empty($plugin['palette'])) { | |
$form['top box']['color'] = array( | |
'#type' => 'fieldset', | |
'#title' => t('Color scheme'), | |
'#attributes' => array('id' => 'ctools_stylizer_color_scheme_form', 'class' => array('ctools-stylizer-color-edit')), | |
'#theme' => 'ctools_stylizer_color_scheme_form', | |
); | |
$form['top box']['color']['palette']['#tree'] = TRUE; | |
foreach ($plugin['palette'] as $key => $color) { | |
if (empty($settings['palette'][$key])) { | |
$settings['palette'][$key] = $color['default_value']; | |
} | |
$form['top box']['color']['palette'][$key] = array( | |
'#type' => 'textfield', | |
'#title' => $color['label'], | |
'#default_value' => $settings['palette'][$key], | |
'#size' => 8, | |
); | |
} | |
} | |
if (!empty($plugin['settings form']) && function_exists($plugin['settings form'])) { | |
$plugin['settings form']($form, $form_state); | |
} | |
if (!empty($form_state['owner info']['owner form']) && function_exists($form_state['owner info']['owner form'])) { | |
$form_state['owner info']['owner form']($form, $form_state); | |
} | |
return $form; | |
} | |
/** | |
* Theme the stylizer color scheme form. | |
*/ | |
function theme_ctools_stylizer_color_scheme_form($vars) { | |
$form = &$vars['form']; | |
$output = ''; | |
// Wrapper | |
$output .= '<div class="color-form clearfix">'; | |
// Color schemes | |
// $output .= drupal_render($form['scheme']); | |
// Palette | |
$output .= '<div id="palette" class="clearfix">'; | |
foreach (element_children($form['palette']) as $name) { | |
$output .= render($form['palette'][$name]); | |
} | |
$output .= '</div>'; // palette | |
$output .= '</div>'; // color form | |
return $output; | |
} | |
/** | |
* Theme the stylizer preview form. | |
*/ | |
function theme_ctools_stylizer_preview_form($vars) { | |
$form = &$vars['form']; | |
$plugin = $form['#form_state']['base_style_plugin']; | |
$settings = $form['#form_state']['settings']; | |
if (!empty($form['#form_state']['settings']['old_settings'])) { | |
ctools_stylizer_cleanup_style($plugin, $form['#form_state']['settings']['old_settings']); | |
} | |
$preview = ''; | |
if (!empty($plugin['preview'])) { | |
$preview = $plugin['preview']; | |
} | |
else { | |
$base_types = ctools_get_style_base_types(); | |
if (!empty($base_types[$plugin['module']][$plugin['type']]['preview'])) { | |
$preview = $base_types[$plugin['module']][$plugin['type']]['preview']; | |
} | |
} | |
if (!empty($preview) && function_exists($preview)) { | |
$output = '<fieldset id="preview"><legend>' . t('Preview') . '</legend>'; | |
$output .= $preview($plugin, $settings); | |
$output .= drupal_render_children($form); | |
$output .= '</fieldset>'; | |
return $output; | |
} | |
} | |
function ctools_stylizer_edit_style_form_default_validate($form, &$form_state) { | |
if (!empty($form_state['owner info']['owner form validate']) && function_exists($form_state['owner info']['owner form validate'])) { | |
$form_state['owner info']['owner form validate']($form, $form_state); | |
} | |
if (!empty($form_state['base_style_plugin']['settings form validate']) && function_exists($form_state['base_style_plugin']['settings form validate'])) { | |
$form_state['base_style_plugin']['settings form validate']($form, $form_state); | |
} | |
} | |
function ctools_stylizer_edit_style_form_default_submit($form, &$form_state) { | |
// Store old settings for the purposes of cleaning up. | |
$form_state['settings']['old_settings'] = $form_state['settings']; | |
$form_state['settings']['palette'] = $form_state['values']['palette']; | |
if (!empty($form_state['owner info']['owner form submit']) && function_exists($form_state['owner info']['owner form submit'])) { | |
$form_state['owner info']['owner form submit']($form, $form_state); | |
} | |
if (!empty($form_state['base_style_plugin']['settings form submit']) && function_exists($form_state['base_style_plugin']['settings form submit'])) { | |
$form_state['base_style_plugin']['settings form submit']($form, $form_state); | |
} | |
if ($form_state['clicked_button']['#value'] == t('Preview')) { | |
$form_state['rerender'] = TRUE; | |
// Update the cache with changes. | |
if (!empty($form_state['name'])) { | |
$cache = array('settings' => $form_state['settings']); | |
if (!empty($form_state['owner info']['owner settings'])) { | |
$cache['owner settings'] = $form_state['owner info']['owner settings']; | |
} | |
ctools_stylizer_set_settings_cache($form_state['name'], $cache); | |
} | |
} | |
} | |
// -------------------------------------------------------------------------- | |
// CSS forms and tools that plugins can use. | |
/** | |
* Font selector form | |
*/ | |
function ctools_stylizer_font_selector_form(&$form, &$form_state, $label, $settings) { | |
// Family | |
$form['#prefix'] = '<div class="ctools-stylizer-spacing-form clearfix">'; | |
$form['#type'] = 'fieldset'; | |
$form['#title'] = $label; | |
$form['#suffix'] = '</div>'; | |
$form['#tree'] = TRUE; | |
$form['font'] = array( | |
'#title' => t('Font family'), | |
'#type' => 'select', | |
'#default_value' => isset($settings['font']) ? $settings['font'] : '', | |
'#options' => array( | |
'' => '', | |
'Arial, Helvetica, sans-serif' => t('Arial, Helvetica, sans-serif'), | |
'Times New Roman, Times, serif' => t('Times New Roman, Times, serif'), | |
'Courier New, Courier, monospace' => t('Courier New, Courier, monospace'), | |
'Georgia, Times New Roman, Times, serif' => t('Georgia, Times New Roman, Times, serif'), | |
'Verdana, Arial, Helvetica, sans-serif' => t('Verdana, Arial, Helvetica, sans-serif'), | |
'Geneva, Arial, Helvetica, sans-serif' => t('Geneva, Arial, Helvetica, sans-serif'), | |
'Trebuchet MS, Trebuchet, Verdana, sans-serif' => t('Trebuchet MS, Trebuchet, Verdana, sans-serif'), | |
), | |
); | |
// size | |
$form['size'] = array( | |
'#title' => t('Size'), | |
'#type' => 'select', | |
'#default_value' => isset($settings['size']) ? $settings['size'] : '', | |
'#options' => array( | |
'' => '', | |
'xx-small' => t('XX-Small'), | |
'x-small' => t('X-Small'), | |
'small' => t('Small'), | |
'medium' => t('Medium'), | |
'large' => t('Large'), | |
'x-large' => t('X-Large'), | |
'xx-large' => t('XX-Large'), | |
), | |
); | |
// letter spacing | |
$form['letter_spacing'] = array( | |
'#title' => t('Letter spacing'), | |
'#type' => 'select', | |
'#default_value' => isset($settings['letter_spacing']) ? $settings['letter_spacing'] : '', | |
'#options' => array( | |
'' => '', | |
"-10px" => '10px', | |
"-9px" => '9px', | |
"-8px" => '8px', | |
"-7px" => '7px', | |
"-6px" => '6px', | |
"-5px" => '5px', | |
"-4px" => '4px', | |
"-3px" => '3px', | |
"-2px" => '2px', | |
"-1px" => '1px', | |
"0" => '0', | |
"1px" => '1px', | |
"2px" => '2px', | |
"3px" => '3px', | |
"4px" => '4px', | |
"5px" => '5px', | |
"6px" => '6px', | |
"7px" => '7px', | |
"8px" => '8px', | |
"9px" => '9px', | |
"10px" => '10px', | |
"11px" => '11px', | |
"12px" => '12px', | |
"13px" => '13px', | |
"14px" => '14px', | |
"15px" => '15px', | |
"16px" => '16px', | |
"17px" => '17px', | |
"18px" => '18px', | |
"19px" => '19px', | |
"20px" => '20px', | |
"21px" => '21px', | |
"22px" => '22px', | |
"23px" => '23px', | |
"24px" => '24px', | |
"25px" => '25px', | |
"26px" => '26px', | |
"27px" => '27px', | |
"28px" => '28px', | |
"29px" => '29px', | |
"30px" => '30px', | |
"31px" => '31px', | |
"32px" => '32px', | |
"33px" => '33px', | |
"34px" => '34px', | |
"35px" => '35px', | |
"36px" => '36px', | |
"37px" => '37px', | |
"38px" => '38px', | |
"39px" => '39px', | |
"40px" => '40px', | |
"41px" => '41px', | |
"42px" => '42px', | |
"43px" => '43px', | |
"44px" => '44px', | |
"45px" => '45px', | |
"46px" => '46px', | |
"47px" => '47px', | |
"48px" => '48px', | |
"49px" => '49px', | |
"50px" => '50px', | |
), | |
); | |
// word space | |
$form['word_spacing'] = array( | |
'#title' => t('Word spacing'), | |
'#type' => 'select', | |
'#default_value' => isset($settings['word_spacing']) ? $settings['word_spacing'] : '', | |
'#options' => array( | |
'' => '', | |
"-1em" => '-1em', | |
"-0.95em" => '-0.95em', | |
"-0.9em" => '-0.9em', | |
"-0.85em" => '-0.85em', | |
"-0.8em" => '-0.8em', | |
"-0.75em" => '-0.75em', | |
"-0.7em" => '-0.7em', | |
"-0.65em" => '-0.65em', | |
"-0.6em" => '-0.6em', | |
"-0.55em" => '-0.55em', | |
"-0.5em" => '-0.5em', | |
"-0.45em" => '-0.45em', | |
"-0.4em" => '-0.4em', | |
"-0.35em" => '-0.35em', | |
"-0.3em" => '-0.3em', | |
"-0.25em" => '-0.25em', | |
"-0.2em" => '-0.2em', | |
"-0.15em" => '-0.15em', | |
"-0.1em" => '-0.1em', | |
"-0.05em" => '-0.05em', | |
"normal" => 'normal', | |
"0.05em" => '0.05em', | |
"0.1em" => '0.1em', | |
"0.15em" => '0.15em', | |
"0.2em" => '0.2em', | |
"0.25em" => '0.25em', | |
"0.3em" => '0.3em', | |
"0.35em" => '0.35em', | |
"0.4em" => '0.4em', | |
"0.45em" => '0.45em', | |
"0.5em" => '0.5em', | |
"0.55em" => '0.55em', | |
"0.6em" => '0.6em', | |
"0.65em" => '0.65em', | |
"0.7em" => '0.7em', | |
"0.75em" => '0.75em', | |
"0.8em" => '0.8em', | |
"0.85em" => '0.85em', | |
"0.9em" => '0.9em', | |
"0.95em" => '0.95em', | |
"1em" => '1em', | |
), | |
); | |
// decoration | |
$form['decoration'] = array( | |
'#title' => t('Decoration'), | |
'#type' => 'select', | |
'#default_value' => isset($settings['decoration']) ? $settings['decoration'] : '', | |
'#options' => array( | |
'' => '', | |
'none' => t('None'), | |
'underline' => t('Underline'), | |
'overline' => t('Overline'), | |
'line-through' => t('Line-through'), | |
), | |
); | |
// weight | |
$form['weight'] = array( | |
'#title' => t('Weight'), | |
'#type' => 'select', | |
'#default_value' => isset($settings['weight']) ? $settings['weight'] : '', | |
'#options' => array( | |
'' => '', | |
'normal' => t('Normal'), | |
'bold' => t('Bold'), | |
'bolder' => t('Bolder'), | |
'lighter' => t('Lighter'), | |
), | |
); | |
// style | |
$form['style'] = array( | |
'#title' => t('Style'), | |
'#type' => 'select', | |
'#default_value' => isset($settings['style']) ? $settings['style'] : '', | |
'#options' => array( | |
'' => '', | |
'normal' => t('Normal'), | |
'italic' => t('Italic'), | |
'oblique' => t('Oblique'), | |
), | |
); | |
// variant | |
$form['variant'] = array( | |
'#title' => t('Variant'), | |
'#type' => 'select', | |
'#default_value' => isset($settings['variant']) ? $settings['variant'] : '', | |
'#options' => array( | |
'' => '', | |
'normal' => t('Normal'), | |
'small-caps' => t('Small-caps'), | |
), | |
); | |
// case | |
$form['case'] = array( | |
'#title' => t('Case'), | |
'#type' => 'select', | |
'#default_value' => isset($settings['case']) ? $settings['case'] : '', | |
'#options' => array( | |
'' => '', | |
'capitalize' => t('Capitalize'), | |
'uppercase' => t('Uppercase'), | |
'lowercase' => t('Lowercase'), | |
'none' => t('None'), | |
), | |
); | |
// alignment | |
$form['alignment'] = array( | |
'#title' => t('Align'), | |
'#type' => 'select', | |
'#default_value' => isset($settings['alignment']) ? $settings['alignment'] : '', | |
'#options' => array( | |
'' => '', | |
'justify' => t('Justify'), | |
'left' => t('Left'), | |
'right' => t('Right'), | |
'center' => t('Center'), | |
), | |
); | |
} | |
/** | |
* Copy font selector information into the settings | |
*/ | |
function ctools_stylizer_font_selector_form_submit(&$form, &$form_state, &$values, &$settings) { | |
$settings = $values; | |
} | |
function ctools_stylizer_font_apply_style(&$stylesheet, $selector, $settings) { | |
$css = ''; | |
if (isset($settings['font']) && $settings['font'] !== '') { | |
$css .= ' font-family: ' . $settings['font'] . ";\n"; | |
} | |
if (isset($settings['size']) && $settings['size'] !== '') { | |
$css .= ' font-size: ' . $settings['size'] . ";\n"; | |
} | |
if (isset($settings['weight']) && $settings['weight'] !== '') { | |
$css .= ' font-weight: ' . $settings['weight'] . ";\n"; | |
} | |
if (isset($settings['style']) && $settings['style'] !== '') { | |
$css .= ' font-style: ' . $settings['style'] . ";\n"; | |
} | |
if (isset($settings['variant']) && $settings['variant'] !== '') { | |
$css .= ' font-variant: ' . $settings['variant'] . ";\n"; | |
} | |
if (isset($settings['case']) && $settings['case'] !== '') { | |
$css .= ' text-transform: ' . $settings['case'] . ";\n"; | |
} | |
if (isset($settings['decoration']) && $settings['decoration'] !== '') { | |
$css .= ' text-decoration: ' . $settings['decoration'] . ";\n"; | |
} | |
if (isset($settings['alignment']) && $settings['alignment'] !== '') { | |
$css .= ' text-align: ' . $settings['alignment'] . ";\n"; | |
} | |
if (isset($settings['letter_spacing']) && $settings['letter_spacing'] !== '') { | |
$css .= ' letter-spacing: ' . $settings['letter_spacing'] . ";\n"; | |
} | |
if (isset($settings['word_spacing']) && $settings['word_spacing'] !== '') { | |
$css .= ' word-spacing: ' . $settings['word_spacing'] . ";\n"; | |
} | |
if ($css) { | |
$stylesheet .= $selector . " {\n" . $css . "}\n"; | |
} | |
} | |
/** | |
* Border selector form | |
*/ | |
function ctools_stylizer_border_selector_form(&$form, &$form_state, $label, $settings) { | |
// Family | |
$form['#prefix'] = '<div class="ctools-stylizer-spacing-form clearfix">'; | |
$form['#type'] = 'fieldset'; | |
$form['#title'] = $label; | |
$form['#suffix'] = '</div>'; | |
$form['#tree'] = TRUE; | |
$form['thickness'] = array( | |
'#title' => t('Thickness'), | |
'#type' => 'select', | |
'#default_value' => isset($settings['thickness']) ? $settings['thickness'] : '', | |
'#options' => array( | |
'' => '', | |
"none" => t('None'), | |
"1px" => '1px', | |
"2px" => '2px', | |
"3px" => '3px', | |
"4px" => '4px', | |
"5px" => '5px', | |
), | |
); | |
$form['style'] = array( | |
'#title' => t('style'), | |
'#type' => 'select', | |
'#default_value' => isset($settings['style']) ? $settings['style'] : '', | |
'#options' => array( | |
'' => '', | |
'solid' => t('Solid'), | |
'dotted' => t('Dotted'), | |
'dashed' => t('Dashed'), | |
'double' => t('Double'), | |
'groove' => t('Groove'), | |
'ridge' => t('Ridge'), | |
'inset' => t('Inset'), | |
'outset' => t('Outset'), | |
), | |
); | |
} | |
/** | |
* Copy border selector information into the settings | |
*/ | |
function ctools_stylizer_border_selector_form_submit(&$form, &$form_state, &$values, &$settings) { | |
$settings = $values; | |
} | |
function ctools_stylizer_border_apply_style(&$stylesheet, $selector, $settings, $color, $which = NULL) { | |
$border = 'border'; | |
if ($which) { | |
$border .= '-' . $which; | |
} | |
$css = ''; | |
if (isset($settings['thickness']) && $settings['thickness'] !== '') { | |
if ($settings['thickness'] == 'none') { | |
$css .= ' ' . $border . ': none'; | |
} | |
else { | |
$css .= ' ' . $border . '-width: ' . $settings['thickness'] . ";\n"; | |
if (isset($settings['style']) && $settings['style'] !== '') { | |
$css .= ' ' . $border . '-style: ' . $settings['style'] . ";\n"; | |
} | |
$css .= ' ' . $border . '-color: ' . $color . ";\n"; | |
} | |
} | |
if ($css) { | |
$stylesheet .= $selector . " {\n" . $css . "}\n"; | |
} | |
} | |
/** | |
* padding selector form | |
*/ | |
function ctools_stylizer_padding_selector_form(&$form, &$form_state, $label, $settings) { | |
// Family | |
$form['#prefix'] = '<div class="ctools-stylizer-spacing-form clearfix">'; | |
$form['#type'] = 'fieldset'; | |
$form['#title'] = $label; | |
$form['#suffix'] = '</div>'; | |
$form['#tree'] = TRUE; | |
$options = array( | |
'' => '', | |
"0.05em" => '0.05em', | |
"0.1em" => '0.1em', | |
"0.15em" => '0.15em', | |
"0.2em" => '0.2em', | |
"0.25em" => '0.25em', | |
"0.3em" => '0.3em', | |
"0.35em" => '0.35em', | |
"0.4em" => '0.4em', | |
"0.45em" => '0.45em', | |
"0.5em" => '0.5em', | |
"0.55em" => '0.55em', | |
"0.6em" => '0.6em', | |
"0.65em" => '0.65em', | |
"0.7em" => '0.7em', | |
"0.75em" => '0.75em', | |
"0.8em" => '0.8em', | |
"0.85em" => '0.85em', | |
"0.9em" => '0.9em', | |
"0.95em" => '0.95em', | |
"1.0em" => '1.0em', | |
"1.05em" => '1.05em', | |
"1.1em" => '1.1em', | |
"1.15em" => '1.15em', | |
"1.2em" => '1.2em', | |
"1.25em" => '1.25em', | |
"1.3em" => '1.3em', | |
"1.35em" => '1.35em', | |
"1.4em" => '1.4em', | |
"1.45em" => '1.45em', | |
"1.5em" => '1.5em', | |
"1.55em" => '1.55em', | |
"1.6em" => '1.6em', | |
"1.65em" => '1.65em', | |
"1.7em" => '1.7em', | |
"1.75em" => '1.75em', | |
"1.8em" => '1.8em', | |
"1.85em" => '1.85em', | |
"1.9em" => '1.9em', | |
"1.95em" => '1.95em', | |
"2.0em" => '2.0em', | |
"2.05em" => '2.05em', | |
"2.1em" => '2.1em', | |
"2.15em" => '2.15em', | |
"2.2em" => '2.2em', | |
"2.25em" => '2.25em', | |
"2.3em" => '2.3em', | |
"2.35em" => '2.35em', | |
"2.4em" => '2.4em', | |
"2.45em" => '2.45em', | |
"2.5em" => '2.5em', | |
"2.55em" => '2.55em', | |
"2.6em" => '2.6em', | |
"2.65em" => '2.65em', | |
"2.7em" => '2.7em', | |
"2.75em" => '2.75em', | |
"2.8em" => '2.8em', | |
"2.85em" => '2.85em', | |
"2.9em" => '2.9em', | |
"2.95em" => '2.95em', | |
"3.0em" => '3.0em', | |
"3.05em" => '3.05em', | |
"3.1em" => '3.1em', | |
"3.15em" => '3.15em', | |
"3.2em" => '3.2em', | |
"3.25em" => '3.25em', | |
"3.3em" => '3.3em', | |
"3.35em" => '3.35em', | |
"3.4em" => '3.4em', | |
"3.45em" => '3.45em', | |
"3.5em" => '3.5em', | |
"3.55em" => '3.55em', | |
"3.6em" => '3.6em', | |
"3.65em" => '3.65em', | |
"3.7em" => '3.7em', | |
"3.75em" => '3.75em', | |
"3.8em" => '3.8em', | |
"3.85em" => '3.85em', | |
"3.9em" => '3.9em', | |
"3.95em" => '3.95em', | |
); | |
$form['top'] = array( | |
'#title' => t('Top'), | |
'#type' => 'select', | |
'#default_value' => isset($settings['top']) ? $settings['top'] : '', | |
'#options' => $options, | |
); | |
$form['right'] = array( | |
'#title' => t('Right'), | |
'#type' => 'select', | |
'#default_value' => isset($settings['right']) ? $settings['right'] : '', | |
'#options' => $options, | |
); | |
$form['bottom'] = array( | |
'#title' => t('Bottom'), | |
'#type' => 'select', | |
'#default_value' => isset($settings['bottom']) ? $settings['bottom'] : '', | |
'#options' => $options, | |
); | |
$form['left'] = array( | |
'#title' => t('Left'), | |
'#type' => 'select', | |
'#default_value' => isset($settings['left']) ? $settings['left'] : '', | |
'#options' => $options, | |
); | |
} | |
/** | |
* Copy padding selector information into the settings | |
*/ | |
function ctools_stylizer_padding_selector_form_submit(&$form, &$form_state, &$values, &$settings) { | |
$settings = $values; | |
} | |
function ctools_stylizer_padding_apply_style(&$stylesheet, $selector, $settings) { | |
$css = ''; | |
if (isset($settings['top']) && $settings['top'] !== '') { | |
$css .= ' padding-top: ' . $settings['top'] . ";\n"; | |
} | |
if (isset($settings['right']) && $settings['right'] !== '') { | |
$css .= ' padding-right: ' . $settings['right'] . ";\n"; | |
} | |
if (isset($settings['bottom']) && $settings['bottom'] !== '') { | |
$css .= ' padding-bottom: ' . $settings['bottom'] . ";\n"; | |
} | |
if (isset($settings['left']) && $settings['left'] !== '') { | |
$css .= ' padding-left: ' . $settings['left'] . ";\n"; | |
} | |
if ($css) { | |
$stylesheet .= $selector . " {\n" . $css . "}\n"; | |
} | |
} |