1 |
85ad3d82
|
Assos Assos
|
<?php
|
2 |
|
|
/**
|
3 |
|
|
* @file
|
4 |
|
|
* Create customized CSS and images from palettes created by user input.
|
5 |
|
|
*/
|
6 |
|
|
|
7 |
|
|
/**
|
8 |
|
|
* Fetch metadata on a specific style_base plugin.
|
9 |
|
|
*
|
10 |
|
|
* @param $content type
|
11 |
|
|
* Name of a panel content type.
|
12 |
|
|
*
|
13 |
|
|
* @return
|
14 |
|
|
* An array with information about the requested stylizer style base.
|
15 |
|
|
*/
|
16 |
|
|
function ctools_get_style_base($style_base) {
|
17 |
|
|
ctools_include('plugins');
|
18 |
|
|
return ctools_get_plugins('stylizer', 'style_bases', $style_base);
|
19 |
|
|
}
|
20 |
|
|
|
21 |
|
|
/**
|
22 |
|
|
* Fetch metadata for all style_base plugins.
|
23 |
|
|
*
|
24 |
|
|
* @return
|
25 |
|
|
* An array of arrays with information about all available styleizer style bases.
|
26 |
|
|
*/
|
27 |
|
|
function ctools_get_style_bases() {
|
28 |
|
|
ctools_include('plugins');
|
29 |
|
|
return ctools_get_plugins('stylizer', 'style_bases');
|
30 |
|
|
}
|
31 |
|
|
|
32 |
|
|
/**
|
33 |
|
|
* Fetch metadata about all of the style base types that are available.
|
34 |
|
|
*/
|
35 |
|
|
function ctools_get_style_base_types() {
|
36 |
|
|
$types = array();
|
37 |
|
|
foreach (module_implements('ctools_style_base_types') as $module) {
|
38 |
|
|
$types[$module] = module_invoke($module, 'ctools_style_base_types');
|
39 |
|
|
}
|
40 |
|
|
|
41 |
|
|
return $types;
|
42 |
|
|
}
|
43 |
|
|
|
44 |
|
|
/**
|
45 |
|
|
* Render the icon for a style base.
|
46 |
|
|
*/
|
47 |
|
|
function ctools_stylizer_print_style_icon($plugin, $print_title = TRUE) {
|
48 |
|
|
$file = $plugin['path'] . '/' . $plugin['icon'];
|
49 |
|
|
$title = $print_title ? $plugin['title'] : '';
|
50 |
|
|
return theme('ctools_style_icon', array('image' => theme('image', array('path' => $file)), 'title' => $title));
|
51 |
|
|
}
|
52 |
|
|
|
53 |
|
|
/**
|
54 |
|
|
* Theme the style icon image
|
55 |
|
|
*/
|
56 |
|
|
function theme_ctools_style_icon($vars) {
|
57 |
|
|
$image = $vars['image'];
|
58 |
|
|
ctools_add_css('stylizer');
|
59 |
|
|
ctools_add_js('stylizer');
|
60 |
|
|
$output = '<div class="ctools-style-icon">';
|
61 |
|
|
$output .= $vars['image'];
|
62 |
|
|
if ($vars['title']) {
|
63 |
|
|
$output .= '<div class="caption">' . $vars['title'] . '</div>';
|
64 |
|
|
}
|
65 |
|
|
$output .= '</div>';
|
66 |
|
|
return $output;
|
67 |
|
|
}
|
68 |
|
|
|
69 |
|
|
/**
|
70 |
|
|
* Add the necessary CSS for a stylizer plugin to the page.
|
71 |
|
|
*
|
72 |
|
|
* This will check to see if the images directory and the cached CSS
|
73 |
|
|
* exists and, if not, will regenerate everything needed.
|
74 |
|
|
*/
|
75 |
|
|
function ctools_stylizer_add_css($plugin, $settings) {
|
76 |
|
|
if (!file_exists(ctools_stylizer_get_image_path($plugin, $settings, FALSE))) {
|
77 |
|
|
ctools_stylizer_build_style($plugin, $settings, TRUE);
|
78 |
|
|
return;
|
79 |
|
|
}
|
80 |
|
|
|
81 |
|
|
ctools_include('css');
|
82 |
|
|
$filename = ctools_css_retrieve(ctools_stylizer_get_css_id($plugin, $settings));
|
83 |
|
|
if (!$filename) {
|
84 |
|
|
ctools_stylizer_build_style($plugin, $settings, TRUE);
|
85 |
|
|
}
|
86 |
|
|
else {
|
87 |
|
|
drupal_add_css($filename);
|
88 |
|
|
}
|
89 |
|
|
}
|
90 |
|
|
|
91 |
|
|
/**
|
92 |
|
|
* Build the files for a stylizer given the proper settings.
|
93 |
|
|
*/
|
94 |
|
|
function ctools_stylizer_build_style($plugin, $settings, $add_css = FALSE) {
|
95 |
|
|
$path = ctools_stylizer_get_image_path($plugin, $settings);
|
96 |
|
|
if (!$path) {
|
97 |
|
|
return;
|
98 |
|
|
}
|
99 |
|
|
|
100 |
|
|
$replacements = array();
|
101 |
|
|
|
102 |
|
|
// Set up palette conversions
|
103 |
|
|
foreach ($settings['palette'] as $key => $color) {
|
104 |
|
|
$replacements['%' . $key ] = $color;
|
105 |
|
|
}
|
106 |
|
|
|
107 |
|
|
// Process image actions:
|
108 |
|
|
if (!empty($plugin['actions'])) {
|
109 |
|
|
$processor = new ctools_stylizer_image_processor;
|
110 |
|
|
$processor->execute($path, $plugin, $settings);
|
111 |
|
|
|
112 |
|
|
// @todo -- there needs to be an easier way to get at this.
|
113 |
|
|
// dsm($processor->message_log);
|
114 |
|
|
// Add filenames to our conversions.
|
115 |
|
|
}
|
116 |
|
|
|
117 |
|
|
// Convert and write the CSS file.
|
118 |
|
|
$css = file_get_contents($plugin['path'] . '/' . $plugin['css']);
|
119 |
|
|
|
120 |
|
|
// Replace %style keyword with our generated class name.
|
121 |
|
|
// @todo We need one more unique identifier I think.
|
122 |
|
|
$class = ctools_stylizer_get_css_class($plugin, $settings);
|
123 |
|
|
$replacements['%style'] = '.' . $class;
|
124 |
|
|
|
125 |
|
|
if (!empty($processor) && !empty($processor->paths)) {
|
126 |
|
|
foreach ($processor->paths as $file => $image) {
|
127 |
|
|
$replacements[$file] = file_create_url($image);
|
128 |
|
|
}
|
129 |
|
|
}
|
130 |
|
|
|
131 |
|
|
if (!empty($plugin['build']) && function_exists($plugin['build'])) {
|
132 |
|
|
$plugin['build']($plugin, $settings, $css, $replacements);
|
133 |
|
|
}
|
134 |
|
|
|
135 |
|
|
$css = strtr($css, $replacements);
|
136 |
|
|
ctools_include('css');
|
137 |
|
|
$filename = ctools_css_store(ctools_stylizer_get_css_id($plugin, $settings), $css, FALSE);
|
138 |
|
|
|
139 |
|
|
if ($add_css) {
|
140 |
|
|
drupal_add_css($filename);
|
141 |
|
|
}
|
142 |
|
|
}
|
143 |
|
|
|
144 |
|
|
/**
|
145 |
|
|
* Clean up no longer used files.
|
146 |
|
|
*
|
147 |
|
|
* To prevent excess clutter in the files directory, this should be called
|
148 |
|
|
* whenever a style is going out of use. When being deleted, but also when
|
149 |
|
|
* the palette is being changed.
|
150 |
|
|
*/
|
151 |
|
|
function ctools_stylizer_cleanup_style($plugin, $settings) {
|
152 |
|
|
ctools_include('css');
|
153 |
|
|
$path = ctools_stylizer_get_image_path($plugin, $settings, FALSE);
|
154 |
|
|
if ($path) {
|
155 |
|
|
ctools_stylizer_recursive_delete($path);
|
156 |
|
|
}
|
157 |
|
|
|
158 |
|
|
ctools_css_clear(ctools_stylizer_get_css_id($plugin, $settings));
|
159 |
|
|
}
|
160 |
|
|
|
161 |
|
|
/**
|
162 |
|
|
* Recursively delete all files and folders in the specified filepath, then
|
163 |
|
|
* delete the containing folder.
|
164 |
|
|
*
|
165 |
|
|
* Note that this only deletes visible files with write permission.
|
166 |
|
|
*
|
167 |
|
|
* @param string $path
|
168 |
|
|
* A filepath relative to file_directory_path.
|
169 |
|
|
*/
|
170 |
|
|
function ctools_stylizer_recursive_delete($path) {
|
171 |
|
|
if (empty($path)) {
|
172 |
|
|
return;
|
173 |
|
|
}
|
174 |
|
|
|
175 |
|
|
$listing = $path . '/*';
|
176 |
|
|
|
177 |
|
|
foreach (glob($listing) as $file) {
|
178 |
|
|
if (is_file($file) === TRUE) {
|
179 |
|
|
@unlink($file);
|
180 |
|
|
}
|
181 |
|
|
elseif (is_dir($file) === TRUE) {
|
182 |
|
|
ctools_stylizer_recursive_delete($file);
|
183 |
|
|
}
|
184 |
|
|
}
|
185 |
|
|
|
186 |
|
|
@rmdir($path);
|
187 |
|
|
}
|
188 |
|
|
|
189 |
|
|
/**
|
190 |
|
|
* Get a safe name for the settings.
|
191 |
|
|
*
|
192 |
|
|
* This uses an md5 of the palette if the name is temporary so
|
193 |
|
|
* that multiple temporary styles on the same page can coexist
|
194 |
|
|
* safely.
|
195 |
|
|
*/
|
196 |
|
|
function ctools_stylizer_get_settings_name($settings) {
|
197 |
|
|
if ($settings['name'] != '_temporary') {
|
198 |
|
|
return $settings['name'];
|
199 |
|
|
}
|
200 |
|
|
|
201 |
|
|
return $settings['name'] . '-' . md5(serialize($settings['palette']));
|
202 |
|
|
}
|
203 |
|
|
|
204 |
|
|
/**
|
205 |
|
|
* Get the path where images will be stored for a given style plugin and settings.
|
206 |
|
|
*
|
207 |
|
|
* This function will make sure the path exists.
|
208 |
|
|
*/
|
209 |
|
|
function ctools_stylizer_get_image_path($plugin, $settings, $check = TRUE) {
|
210 |
|
|
$path = 'public://ctools/style/' . $settings['name'] . '/' . md5(serialize($settings['palette']));
|
211 |
|
|
if (!file_prepare_directory($path, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) {
|
212 |
|
|
drupal_set_message(t('Unable to create CTools styles cache directory @path. Check the permissions on your files directory.', array('@path' => $path)), 'error');
|
213 |
|
|
return;
|
214 |
|
|
}
|
215 |
|
|
|
216 |
|
|
return $path;
|
217 |
|
|
}
|
218 |
|
|
|
219 |
|
|
/**
|
220 |
|
|
* Get the id used to cache CSS for a given style plugin and settings.
|
221 |
|
|
*/
|
222 |
|
|
function ctools_stylizer_get_css_id($plugin, $settings) {
|
223 |
|
|
return 'ctools-stylizer:' . $settings['name'] . ':' . md5(serialize($settings['palette']));
|
224 |
|
|
}
|
225 |
|
|
|
226 |
|
|
/**
|
227 |
|
|
* Get the class to use for a stylizer plugin.
|
228 |
|
|
*/
|
229 |
|
|
function ctools_stylizer_get_css_class($plugin, $settings) {
|
230 |
|
|
ctools_include('cleanstring');
|
231 |
|
|
return ctools_cleanstring($plugin['name'] . '-' . ctools_stylizer_get_settings_name($settings));
|
232 |
|
|
}
|
233 |
|
|
|
234 |
|
|
class ctools_stylizer_image_processor {
|
235 |
|
|
var $workspace = NULL;
|
236 |
|
|
var $name = NULL;
|
237 |
|
|
|
238 |
|
|
var $workspaces = array();
|
239 |
|
|
|
240 |
|
|
var $message_log = array();
|
241 |
|
|
var $error_log = array();
|
242 |
|
|
|
243 |
|
|
function execute($path, $plugin, $settings) {
|
244 |
|
|
$this->path = $path;
|
245 |
|
|
$this->plugin = $plugin;
|
246 |
|
|
$this->settings = $settings;
|
247 |
|
|
$this->palette = $settings['palette'];
|
248 |
|
|
|
249 |
|
|
if (is_string($plugin['actions']) && function_exists($plugin['actions'])) {
|
250 |
|
|
$actions = $plugin['actions']($plugin, $settings);
|
251 |
|
|
}
|
252 |
|
|
else if (is_array($plugin['actions'])) {
|
253 |
|
|
$actions = $plugin['actions'];
|
254 |
|
|
}
|
255 |
|
|
|
256 |
|
|
if (!empty($actions) && is_array($actions)) {
|
257 |
|
|
foreach ($plugin['actions'] as $action) {
|
258 |
|
|
$command = 'command_' . array_shift($action);
|
259 |
|
|
if (method_exists($this, $command)) {
|
260 |
|
|
call_user_func_array(array($this, $command), $action);
|
261 |
|
|
}
|
262 |
|
|
}
|
263 |
|
|
}
|
264 |
|
|
|
265 |
|
|
// Clean up buffers.
|
266 |
|
|
foreach ($this->workspaces as $name => $workspace) {
|
267 |
|
|
imagedestroy($this->workspaces[$name]);
|
268 |
|
|
}
|
269 |
|
|
}
|
270 |
|
|
|
271 |
|
|
function log($message, $type = 'normal') {
|
272 |
|
|
$this->message_log[] = $message;
|
273 |
|
|
if ($type == 'error') {
|
274 |
|
|
$this->error_log[] = $message;
|
275 |
|
|
}
|
276 |
|
|
}
|
277 |
|
|
|
278 |
|
|
function set_current_workspace($workspace) {
|
279 |
|
|
$this->log("Set current workspace: $workspace");
|
280 |
|
|
$this->workspace = &$this->workspaces[$workspace];
|
281 |
|
|
$this->name = $workspace;
|
282 |
|
|
}
|
283 |
|
|
|
284 |
|
|
/**
|
285 |
|
|
* Create a new workspace.
|
286 |
|
|
*/
|
287 |
|
|
function command_new($name, $width, $height) {
|
288 |
|
|
$this->log("New workspace: $name ($width x $height)");
|
289 |
|
|
// Clean up if there was already a workspace there.
|
290 |
|
|
if (isset($this->workspaces[$name])) {
|
291 |
|
|
imagedestroy($this->workspaces[$name]);
|
292 |
|
|
}
|
293 |
|
|
|
294 |
|
|
$this->workspaces[$name] = imagecreatetruecolor($width, $height);
|
295 |
|
|
$this->set_current_workspace($name);
|
296 |
|
|
|
297 |
|
|
// Make sure the new workspace has a transparent color.
|
298 |
|
|
|
299 |
|
|
// Turn off transparency blending (temporarily)
|
300 |
|
|
imagealphablending($this->workspace, FALSE);
|
301 |
|
|
|
302 |
|
|
// Create a new transparent color for image
|
303 |
|
|
$color = imagecolorallocatealpha($this->workspace, 0, 0, 0, 127);
|
304 |
|
|
|
305 |
|
|
// Completely fill the background of the new image with allocated color.
|
306 |
|
|
imagefill($this->workspace, 0, 0, $color);
|
307 |
|
|
|
308 |
|
|
// Restore transparency blending
|
309 |
|
|
imagesavealpha($this->workspace, TRUE);
|
310 |
|
|
|
311 |
|
|
}
|
312 |
|
|
|
313 |
|
|
/**
|
314 |
|
|
* Create a new workspace a file.
|
315 |
|
|
*
|
316 |
|
|
* This will make the new workspace the current workspace.
|
317 |
|
|
*/
|
318 |
|
|
function command_load($name, $file) {
|
319 |
|
|
$this->log("New workspace: $name (from $file)");
|
320 |
|
|
if (!file_exists($file)) {
|
321 |
|
|
// Try it relative to the plugin
|
322 |
|
|
$file = $this->plugin['path'] . '/' . $file;
|
323 |
|
|
if (!file_exists($file)) {
|
324 |
|
|
$this->log("Unable to open $file");
|
325 |
|
|
return;
|
326 |
|
|
}
|
327 |
|
|
}
|
328 |
|
|
|
329 |
|
|
// Clean up if there was already a workspace there.
|
330 |
|
|
if (isset($this->workspaces[$name])) {
|
331 |
|
|
imagedestroy($this->workspaces[$name]);
|
332 |
|
|
}
|
333 |
|
|
|
334 |
|
|
$this->workspaces[$name] = imagecreatefrompng($file);
|
335 |
|
|
$this->set_current_workspace($name);
|
336 |
|
|
}
|
337 |
|
|
|
338 |
|
|
/**
|
339 |
|
|
* Create a new workspace using the properties of an existing workspace
|
340 |
|
|
*/
|
341 |
|
|
function command_new_from($name, $workspace) {
|
342 |
|
|
$this->log("New workspace: $name from existing $workspace");
|
343 |
|
|
if (empty($this->workspaces[$workspace])) {
|
344 |
|
|
$this->log("Workspace $name does not exist.", 'error');
|
345 |
|
|
return;
|
346 |
|
|
}
|
347 |
|
|
|
348 |
|
|
// Clean up if there was already a workspace there.
|
349 |
|
|
if (isset($this->workspaces[$name])) {
|
350 |
|
|
imagedestroy($this->workspaces[$name]);
|
351 |
|
|
}
|
352 |
|
|
|
353 |
|
|
$this->workspaces[$name] = $this->new_image($this->workspace[$workspace]);
|
354 |
|
|
$this->set_current_workspace($name);
|
355 |
|
|
}
|
356 |
|
|
|
357 |
|
|
/**
|
358 |
|
|
* Set the current workspace.
|
359 |
|
|
*/
|
360 |
|
|
function command_workspace($name) {
|
361 |
|
|
$this->log("Set workspace: $name");
|
362 |
|
|
if (empty($this->workspaces[$name])) {
|
363 |
|
|
$this->log("Workspace $name does not exist.", 'error');
|
364 |
|
|
return;
|
365 |
|
|
}
|
366 |
|
|
$this->set_current_workspace($name);
|
367 |
|
|
}
|
368 |
|
|
|
369 |
|
|
/**
|
370 |
|
|
* Copy the contents of one workspace into the current workspace.
|
371 |
|
|
*/
|
372 |
|
|
function command_merge_from($workspace, $x = 0, $y = 0) {
|
373 |
|
|
$this->log("Merge from: $workspace ($x, $y)");
|
374 |
|
|
if (empty($this->workspaces[$workspace])) {
|
375 |
|
|
$this->log("Workspace $name does not exist.", 'error');
|
376 |
|
|
return;
|
377 |
|
|
}
|
378 |
|
|
|
379 |
|
|
$this->merge($this->workspaces[$workspace], $this->workspace, $x, $y);
|
380 |
|
|
}
|
381 |
|
|
|
382 |
|
|
function command_merge_to($workspace, $x = 0, $y = 0) {
|
383 |
|
|
$this->log("Merge to: $workspace ($x, $y)");
|
384 |
|
|
if (empty($this->workspaces[$workspace])) {
|
385 |
|
|
$this->log("Workspace $name does not exist.", 'error');
|
386 |
|
|
return;
|
387 |
|
|
}
|
388 |
|
|
|
389 |
|
|
$this->merge($this->workspace, $this->workspaces[$workspace], $x, $y);
|
390 |
|
|
$this->set_current_workspace($workspace);
|
391 |
|
|
}
|
392 |
|
|
|
393 |
|
|
/**
|
394 |
|
|
* Blend an image into the current workspace.
|
395 |
|
|
*/
|
396 |
|
|
function command_merge_from_file($file, $x = 0, $y = 0) {
|
397 |
|
|
$this->log("Merge from file: $file ($x, $y)");
|
398 |
|
|
if (!file_exists($file)) {
|
399 |
|
|
// Try it relative to the plugin
|
400 |
|
|
$file = $this->plugin['path'] . '/' . $file;
|
401 |
|
|
if (!file_exists($file)) {
|
402 |
|
|
$this->log("Unable to open $file");
|
403 |
|
|
return;
|
404 |
|
|
}
|
405 |
|
|
}
|
406 |
|
|
|
407 |
|
|
$source = imagecreatefrompng($file);
|
408 |
|
|
|
409 |
|
|
$this->merge($source, $this->workspace, $x, $y);
|
410 |
|
|
|
411 |
|
|
imagedestroy($source);
|
412 |
|
|
}
|
413 |
|
|
|
414 |
|
|
function command_fill($color, $x, $y, $width, $height) {
|
415 |
|
|
$this->log("Fill: $color ($x, $y, $width, $height)");
|
416 |
|
|
imagefilledrectangle($this->workspace, $x, $y, $x + $width, $y + $height, _color_gd($this->workspace, $this->palette[$color]));
|
417 |
|
|
}
|
418 |
|
|
|
419 |
|
|
function command_gradient($from, $to, $x, $y, $width, $height, $direction = 'down') {
|
420 |
|
|
$this->log("Gradient: $from to $to ($x, $y, $width, $height) $direction");
|
421 |
|
|
|
422 |
|
|
if ($direction == 'down') {
|
423 |
|
|
for ($i = 0; $i < $height; ++$i) {
|
424 |
|
|
$color = _color_blend($this->workspace, $this->palette[$from], $this->palette[$to], $i / ($height - 1));
|
425 |
|
|
imagefilledrectangle($this->workspace, $x, $y + $i, $x + $width, $y + $i + 1, $color);
|
426 |
|
|
}
|
427 |
|
|
}
|
428 |
|
|
else {
|
429 |
|
|
for ($i = 0; $i < $width; ++$i) {
|
430 |
|
|
$color = _color_blend($this->workspace, $this->palette[$from], $this->palette[$to], $i / ($width - 1));
|
431 |
|
|
imagefilledrectangle($this->workspace, $x + $i, $y, $x + $i + 1, $y + $height, $color);
|
432 |
|
|
}
|
433 |
|
|
}
|
434 |
|
|
}
|
435 |
|
|
|
436 |
|
|
/**
|
437 |
|
|
* Colorize the current workspace with the given location.
|
438 |
|
|
*
|
439 |
|
|
* This uses simple color blending to colorize the image.
|
440 |
|
|
*
|
441 |
|
|
* @todo it is possible that this colorize could allow different methods for
|
442 |
|
|
* determining how to blend colors?
|
443 |
|
|
*/
|
444 |
|
|
function command_colorize($color, $x = NULL, $y = NULL, $width = NULL, $height = NULL) {
|
445 |
|
|
if (!isset($x)) {
|
446 |
|
|
$whole_image = TRUE;
|
447 |
|
|
$x = $y = 0;
|
448 |
|
|
$width = imagesx($this->workspace);
|
449 |
|
|
$height = imagesy($this->workspace);
|
450 |
|
|
}
|
451 |
|
|
$this->log("Colorize: $color ($x, $y, $width, $height)");
|
452 |
|
|
|
453 |
|
|
$c = _color_unpack($this->palette[$color]);
|
454 |
|
|
|
455 |
|
|
imagealphablending($this->workspace, FALSE);
|
456 |
|
|
imagesavealpha($this->workspace, TRUE);
|
457 |
|
|
|
458 |
|
|
// If PHP 5 use the nice imagefilter which is faster.
|
459 |
|
|
if (!empty($whole_image) && version_compare(phpversion(), '5.2.5', '>=') && function_exists('imagefilter')) {
|
460 |
|
|
imagefilter($this->workspace, IMG_FILTER_COLORIZE, $c[0], $c[1], $c[2]);
|
461 |
|
|
}
|
462 |
|
|
else {
|
463 |
|
|
// Otherwise we can do it the brute force way.
|
464 |
|
|
for ($j = 0; $j < $height; $j++) {
|
465 |
|
|
for ($i = 0; $i < $width; $i++) {
|
466 |
|
|
$current = imagecolorsforindex($this->workspace, imagecolorat($this->workspace, $i, $j));
|
467 |
|
|
$new_index = imagecolorallocatealpha($this->workspace, $c[0], $c[1], $c[2], $current['alpha']);
|
468 |
|
|
imagesetpixel($this->workspace, $i, $j, $new_index);
|
469 |
|
|
}
|
470 |
|
|
}
|
471 |
|
|
}
|
472 |
|
|
}
|
473 |
|
|
|
474 |
|
|
/**
|
475 |
|
|
* Colorize the current workspace with the given location.
|
476 |
|
|
*
|
477 |
|
|
* This uses a color replacement algorithm that retains luminosity but
|
478 |
|
|
* turns replaces all color with the specified color.
|
479 |
|
|
*/
|
480 |
|
|
function command_hue($color, $x = NULL, $y = NULL, $width = NULL, $height = NULL) {
|
481 |
|
|
if (!isset($x)) {
|
482 |
|
|
$whole_image = TRUE;
|
483 |
|
|
$x = $y = 0;
|
484 |
|
|
$width = imagesx($this->workspace);
|
485 |
|
|
$height = imagesy($this->workspace);
|
486 |
|
|
}
|
487 |
|
|
$this->log("Hue: $color ($x, $y, $width, $height)");
|
488 |
|
|
|
489 |
|
|
list($red, $green, $blue) = _color_unpack($this->palette[$color]);
|
490 |
|
|
|
491 |
|
|
// We will create a monochromatic palette based on the input color
|
492 |
|
|
// which will go from black to white.
|
493 |
|
|
|
494 |
|
|
// Input color luminosity: this is equivalent to the position of the
|
495 |
|
|
// input color in the monochromatic palette
|
496 |
|
|
$luminosity_input = round(255 * ($red + $green + $blue) / 765); // 765 = 255 * 3
|
497 |
|
|
|
498 |
|
|
// We fill the palette entry with the input color at itscorresponding position
|
499 |
|
|
$palette[$luminosity_input]['red'] = $red;
|
500 |
|
|
$palette[$luminosity_input]['green'] = $green;
|
501 |
|
|
$palette[$luminosity_input]['blue'] = $blue;
|
502 |
|
|
|
503 |
|
|
// Now we complete the palette, first we'll do it tothe black, and then to
|
504 |
|
|
// the white.
|
505 |
|
|
|
506 |
|
|
// From input to black
|
507 |
|
|
$steps_to_black = $luminosity_input;
|
508 |
|
|
|
509 |
|
|
// The step size for each component
|
510 |
|
|
if ($steps_to_black) {
|
511 |
|
|
$step_size_red = $red / $steps_to_black;
|
512 |
|
|
$step_size_green = $green / $steps_to_black;
|
513 |
|
|
$step_size_blue = $blue / $steps_to_black;
|
514 |
|
|
|
515 |
|
|
for ($i = $steps_to_black; $i >= 0; $i--) {
|
516 |
|
|
$palette[$steps_to_black-$i]['red'] = $red - round($step_size_red * $i);
|
517 |
|
|
$palette[$steps_to_black-$i]['green'] = $green - round($step_size_green * $i);
|
518 |
|
|
$palette[$steps_to_black-$i]['blue'] = $blue - round($step_size_blue * $i);
|
519 |
|
|
}
|
520 |
|
|
}
|
521 |
|
|
|
522 |
|
|
// From input to white
|
523 |
|
|
$steps_to_white = 255 - $luminosity_input;
|
524 |
|
|
|
525 |
|
|
if ($steps_to_white) {
|
526 |
|
|
$step_size_red = (255 - $red) / $steps_to_white;
|
527 |
|
|
$step_size_green = (255 - $green) / $steps_to_white;
|
528 |
|
|
$step_size_blue = (255 - $blue) / $steps_to_white;
|
529 |
|
|
}
|
530 |
|
|
else {
|
531 |
|
|
$step_size_red=$step_size_green=$step_size_blue=0;
|
532 |
|
|
}
|
533 |
|
|
|
534 |
|
|
// The step size for each component
|
535 |
|
|
for ($i = ($luminosity_input + 1); $i <= 255; $i++) {
|
536 |
|
|
$palette[$i]['red'] = $red + round($step_size_red * ($i - $luminosity_input));
|
537 |
|
|
$palette[$i]['green'] = $green + round($step_size_green * ($i - $luminosity_input));
|
538 |
|
|
$palette[$i]['blue']= $blue + round($step_size_blue * ($i - $luminosity_input));
|
539 |
|
|
}
|
540 |
|
|
|
541 |
|
|
// Go over the specified area of the image and update the colors.
|
542 |
|
|
for ($j = $x; $j < $height; $j++) {
|
543 |
|
|
for ($i = $y; $i < $width; $i++) {
|
544 |
|
|
$color = imagecolorsforindex($this->workspace, imagecolorat($this->workspace, $i, $j));
|
545 |
|
|
$luminosity = round(255 * ($color['red'] + $color['green'] + $color['blue']) / 765);
|
546 |
|
|
$new_color = imagecolorallocatealpha($this->workspace, $palette[$luminosity]['red'], $palette[$luminosity]['green'], $palette[$luminosity]['blue'], $color['alpha']);
|
547 |
|
|
imagesetpixel($this->workspace, $i, $j, $new_color);
|
548 |
|
|
}
|
549 |
|
|
}
|
550 |
|
|
}
|
551 |
|
|
|
552 |
|
|
/**
|
553 |
|
|
* Take a slice out of the current workspace and save it as an image.
|
554 |
|
|
*/
|
555 |
|
|
function command_slice($file, $x = NULL, $y = NULL, $width = NULL, $height = NULL) {
|
556 |
|
|
if (!isset($x)) {
|
557 |
|
|
$x = $y = 0;
|
558 |
|
|
$width = imagesx($this->workspace);
|
559 |
|
|
$height = imagesy($this->workspace);
|
560 |
|
|
}
|
561 |
|
|
|
562 |
|
|
$this->log("Slice: $file ($x, $y, $width, $height)");
|
563 |
|
|
|
564 |
|
|
$base = basename($file);
|
565 |
|
|
$image = $this->path . '/' . $base;
|
566 |
|
|
|
567 |
|
|
$slice = $this->new_image($this->workspace, $width, $height);
|
568 |
|
|
imagecopy($slice, $this->workspace, 0, 0, $x, $y, $width, $height);
|
569 |
|
|
|
570 |
|
|
// Make sure alphas are saved:
|
571 |
|
|
imagealphablending($slice, FALSE);
|
572 |
|
|
imagesavealpha($slice, TRUE);
|
573 |
|
|
|
574 |
|
|
// Save image.
|
575 |
|
|
$temp_name = drupal_tempnam('temporary://', 'file');
|
576 |
|
|
|
577 |
|
|
imagepng($slice, drupal_realpath($temp_name));
|
578 |
|
|
file_unmanaged_move($temp_name, $image);
|
579 |
|
|
imagedestroy($slice);
|
580 |
|
|
|
581 |
|
|
// Set standard file permissions for webserver-generated files
|
582 |
|
|
@chmod(realpath($image), 0664);
|
583 |
|
|
|
584 |
|
|
$this->paths[$file] = $image;
|
585 |
|
|
}
|
586 |
|
|
|
587 |
|
|
/**
|
588 |
|
|
* Prepare a new image for being copied or worked on, preserving transparency.
|
589 |
|
|
*/
|
590 |
|
|
function &new_image(&$source, $width = NULL, $height = NULL) {
|
591 |
|
|
if (!isset($width)) {
|
592 |
|
|
$width = imagesx($source);
|
593 |
|
|
}
|
594 |
|
|
|
595 |
|
|
if (!isset($height)) {
|
596 |
|
|
$height = imagesy($source);
|
597 |
|
|
}
|
598 |
|
|
|
599 |
|
|
$target = imagecreatetruecolor($width, $height);
|
600 |
|
|
imagealphablending($target, FALSE);
|
601 |
|
|
imagesavealpha($target, TRUE);
|
602 |
|
|
|
603 |
|
|
$transparency_index = imagecolortransparent($source);
|
604 |
|
|
|
605 |
|
|
// If we have a specific transparent color
|
606 |
|
|
if ($transparency_index >= 0) {
|
607 |
|
|
// Get the original image's transparent color's RGB values
|
608 |
|
|
$transparent_color = imagecolorsforindex($source, $transparency_index);
|
609 |
|
|
|
610 |
|
|
// Allocate the same color in the new image resource
|
611 |
|
|
$transparency_index = imagecolorallocate($target, $transparent_color['red'], $transparent_color['green'], $transparent_color['blue']);
|
612 |
|
|
|
613 |
|
|
// Completely fill the background of the new image with allocated color.
|
614 |
|
|
imagefill($target, 0, 0, $transparency_index);
|
615 |
|
|
|
616 |
|
|
// Set the background color for new image to transparent
|
617 |
|
|
imagecolortransparent($target, $transparency_index);
|
618 |
|
|
}
|
619 |
|
|
// Always make a transparent background color for PNGs that don't have one allocated already
|
620 |
|
|
else {
|
621 |
|
|
// Create a new transparent color for image
|
622 |
|
|
$color = imagecolorallocatealpha($target, 0, 0, 0, 127);
|
623 |
|
|
|
624 |
|
|
// Completely fill the background of the new image with allocated color.
|
625 |
|
|
imagefill($target, 0, 0, $color);
|
626 |
|
|
}
|
627 |
|
|
|
628 |
|
|
return $target;
|
629 |
|
|
}
|
630 |
|
|
|
631 |
|
|
/**
|
632 |
|
|
* Merge two images together, preserving alpha transparency.
|
633 |
|
|
*/
|
634 |
|
|
function merge(&$from, &$to, $x, $y) {
|
635 |
|
|
// Blend over template.
|
636 |
|
|
$width = imagesx($from);
|
637 |
|
|
$height = imagesy($from);
|
638 |
|
|
|
639 |
|
|
// Re-enable alpha blending to make sure transparency merges.
|
640 |
|
|
imagealphablending($to, TRUE);
|
641 |
|
|
imagecopy($to, $from, $x, $y, 0, 0, $width, $height);
|
642 |
|
|
imagealphablending($to, FALSE);
|
643 |
|
|
}
|
644 |
|
|
}
|
645 |
|
|
|
646 |
|
|
/**
|
647 |
|
|
* Get the cached changes to a given task handler.
|
648 |
|
|
*/
|
649 |
|
|
function ctools_stylizer_get_settings_cache($name) {
|
650 |
|
|
ctools_include('object-cache');
|
651 |
|
|
return ctools_object_cache_get('ctools_stylizer_settings', $name);
|
652 |
|
|
}
|
653 |
|
|
|
654 |
|
|
/**
|
655 |
|
|
* Store changes to a task handler in the object cache.
|
656 |
|
|
*/
|
657 |
|
|
function ctools_stylizer_set_settings_cache($name, $settings) {
|
658 |
|
|
ctools_include('object-cache');
|
659 |
|
|
ctools_object_cache_set('ctools_stylizer_settings', $name, $settings);
|
660 |
|
|
}
|
661 |
|
|
|
662 |
|
|
/**
|
663 |
|
|
* Remove an item from the object cache.
|
664 |
|
|
*/
|
665 |
|
|
function ctools_stylizer_clear_settings_cache($name) {
|
666 |
|
|
ctools_include('object-cache');
|
667 |
|
|
ctools_object_cache_clear('ctools_stylizer_settings', $name);
|
668 |
|
|
}
|
669 |
|
|
|
670 |
|
|
/**
|
671 |
|
|
* Add a new style of the specified type.
|
672 |
|
|
*/
|
673 |
|
|
function ctools_stylizer_edit_style(&$info, $js, $step = NULL) {
|
674 |
|
|
$name = '::new';
|
675 |
|
|
$form_info = array(
|
676 |
|
|
'id' => 'ctools_stylizer_edit_style',
|
677 |
|
|
'path' => $info['path'],
|
678 |
|
|
'show trail' => TRUE,
|
679 |
|
|
'show back' => TRUE,
|
680 |
|
|
'show return' => FALSE,
|
681 |
|
|
'next callback' => 'ctools_stylizer_edit_style_next',
|
682 |
|
|
'finish callback' => 'ctools_stylizer_edit_style_finish',
|
683 |
|
|
'return callback' => 'ctools_stylizer_edit_style_finish',
|
684 |
|
|
'cancel callback' => 'ctools_stylizer_edit_style_cancel',
|
685 |
|
|
'forms' => array(
|
686 |
|
|
'choose' => array(
|
687 |
|
|
'form id' => 'ctools_stylizer_edit_style_form_choose',
|
688 |
|
|
),
|
689 |
|
|
),
|
690 |
|
|
);
|
691 |
|
|
|
692 |
|
|
if (empty($info['settings'])) {
|
693 |
|
|
$form_info['order'] = array(
|
694 |
|
|
'choose' => t('Select base style'),
|
695 |
|
|
);
|
696 |
|
|
if (empty($step)) {
|
697 |
|
|
$step = 'choose';
|
698 |
|
|
}
|
699 |
|
|
|
700 |
|
|
if ($step != 'choose') {
|
701 |
|
|
$cache = ctools_stylizer_get_settings_cache($name);
|
702 |
|
|
if (!$cache) {
|
703 |
|
|
$output = t('Missing settings cache.');
|
704 |
|
|
if ($js) {
|
705 |
|
|
return ctools_modal_form_render($form_state, $output);
|
706 |
|
|
}
|
707 |
|
|
else {
|
708 |
|
|
return $output;
|
709 |
|
|
}
|
710 |
|
|
}
|
711 |
|
|
|
712 |
|
|
if (!empty($cache['owner settings'])) {
|
713 |
|
|
$info['owner settings'] = $cache['owner settings'];
|
714 |
|
|
}
|
715 |
|
|
$settings = $cache['settings'];
|
716 |
|
|
}
|
717 |
|
|
else {
|
718 |
|
|
$settings = array(
|
719 |
|
|
'name' => '_temporary',
|
720 |
|
|
'style_base' => NULL,
|
721 |
|
|
'palette' => array(),
|
722 |
|
|
);
|
723 |
|
|
ctools_stylizer_clear_settings_cache($name);
|
724 |
|
|
}
|
725 |
|
|
$op = 'add';
|
726 |
|
|
}
|
727 |
|
|
else {
|
728 |
|
|
$cache = ctools_stylizer_get_settings_cache($info['settings']['name']);
|
729 |
|
|
|
730 |
|
|
if (!empty($cache)) {
|
731 |
|
|
if (!empty($cache['owner settings'])) {
|
732 |
|
|
$info['owner settings'] = $cache['owner settings'];
|
733 |
|
|
}
|
734 |
|
|
$settings = $cache['settings'];
|
735 |
|
|
}
|
736 |
|
|
else {
|
737 |
|
|
$settings = $info['settings'];
|
738 |
|
|
}
|
739 |
|
|
$op = 'edit';
|
740 |
|
|
}
|
741 |
|
|
|
742 |
|
|
if (!empty($info['op'])) {
|
743 |
|
|
// Allow this to override. Necessary to allow cloning properly.
|
744 |
|
|
$op = $info['op'];
|
745 |
|
|
}
|
746 |
|
|
|
747 |
|
|
$plugin = NULL;
|
748 |
|
|
if (!empty($settings['style_base'])) {
|
749 |
|
|
$plugin = ctools_get_style_base($settings['style_base']);
|
750 |
|
|
$info['type'] = $plugin['type'];
|
751 |
|
|
ctools_stylizer_add_plugin_forms($form_info, $plugin, $op);
|
752 |
|
|
}
|
753 |
|
|
else {
|
754 |
|
|
// This is here so the 'finish' button does not show up, and because
|
755 |
|
|
// we don't have the selected style we don't know what the next form(s)
|
756 |
|
|
// will be.
|
757 |
|
|
$form_info['order']['next'] = t('Configure style');
|
758 |
|
|
}
|
759 |
|
|
|
760 |
|
|
if (count($form_info['order']) < 2 || $step == 'choose') {
|
761 |
|
|
$form_info['show trail'] = FALSE;
|
762 |
|
|
}
|
763 |
|
|
|
764 |
|
|
$form_state = array(
|
765 |
|
|
'module' => $info['module'],
|
766 |
|
|
'type' => $info['type'],
|
767 |
|
|
'owner info' => &$info,
|
768 |
|
|
'base_style_plugin' => $plugin,
|
769 |
|
|
'name' => $name,
|
770 |
|
|
'step' => $step,
|
771 |
|
|
'settings' => $settings,
|
772 |
|
|
'ajax' => $js,
|
773 |
|
|
'op' => $op,
|
774 |
|
|
);
|
775 |
|
|
|
776 |
|
|
if (!empty($info['modal'])) {
|
777 |
|
|
$form_state['modal'] = TRUE;
|
778 |
|
|
$form_state['title'] = $info['modal'];
|
779 |
|
|
$form_state['modal return'] = TRUE;
|
780 |
|
|
}
|
781 |
|
|
|
782 |
|
|
ctools_include('wizard');
|
783 |
|
|
$output = ctools_wizard_multistep_form($form_info, $step, $form_state);
|
784 |
|
|
|
785 |
|
|
if (!empty($form_state['complete'])) {
|
786 |
|
|
$info['complete'] = TRUE;
|
787 |
|
|
$info['settings'] = $form_state['settings'];
|
788 |
|
|
}
|
789 |
|
|
|
790 |
|
|
if ($js && !$output && !empty($form_state['clicked_button']['#next'])) {
|
791 |
|
|
// We have to do a separate redirect here because the formula that adds
|
792 |
|
|
// stuff to the wizard after being chosen hasn't happened. The wizard
|
793 |
|
|
// tried to go to the next step which did not exist.
|
794 |
|
|
return ctools_stylizer_edit_style($info, $js, $form_state['clicked_button']['#next']);
|
795 |
|
|
}
|
796 |
|
|
|
797 |
|
|
if ($js) {
|
798 |
|
|
return ctools_modal_form_render($form_state, $output);
|
799 |
|
|
}
|
800 |
|
|
else {
|
801 |
|
|
return $output;
|
802 |
|
|
}
|
803 |
|
|
}
|
804 |
|
|
|
805 |
|
|
/**
|
806 |
|
|
* Add wizard forms specific to a style base plugin.
|
807 |
|
|
*
|
808 |
|
|
* The plugin can store forms either as a simple 'edit form'
|
809 |
|
|
* => 'form callback' or if it needs the more complicated wizard
|
810 |
|
|
* functionality, it can set 'forms' and 'order' with values suitable
|
811 |
|
|
* for the wizard $form_info array.
|
812 |
|
|
*
|
813 |
|
|
* @param &$form_info
|
814 |
|
|
* The form info to modify.
|
815 |
|
|
* @param $plugin
|
816 |
|
|
* The plugin to use.
|
817 |
|
|
* @param $op
|
818 |
|
|
* Either 'add' or 'edit' so we can get the right forms.
|
819 |
|
|
*/
|
820 |
|
|
function ctools_stylizer_add_plugin_forms(&$form_info, $plugin, $op) {
|
821 |
|
|
if (empty($plugin['forms'])) {
|
822 |
|
|
if ($op == 'add' && isset($plugin['add form'])) {
|
823 |
|
|
$id = $plugin['add form'];
|
824 |
|
|
}
|
825 |
|
|
else if (isset($plugin['edit form'])) {
|
826 |
|
|
$id = $plugin['edit form'];
|
827 |
|
|
}
|
828 |
|
|
else {
|
829 |
|
|
$id = 'ctools_stylizer_edit_style_form_default';
|
830 |
|
|
}
|
831 |
|
|
|
832 |
|
|
$form_info['forms']['settings'] = array(
|
833 |
|
|
'form id' => $id,
|
834 |
|
|
);
|
835 |
|
|
$form_info['order']['settings'] = t('Settings');
|
836 |
|
|
}
|
837 |
|
|
else {
|
838 |
|
|
$form_info['forms'] += $plugin['forms'];
|
839 |
|
|
$form_info['order'] += $plugin['order'];
|
840 |
|
|
}
|
841 |
|
|
}
|
842 |
|
|
|
843 |
|
|
/**
|
844 |
|
|
* Callback generated when the add style process is finished.
|
845 |
|
|
*/
|
846 |
|
|
function ctools_stylizer_edit_style_finish(&$form_state) {
|
847 |
|
|
$form_state['complete'] = TRUE;
|
848 |
|
|
ctools_stylizer_clear_settings_cache($form_state['name']);
|
849 |
|
|
|
850 |
|
|
if (isset($form_state['settings']['old_settings'])) {
|
851 |
|
|
unset($form_state['settings']['old_settings']);
|
852 |
|
|
}
|
853 |
|
|
}
|
854 |
|
|
|
855 |
|
|
/**
|
856 |
|
|
* Callback generated when the 'next' button is clicked.
|
857 |
|
|
*/
|
858 |
|
|
function ctools_stylizer_edit_style_next(&$form_state) {
|
859 |
|
|
$form_state['form_info']['path'] = str_replace('%name', $form_state['name'], $form_state['form_info']['path']);
|
860 |
|
|
$form_state['redirect'] = ctools_wizard_get_path($form_state['form_info'], $form_state['clicked_button']['#next']);
|
861 |
|
|
|
862 |
|
|
// Update the cache with changes.
|
863 |
|
|
$cache = array('settings' => $form_state['settings']);
|
864 |
|
|
if (!empty($form_state['owner info']['owner settings'])) {
|
865 |
|
|
$cache['owner settings'] = $form_state['owner info']['owner settings'];
|
866 |
|
|
}
|
867 |
|
|
ctools_stylizer_set_settings_cache($form_state['name'], $cache);
|
868 |
|
|
}
|
869 |
|
|
|
870 |
|
|
/**
|
871 |
|
|
* Callback generated when the 'cancel' button is clicked.
|
872 |
|
|
*
|
873 |
|
|
* We might have some temporary data lying around. We must remove it.
|
874 |
|
|
*/
|
875 |
|
|
function ctools_stylizer_edit_style_cancel(&$form_state) {
|
876 |
|
|
if (!empty($form_state['name'])) {
|
877 |
|
|
ctools_stylizer_clear_settings_cache($form_state['name']);
|
878 |
|
|
}
|
879 |
|
|
}
|
880 |
|
|
|
881 |
|
|
/**
|
882 |
|
|
* Choose which plugin to use to create a new style.
|
883 |
|
|
*/
|
884 |
|
|
function ctools_stylizer_edit_style_form_choose($form, &$form_state) {
|
885 |
|
|
$plugins = ctools_get_style_bases();
|
886 |
|
|
$options = array();
|
887 |
|
|
|
888 |
|
|
$categories = array();
|
889 |
|
|
foreach ($plugins as $name => $plugin) {
|
890 |
|
|
if ($form_state['module'] == $plugin['module'] && $form_state['type'] == $plugin['type']) {
|
891 |
|
|
$categories[$plugin['category']] = $plugin['category'];
|
892 |
|
|
$unsorted_options[$plugin['category']][$name] = ctools_stylizer_print_style_icon($plugin, TRUE);
|
893 |
|
|
}
|
894 |
|
|
}
|
895 |
|
|
|
896 |
|
|
asort($categories);
|
897 |
|
|
|
898 |
|
|
foreach ($categories as $category) {
|
899 |
|
|
$options[$category] = $unsorted_options[$category];
|
900 |
|
|
}
|
901 |
|
|
|
902 |
|
|
$form['style_base'] = array(
|
903 |
|
|
'#prefix' => '<div class="ctools-style-icons clearfix">',
|
904 |
|
|
'#suffix' => '</div>',
|
905 |
|
|
);
|
906 |
|
|
|
907 |
|
|
ctools_include('cleanstring');
|
908 |
|
|
foreach ($options as $category => $radios) {
|
909 |
|
|
$cat = ctools_cleanstring($category);
|
910 |
|
|
$form['style_base'][$cat] = array(
|
911 |
|
|
'#prefix' => '<div class="ctools-style-category clearfix"><label>' . $category . '</label>',
|
912 |
|
|
'#suffix' => '</div>',
|
913 |
|
|
);
|
914 |
|
|
|
915 |
|
|
foreach ($radios as $key => $choice) {
|
916 |
|
|
// Generate the parents as the autogenerator does, so we will have a
|
917 |
|
|
// unique id for each radio button.
|
918 |
|
|
$form['style_base'][$cat][$key] = array(
|
919 |
|
|
'#type' => 'radio',
|
920 |
|
|
'#title' => $choice,
|
921 |
|
|
'#parents' => array('style_base'),
|
922 |
|
|
'#id' => drupal_clean_css_identifier('edit-style-base-' . $key),
|
923 |
|
|
'#return_value' => check_plain($key),
|
924 |
|
|
);
|
925 |
|
|
}
|
926 |
|
|
}
|
927 |
|
|
|
928 |
|
|
return $form;
|
929 |
|
|
}
|
930 |
|
|
|
931 |
|
|
function ctools_stylizer_edit_style_form_choose_submit($form, &$form_state) {
|
932 |
|
|
$form_state['settings']['style_base'] = $form_state['values']['style_base'];
|
933 |
|
|
|
934 |
|
|
// The 'next' form will show up as 'next' but that's not accurate now that
|
935 |
|
|
// we have a style. Figure out what next really is and update.
|
936 |
|
|
$plugin = ctools_get_style_base($form_state['settings']['style_base']);
|
937 |
|
|
if (empty($plugin['forms'])) {
|
938 |
|
|
$form_state['clicked_button']['#next'] = 'settings';
|
939 |
|
|
}
|
940 |
|
|
else {
|
941 |
|
|
$forms = array_keys($form_info['forms']);
|
942 |
|
|
$form_state['clicked_button']['#next'] = array_shift($forms);
|
943 |
|
|
}
|
944 |
|
|
|
945 |
|
|
// Fill in the defaults for the settings.
|
946 |
|
|
if (!empty($plugin['defaults'])) {
|
947 |
|
|
// @todo allow a callback
|
948 |
|
|
$form_state['settings'] += $plugin['defaults'];
|
949 |
|
|
}
|
950 |
|
|
|
951 |
|
|
return $form;
|
952 |
|
|
}
|
953 |
|
|
|
954 |
|
|
/**
|
955 |
|
|
* The default stylizer style editing form.
|
956 |
|
|
*
|
957 |
|
|
* Even when not using this, styles should call through to this form in
|
958 |
|
|
* their own edit forms.
|
959 |
|
|
*/
|
960 |
|
|
function ctools_stylizer_edit_style_form_default($form, &$form_state) {
|
961 |
|
|
ctools_add_js('stylizer');
|
962 |
|
|
ctools_add_css('stylizer');
|
963 |
|
|
drupal_add_library('system', 'farbtastic');
|
964 |
|
|
|
965 |
|
|
$plugin = &$form_state['base_style_plugin'];
|
966 |
|
|
$settings = &$form_state['settings'];
|
967 |
|
|
|
968 |
|
|
$form['top box'] = array(
|
969 |
|
|
'#prefix' => '<div id="ctools-stylizer-top-box" class="clearfix">',
|
970 |
|
|
'#suffix' => '</div>',
|
971 |
|
|
);
|
972 |
|
|
$form['top box']['left'] = array(
|
973 |
|
|
'#prefix' => '<div id="ctools-stylizer-left-box">',
|
974 |
|
|
'#suffix' => '</div>',
|
975 |
|
|
);
|
976 |
|
|
$form['top box']['preview'] = array(
|
977 |
|
|
// We have a copy of the $form_state on $form because form theme functions
|
978 |
|
|
// do not get $form_state.
|
979 |
|
|
'#theme' => 'ctools_stylizer_preview_form',
|
980 |
|
|
'#form_state' => &$form_state,
|
981 |
|
|
);
|
982 |
|
|
|
983 |
|
|
$form['top box']['preview']['submit'] = array(
|
984 |
|
|
'#type' => 'submit',
|
985 |
|
|
'#value' => t('Preview'),
|
986 |
|
|
);
|
987 |
|
|
|
988 |
|
|
if (!empty($plugin['palette'])) {
|
989 |
|
|
$form['top box']['color'] = array(
|
990 |
|
|
'#type' => 'fieldset',
|
991 |
|
|
'#title' => t('Color scheme'),
|
992 |
|
|
'#attributes' => array('id' => 'ctools_stylizer_color_scheme_form', 'class' => array('ctools-stylizer-color-edit')),
|
993 |
|
|
'#theme' => 'ctools_stylizer_color_scheme_form',
|
994 |
|
|
);
|
995 |
|
|
|
996 |
|
|
$form['top box']['color']['palette']['#tree'] = TRUE;
|
997 |
|
|
|
998 |
|
|
foreach ($plugin['palette'] as $key => $color) {
|
999 |
|
|
if (empty($settings['palette'][$key])) {
|
1000 |
|
|
$settings['palette'][$key] = $color['default_value'];
|
1001 |
|
|
}
|
1002 |
|
|
|
1003 |
|
|
$form['top box']['color']['palette'][$key] = array(
|
1004 |
|
|
'#type' => 'textfield',
|
1005 |
|
|
'#title' => $color['label'],
|
1006 |
|
|
'#default_value' => $settings['palette'][$key],
|
1007 |
|
|
'#size' => 8,
|
1008 |
|
|
);
|
1009 |
|
|
}
|
1010 |
|
|
}
|
1011 |
|
|
|
1012 |
|
|
if (!empty($plugin['settings form']) && function_exists($plugin['settings form'])) {
|
1013 |
|
|
$plugin['settings form']($form, $form_state);
|
1014 |
|
|
}
|
1015 |
|
|
|
1016 |
|
|
if (!empty($form_state['owner info']['owner form']) && function_exists($form_state['owner info']['owner form'])) {
|
1017 |
|
|
$form_state['owner info']['owner form']($form, $form_state);
|
1018 |
|
|
}
|
1019 |
|
|
|
1020 |
|
|
return $form;
|
1021 |
|
|
}
|
1022 |
|
|
|
1023 |
|
|
/**
|
1024 |
|
|
* Theme the stylizer color scheme form.
|
1025 |
|
|
*/
|
1026 |
|
|
function theme_ctools_stylizer_color_scheme_form($vars) {
|
1027 |
|
|
$form = &$vars['form'];
|
1028 |
|
|
$output = '';
|
1029 |
|
|
|
1030 |
|
|
// Wrapper
|
1031 |
|
|
$output .= '<div class="color-form clearfix">';
|
1032 |
|
|
|
1033 |
|
|
// Color schemes
|
1034 |
|
|
// $output .= drupal_render($form['scheme']);
|
1035 |
|
|
|
1036 |
|
|
// Palette
|
1037 |
|
|
$output .= '<div id="palette" class="clearfix">';
|
1038 |
|
|
foreach (element_children($form['palette']) as $name) {
|
1039 |
|
|
$output .= render($form['palette'][$name]);
|
1040 |
|
|
}
|
1041 |
|
|
$output .= '</div>'; // palette
|
1042 |
|
|
|
1043 |
|
|
$output .= '</div>'; // color form
|
1044 |
|
|
|
1045 |
|
|
return $output;
|
1046 |
|
|
}
|
1047 |
|
|
|
1048 |
|
|
/**
|
1049 |
|
|
* Theme the stylizer preview form.
|
1050 |
|
|
*/
|
1051 |
|
|
function theme_ctools_stylizer_preview_form($vars) {
|
1052 |
|
|
$form = &$vars['form'];
|
1053 |
|
|
|
1054 |
|
|
$plugin = $form['#form_state']['base_style_plugin'];
|
1055 |
|
|
$settings = $form['#form_state']['settings'];
|
1056 |
|
|
|
1057 |
|
|
if (!empty($form['#form_state']['settings']['old_settings'])) {
|
1058 |
|
|
ctools_stylizer_cleanup_style($plugin, $form['#form_state']['settings']['old_settings']);
|
1059 |
|
|
}
|
1060 |
|
|
$preview = '';
|
1061 |
|
|
if (!empty($plugin['preview'])) {
|
1062 |
|
|
$preview = $plugin['preview'];
|
1063 |
|
|
}
|
1064 |
|
|
else {
|
1065 |
|
|
$base_types = ctools_get_style_base_types();
|
1066 |
|
|
if (!empty($base_types[$plugin['module']][$plugin['type']]['preview'])) {
|
1067 |
|
|
$preview = $base_types[$plugin['module']][$plugin['type']]['preview'];
|
1068 |
|
|
}
|
1069 |
|
|
}
|
1070 |
|
|
|
1071 |
|
|
if (!empty($preview) && function_exists($preview)) {
|
1072 |
|
|
$output = '<fieldset id="preview"><legend>' . t('Preview') . '</legend>';
|
1073 |
|
|
$output .= $preview($plugin, $settings);
|
1074 |
|
|
$output .= drupal_render_children($form);
|
1075 |
|
|
$output .= '</fieldset>';
|
1076 |
|
|
|
1077 |
|
|
return $output;
|
1078 |
|
|
}
|
1079 |
|
|
}
|
1080 |
|
|
|
1081 |
|
|
function ctools_stylizer_edit_style_form_default_validate($form, &$form_state) {
|
1082 |
|
|
if (!empty($form_state['owner info']['owner form validate']) && function_exists($form_state['owner info']['owner form validate'])) {
|
1083 |
|
|
$form_state['owner info']['owner form validate']($form, $form_state);
|
1084 |
|
|
}
|
1085 |
|
|
|
1086 |
|
|
if (!empty($form_state['base_style_plugin']['settings form validate']) && function_exists($form_state['base_style_plugin']['settings form validate'])) {
|
1087 |
|
|
$form_state['base_style_plugin']['settings form validate']($form, $form_state);
|
1088 |
|
|
}
|
1089 |
|
|
}
|
1090 |
|
|
|
1091 |
|
|
function ctools_stylizer_edit_style_form_default_submit($form, &$form_state) {
|
1092 |
|
|
// Store old settings for the purposes of cleaning up.
|
1093 |
|
|
$form_state['settings']['old_settings'] = $form_state['settings'];
|
1094 |
|
|
$form_state['settings']['palette'] = $form_state['values']['palette'];
|
1095 |
|
|
|
1096 |
|
|
if (!empty($form_state['owner info']['owner form submit']) && function_exists($form_state['owner info']['owner form submit'])) {
|
1097 |
|
|
$form_state['owner info']['owner form submit']($form, $form_state);
|
1098 |
|
|
}
|
1099 |
|
|
|
1100 |
|
|
if (!empty($form_state['base_style_plugin']['settings form submit']) && function_exists($form_state['base_style_plugin']['settings form submit'])) {
|
1101 |
|
|
$form_state['base_style_plugin']['settings form submit']($form, $form_state);
|
1102 |
|
|
}
|
1103 |
|
|
|
1104 |
|
|
if ($form_state['clicked_button']['#value'] == t('Preview')) {
|
1105 |
|
|
$form_state['rerender'] = TRUE;
|
1106 |
|
|
// Update the cache with changes.
|
1107 |
|
|
if (!empty($form_state['name'])) {
|
1108 |
|
|
$cache = array('settings' => $form_state['settings']);
|
1109 |
|
|
if (!empty($form_state['owner info']['owner settings'])) {
|
1110 |
|
|
$cache['owner settings'] = $form_state['owner info']['owner settings'];
|
1111 |
|
|
}
|
1112 |
|
|
ctools_stylizer_set_settings_cache($form_state['name'], $cache);
|
1113 |
|
|
}
|
1114 |
|
|
}
|
1115 |
|
|
}
|
1116 |
|
|
|
1117 |
|
|
// --------------------------------------------------------------------------
|
1118 |
|
|
// CSS forms and tools that plugins can use.
|
1119 |
|
|
|
1120 |
|
|
/**
|
1121 |
|
|
* Font selector form
|
1122 |
|
|
*/
|
1123 |
|
|
function ctools_stylizer_font_selector_form(&$form, &$form_state, $label, $settings) {
|
1124 |
|
|
// Family
|
1125 |
|
|
$form['#prefix'] = '<div class="ctools-stylizer-spacing-form clearfix">';
|
1126 |
|
|
$form['#type'] = 'fieldset';
|
1127 |
|
|
$form['#title'] = $label;
|
1128 |
|
|
$form['#suffix'] = '</div>';
|
1129 |
|
|
$form['#tree'] = TRUE;
|
1130 |
|
|
|
1131 |
|
|
$form['font'] = array(
|
1132 |
|
|
'#title' => t('Font family'),
|
1133 |
|
|
'#type' => 'select',
|
1134 |
|
|
'#default_value' => isset($settings['font']) ? $settings['font'] : '',
|
1135 |
|
|
'#options' => array(
|
1136 |
|
|
'' => '',
|
1137 |
|
|
'Arial, Helvetica, sans-serif' => t('Arial, Helvetica, sans-serif'),
|
1138 |
|
|
'Times New Roman, Times, serif' => t('Times New Roman, Times, serif'),
|
1139 |
|
|
'Courier New, Courier, monospace' => t('Courier New, Courier, monospace'),
|
1140 |
|
|
'Georgia, Times New Roman, Times, serif' => t('Georgia, Times New Roman, Times, serif'),
|
1141 |
|
|
'Verdana, Arial, Helvetica, sans-serif' => t('Verdana, Arial, Helvetica, sans-serif'),
|
1142 |
|
|
'Geneva, Arial, Helvetica, sans-serif' => t('Geneva, Arial, Helvetica, sans-serif'),
|
1143 |
|
|
'Trebuchet MS, Trebuchet, Verdana, sans-serif' => t('Trebuchet MS, Trebuchet, Verdana, sans-serif'),
|
1144 |
|
|
),
|
1145 |
|
|
);
|
1146 |
|
|
|
1147 |
|
|
// size
|
1148 |
|
|
$form['size'] = array(
|
1149 |
|
|
'#title' => t('Size'),
|
1150 |
|
|
'#type' => 'select',
|
1151 |
|
|
'#default_value' => isset($settings['size']) ? $settings['size'] : '',
|
1152 |
|
|
'#options' => array(
|
1153 |
|
|
'' => '',
|
1154 |
|
|
'xx-small' => t('XX-Small'),
|
1155 |
|
|
'x-small' => t('X-Small'),
|
1156 |
|
|
'small' => t('Small'),
|
1157 |
|
|
'medium' => t('Medium'),
|
1158 |
|
|
'large' => t('Large'),
|
1159 |
|
|
'x-large' => t('X-Large'),
|
1160 |
|
|
'xx-large' => t('XX-Large'),
|
1161 |
|
|
),
|
1162 |
|
|
);
|
1163 |
|
|
|
1164 |
|
|
// letter spacing
|
1165 |
|
|
$form['letter_spacing'] = array(
|
1166 |
|
|
'#title' => t('Letter spacing'),
|
1167 |
|
|
'#type' => 'select',
|
1168 |
|
|
'#default_value' => isset($settings['letter_spacing']) ? $settings['letter_spacing'] : '',
|
1169 |
|
|
'#options' => array(
|
1170 |
|
|
'' => '',
|
1171 |
|
|
"-10px" => '10px',
|
1172 |
|
|
"-9px" => '9px',
|
1173 |
|
|
"-8px" => '8px',
|
1174 |
|
|
"-7px" => '7px',
|
1175 |
|
|
"-6px" => '6px',
|
1176 |
|
|
"-5px" => '5px',
|
1177 |
|
|
"-4px" => '4px',
|
1178 |
|
|
"-3px" => '3px',
|
1179 |
|
|
"-2px" => '2px',
|
1180 |
|
|
"-1px" => '1px',
|
1181 |
|
|
"0" => '0',
|
1182 |
|
|
"1px" => '1px',
|
1183 |
|
|
"2px" => '2px',
|
1184 |
|
|
"3px" => '3px',
|
1185 |
|
|
"4px" => '4px',
|
1186 |
|
|
"5px" => '5px',
|
1187 |
|
|
"6px" => '6px',
|
1188 |
|
|
"7px" => '7px',
|
1189 |
|
|
"8px" => '8px',
|
1190 |
|
|
"9px" => '9px',
|
1191 |
|
|
"10px" => '10px',
|
1192 |
|
|
"11px" => '11px',
|
1193 |
|
|
"12px" => '12px',
|
1194 |
|
|
"13px" => '13px',
|
1195 |
|
|
"14px" => '14px',
|
1196 |
|
|
"15px" => '15px',
|
1197 |
|
|
"16px" => '16px',
|
1198 |
|
|
"17px" => '17px',
|
1199 |
|
|
"18px" => '18px',
|
1200 |
|
|
"19px" => '19px',
|
1201 |
|
|
"20px" => '20px',
|
1202 |
|
|
"21px" => '21px',
|
1203 |
|
|
"22px" => '22px',
|
1204 |
|
|
"23px" => '23px',
|
1205 |
|
|
"24px" => '24px',
|
1206 |
|
|
"25px" => '25px',
|
1207 |
|
|
"26px" => '26px',
|
1208 |
|
|
"27px" => '27px',
|
1209 |
|
|
"28px" => '28px',
|
1210 |
|
|
"29px" => '29px',
|
1211 |
|
|
"30px" => '30px',
|
1212 |
|
|
"31px" => '31px',
|
1213 |
|
|
"32px" => '32px',
|
1214 |
|
|
"33px" => '33px',
|
1215 |
|
|
"34px" => '34px',
|
1216 |
|
|
"35px" => '35px',
|
1217 |
|
|
"36px" => '36px',
|
1218 |
|
|
"37px" => '37px',
|
1219 |
|
|
"38px" => '38px',
|
1220 |
|
|
"39px" => '39px',
|
1221 |
|
|
"40px" => '40px',
|
1222 |
|
|
"41px" => '41px',
|
1223 |
|
|
"42px" => '42px',
|
1224 |
|
|
"43px" => '43px',
|
1225 |
|
|
"44px" => '44px',
|
1226 |
|
|
"45px" => '45px',
|
1227 |
|
|
"46px" => '46px',
|
1228 |
|
|
"47px" => '47px',
|
1229 |
|
|
"48px" => '48px',
|
1230 |
|
|
"49px" => '49px',
|
1231 |
|
|
"50px" => '50px',
|
1232 |
|
|
),
|
1233 |
|
|
);
|
1234 |
|
|
|
1235 |
|
|
// word space
|
1236 |
|
|
$form['word_spacing'] = array(
|
1237 |
|
|
'#title' => t('Word spacing'),
|
1238 |
|
|
'#type' => 'select',
|
1239 |
|
|
'#default_value' => isset($settings['word_spacing']) ? $settings['word_spacing'] : '',
|
1240 |
|
|
'#options' => array(
|
1241 |
|
|
'' => '',
|
1242 |
|
|
"-1em" => '-1em',
|
1243 |
|
|
"-0.95em" => '-0.95em',
|
1244 |
|
|
"-0.9em" => '-0.9em',
|
1245 |
|
|
"-0.85em" => '-0.85em',
|
1246 |
|
|
"-0.8em" => '-0.8em',
|
1247 |
|
|
"-0.75em" => '-0.75em',
|
1248 |
|
|
"-0.7em" => '-0.7em',
|
1249 |
|
|
"-0.65em" => '-0.65em',
|
1250 |
|
|
"-0.6em" => '-0.6em',
|
1251 |
|
|
"-0.55em" => '-0.55em',
|
1252 |
|
|
"-0.5em" => '-0.5em',
|
1253 |
|
|
"-0.45em" => '-0.45em',
|
1254 |
|
|
"-0.4em" => '-0.4em',
|
1255 |
|
|
"-0.35em" => '-0.35em',
|
1256 |
|
|
"-0.3em" => '-0.3em',
|
1257 |
|
|
"-0.25em" => '-0.25em',
|
1258 |
|
|
"-0.2em" => '-0.2em',
|
1259 |
|
|
"-0.15em" => '-0.15em',
|
1260 |
|
|
"-0.1em" => '-0.1em',
|
1261 |
|
|
"-0.05em" => '-0.05em',
|
1262 |
|
|
"normal" => 'normal',
|
1263 |
|
|
"0.05em" => '0.05em',
|
1264 |
|
|
"0.1em" => '0.1em',
|
1265 |
|
|
"0.15em" => '0.15em',
|
1266 |
|
|
"0.2em" => '0.2em',
|
1267 |
|
|
"0.25em" => '0.25em',
|
1268 |
|
|
"0.3em" => '0.3em',
|
1269 |
|
|
"0.35em" => '0.35em',
|
1270 |
|
|
"0.4em" => '0.4em',
|
1271 |
|
|
"0.45em" => '0.45em',
|
1272 |
|
|
"0.5em" => '0.5em',
|
1273 |
|
|
"0.55em" => '0.55em',
|
1274 |
|
|
"0.6em" => '0.6em',
|
1275 |
|
|
"0.65em" => '0.65em',
|
1276 |
|
|
"0.7em" => '0.7em',
|
1277 |
|
|
"0.75em" => '0.75em',
|
1278 |
|
|
"0.8em" => '0.8em',
|
1279 |
|
|
"0.85em" => '0.85em',
|
1280 |
|
|
"0.9em" => '0.9em',
|
1281 |
|
|
"0.95em" => '0.95em',
|
1282 |
|
|
"1em" => '1em',
|
1283 |
|
|
),
|
1284 |
|
|
);
|
1285 |
|
|
|
1286 |
|
|
// decoration
|
1287 |
|
|
$form['decoration'] = array(
|
1288 |
|
|
'#title' => t('Decoration'),
|
1289 |
|
|
'#type' => 'select',
|
1290 |
|
|
'#default_value' => isset($settings['decoration']) ? $settings['decoration'] : '',
|
1291 |
|
|
'#options' => array(
|
1292 |
|
|
'' => '',
|
1293 |
|
|
'none' => t('None'),
|
1294 |
|
|
'underline' => t('Underline'),
|
1295 |
|
|
'overline' => t('Overline'),
|
1296 |
|
|
'line-through' => t('Line-through'),
|
1297 |
|
|
),
|
1298 |
|
|
);
|
1299 |
|
|
|
1300 |
|
|
// weight
|
1301 |
|
|
$form['weight'] = array(
|
1302 |
|
|
'#title' => t('Weight'),
|
1303 |
|
|
'#type' => 'select',
|
1304 |
|
|
'#default_value' => isset($settings['weight']) ? $settings['weight'] : '',
|
1305 |
|
|
'#options' => array(
|
1306 |
|
|
'' => '',
|
1307 |
|
|
'normal' => t('Normal'),
|
1308 |
|
|
'bold' => t('Bold'),
|
1309 |
|
|
'bolder' => t('Bolder'),
|
1310 |
|
|
'lighter' => t('Lighter'),
|
1311 |
|
|
),
|
1312 |
|
|
);
|
1313 |
|
|
|
1314 |
|
|
// style
|
1315 |
|
|
$form['style'] = array(
|
1316 |
|
|
'#title' => t('Style'),
|
1317 |
|
|
'#type' => 'select',
|
1318 |
|
|
'#default_value' => isset($settings['style']) ? $settings['style'] : '',
|
1319 |
|
|
'#options' => array(
|
1320 |
|
|
'' => '',
|
1321 |
|
|
'normal' => t('Normal'),
|
1322 |
|
|
'italic' => t('Italic'),
|
1323 |
|
|
'oblique' => t('Oblique'),
|
1324 |
|
|
),
|
1325 |
|
|
);
|
1326 |
|
|
|
1327 |
|
|
// variant
|
1328 |
|
|
$form['variant'] = array(
|
1329 |
|
|
'#title' => t('Variant'),
|
1330 |
|
|
'#type' => 'select',
|
1331 |
|
|
'#default_value' => isset($settings['variant']) ? $settings['variant'] : '',
|
1332 |
|
|
'#options' => array(
|
1333 |
|
|
'' => '',
|
1334 |
|
|
'normal' => t('Normal'),
|
1335 |
|
|
'small-caps' => t('Small-caps'),
|
1336 |
|
|
),
|
1337 |
|
|
);
|
1338 |
|
|
|
1339 |
|
|
// case
|
1340 |
|
|
$form['case'] = array(
|
1341 |
|
|
'#title' => t('Case'),
|
1342 |
|
|
'#type' => 'select',
|
1343 |
|
|
'#default_value' => isset($settings['case']) ? $settings['case'] : '',
|
1344 |
|
|
'#options' => array(
|
1345 |
|
|
'' => '',
|
1346 |
|
|
'capitalize' => t('Capitalize'),
|
1347 |
|
|
'uppercase' => t('Uppercase'),
|
1348 |
|
|
'lowercase' => t('Lowercase'),
|
1349 |
|
|
'none' => t('None'),
|
1350 |
|
|
),
|
1351 |
|
|
);
|
1352 |
|
|
|
1353 |
|
|
// alignment
|
1354 |
|
|
$form['alignment'] = array(
|
1355 |
|
|
'#title' => t('Align'),
|
1356 |
|
|
'#type' => 'select',
|
1357 |
|
|
'#default_value' => isset($settings['alignment']) ? $settings['alignment'] : '',
|
1358 |
|
|
'#options' => array(
|
1359 |
|
|
'' => '',
|
1360 |
|
|
'justify' => t('Justify'),
|
1361 |
|
|
'left' => t('Left'),
|
1362 |
|
|
'right' => t('Right'),
|
1363 |
|
|
'center' => t('Center'),
|
1364 |
|
|
),
|
1365 |
|
|
);
|
1366 |
|
|
}
|
1367 |
|
|
|
1368 |
|
|
/**
|
1369 |
|
|
* Copy font selector information into the settings
|
1370 |
|
|
*/
|
1371 |
|
|
function ctools_stylizer_font_selector_form_submit(&$form, &$form_state, &$values, &$settings) {
|
1372 |
|
|
$settings = $values;
|
1373 |
|
|
}
|
1374 |
|
|
|
1375 |
|
|
function ctools_stylizer_font_apply_style(&$stylesheet, $selector, $settings) {
|
1376 |
|
|
$css = '';
|
1377 |
|
|
if (isset($settings['font']) && $settings['font'] !== '') {
|
1378 |
|
|
$css .= ' font-family: ' . $settings['font'] . ";\n";
|
1379 |
|
|
}
|
1380 |
|
|
|
1381 |
|
|
if (isset($settings['size']) && $settings['size'] !== '') {
|
1382 |
|
|
$css .= ' font-size: ' . $settings['size'] . ";\n";
|
1383 |
|
|
}
|
1384 |
|
|
|
1385 |
|
|
if (isset($settings['weight']) && $settings['weight'] !== '') {
|
1386 |
|
|
$css .= ' font-weight: ' . $settings['weight'] . ";\n";
|
1387 |
|
|
}
|
1388 |
|
|
|
1389 |
|
|
if (isset($settings['style']) && $settings['style'] !== '') {
|
1390 |
|
|
$css .= ' font-style: ' . $settings['style'] . ";\n";
|
1391 |
|
|
}
|
1392 |
|
|
|
1393 |
|
|
if (isset($settings['variant']) && $settings['variant'] !== '') {
|
1394 |
|
|
$css .= ' font-variant: ' . $settings['variant'] . ";\n";
|
1395 |
|
|
}
|
1396 |
|
|
|
1397 |
|
|
if (isset($settings['case']) && $settings['case'] !== '') {
|
1398 |
|
|
$css .= ' text-transform: ' . $settings['case'] . ";\n";
|
1399 |
|
|
}
|
1400 |
|
|
|
1401 |
|
|
if (isset($settings['decoration']) && $settings['decoration'] !== '') {
|
1402 |
|
|
$css .= ' text-decoration: ' . $settings['decoration'] . ";\n";
|
1403 |
|
|
}
|
1404 |
|
|
|
1405 |
|
|
if (isset($settings['alignment']) && $settings['alignment'] !== '') {
|
1406 |
|
|
$css .= ' text-align: ' . $settings['alignment'] . ";\n";
|
1407 |
|
|
}
|
1408 |
|
|
|
1409 |
|
|
if (isset($settings['letter_spacing']) && $settings['letter_spacing'] !== '') {
|
1410 |
|
|
$css .= ' letter-spacing: ' . $settings['letter_spacing'] . ";\n";
|
1411 |
|
|
}
|
1412 |
|
|
|
1413 |
|
|
if (isset($settings['word_spacing']) && $settings['word_spacing'] !== '') {
|
1414 |
|
|
$css .= ' word-spacing: ' . $settings['word_spacing'] . ";\n";
|
1415 |
|
|
}
|
1416 |
|
|
|
1417 |
|
|
if ($css) {
|
1418 |
|
|
$stylesheet .= $selector . " {\n" . $css . "}\n";
|
1419 |
|
|
}
|
1420 |
|
|
}
|
1421 |
|
|
|
1422 |
|
|
/**
|
1423 |
|
|
* Border selector form
|
1424 |
|
|
*/
|
1425 |
|
|
function ctools_stylizer_border_selector_form(&$form, &$form_state, $label, $settings) {
|
1426 |
|
|
// Family
|
1427 |
|
|
$form['#prefix'] = '<div class="ctools-stylizer-spacing-form clearfix">';
|
1428 |
|
|
$form['#type'] = 'fieldset';
|
1429 |
|
|
$form['#title'] = $label;
|
1430 |
|
|
$form['#suffix'] = '</div>';
|
1431 |
|
|
$form['#tree'] = TRUE;
|
1432 |
|
|
|
1433 |
|
|
$form['thickness'] = array(
|
1434 |
|
|
'#title' => t('Thickness'),
|
1435 |
|
|
'#type' => 'select',
|
1436 |
|
|
'#default_value' => isset($settings['thickness']) ? $settings['thickness'] : '',
|
1437 |
|
|
'#options' => array(
|
1438 |
|
|
'' => '',
|
1439 |
|
|
"none" => t('None'),
|
1440 |
|
|
"1px" => '1px',
|
1441 |
|
|
"2px" => '2px',
|
1442 |
|
|
"3px" => '3px',
|
1443 |
|
|
"4px" => '4px',
|
1444 |
|
|
"5px" => '5px',
|
1445 |
|
|
),
|
1446 |
|
|
);
|
1447 |
|
|
|
1448 |
|
|
$form['style'] = array(
|
1449 |
|
|
'#title' => t('style'),
|
1450 |
|
|
'#type' => 'select',
|
1451 |
|
|
'#default_value' => isset($settings['style']) ? $settings['style'] : '',
|
1452 |
|
|
'#options' => array(
|
1453 |
|
|
'' => '',
|
1454 |
|
|
'solid' => t('Solid'),
|
1455 |
|
|
'dotted' => t('Dotted'),
|
1456 |
|
|
'dashed' => t('Dashed'),
|
1457 |
|
|
'double' => t('Double'),
|
1458 |
|
|
'groove' => t('Groove'),
|
1459 |
|
|
'ridge' => t('Ridge'),
|
1460 |
|
|
'inset' => t('Inset'),
|
1461 |
|
|
'outset' => t('Outset'),
|
1462 |
|
|
),
|
1463 |
|
|
);
|
1464 |
|
|
}
|
1465 |
|
|
|
1466 |
|
|
/**
|
1467 |
|
|
* Copy border selector information into the settings
|
1468 |
|
|
*/
|
1469 |
|
|
function ctools_stylizer_border_selector_form_submit(&$form, &$form_state, &$values, &$settings) {
|
1470 |
|
|
$settings = $values;
|
1471 |
|
|
}
|
1472 |
|
|
|
1473 |
|
|
function ctools_stylizer_border_apply_style(&$stylesheet, $selector, $settings, $color, $which = NULL) {
|
1474 |
|
|
$border = 'border';
|
1475 |
|
|
if ($which) {
|
1476 |
|
|
$border .= '-' . $which;
|
1477 |
|
|
}
|
1478 |
|
|
|
1479 |
|
|
$css = '';
|
1480 |
|
|
if (isset($settings['thickness']) && $settings['thickness'] !== '') {
|
1481 |
|
|
if ($settings['thickness'] == 'none') {
|
1482 |
|
|
$css .= ' ' . $border . ': none';
|
1483 |
|
|
}
|
1484 |
|
|
else {
|
1485 |
|
|
$css .= ' ' . $border . '-width: ' . $settings['thickness'] . ";\n";
|
1486 |
|
|
|
1487 |
|
|
if (isset($settings['style']) && $settings['style'] !== '') {
|
1488 |
|
|
$css .= ' ' . $border . '-style: ' . $settings['style'] . ";\n";
|
1489 |
|
|
}
|
1490 |
|
|
|
1491 |
|
|
$css .= ' ' . $border . '-color: ' . $color . ";\n";
|
1492 |
|
|
}
|
1493 |
|
|
}
|
1494 |
|
|
|
1495 |
|
|
if ($css) {
|
1496 |
|
|
$stylesheet .= $selector . " {\n" . $css . "}\n";
|
1497 |
|
|
}
|
1498 |
|
|
|
1499 |
|
|
}
|
1500 |
|
|
|
1501 |
|
|
/**
|
1502 |
|
|
* padding selector form
|
1503 |
|
|
*/
|
1504 |
|
|
function ctools_stylizer_padding_selector_form(&$form, &$form_state, $label, $settings) {
|
1505 |
|
|
// Family
|
1506 |
|
|
$form['#prefix'] = '<div class="ctools-stylizer-spacing-form clearfix">';
|
1507 |
|
|
$form['#type'] = 'fieldset';
|
1508 |
|
|
$form['#title'] = $label;
|
1509 |
|
|
$form['#suffix'] = '</div>';
|
1510 |
|
|
$form['#tree'] = TRUE;
|
1511 |
|
|
|
1512 |
|
|
$options = array(
|
1513 |
|
|
'' => '',
|
1514 |
|
|
"0.05em" => '0.05em',
|
1515 |
|
|
"0.1em" => '0.1em',
|
1516 |
|
|
"0.15em" => '0.15em',
|
1517 |
|
|
"0.2em" => '0.2em',
|
1518 |
|
|
"0.25em" => '0.25em',
|
1519 |
|
|
"0.3em" => '0.3em',
|
1520 |
|
|
"0.35em" => '0.35em',
|
1521 |
|
|
"0.4em" => '0.4em',
|
1522 |
|
|
"0.45em" => '0.45em',
|
1523 |
|
|
"0.5em" => '0.5em',
|
1524 |
|
|
"0.55em" => '0.55em',
|
1525 |
|
|
"0.6em" => '0.6em',
|
1526 |
|
|
"0.65em" => '0.65em',
|
1527 |
|
|
"0.7em" => '0.7em',
|
1528 |
|
|
"0.75em" => '0.75em',
|
1529 |
|
|
"0.8em" => '0.8em',
|
1530 |
|
|
"0.85em" => '0.85em',
|
1531 |
|
|
"0.9em" => '0.9em',
|
1532 |
|
|
"0.95em" => '0.95em',
|
1533 |
|
|
"1.0em" => '1.0em',
|
1534 |
|
|
"1.05em" => '1.05em',
|
1535 |
|
|
"1.1em" => '1.1em',
|
1536 |
|
|
"1.15em" => '1.15em',
|
1537 |
|
|
"1.2em" => '1.2em',
|
1538 |
|
|
"1.25em" => '1.25em',
|
1539 |
|
|
"1.3em" => '1.3em',
|
1540 |
|
|
"1.35em" => '1.35em',
|
1541 |
|
|
"1.4em" => '1.4em',
|
1542 |
|
|
"1.45em" => '1.45em',
|
1543 |
|
|
"1.5em" => '1.5em',
|
1544 |
|
|
"1.55em" => '1.55em',
|
1545 |
|
|
"1.6em" => '1.6em',
|
1546 |
|
|
"1.65em" => '1.65em',
|
1547 |
|
|
"1.7em" => '1.7em',
|
1548 |
|
|
"1.75em" => '1.75em',
|
1549 |
|
|
"1.8em" => '1.8em',
|
1550 |
|
|
"1.85em" => '1.85em',
|
1551 |
|
|
"1.9em" => '1.9em',
|
1552 |
|
|
"1.95em" => '1.95em',
|
1553 |
|
|
"2.0em" => '2.0em',
|
1554 |
|
|
"2.05em" => '2.05em',
|
1555 |
|
|
"2.1em" => '2.1em',
|
1556 |
|
|
"2.15em" => '2.15em',
|
1557 |
|
|
"2.2em" => '2.2em',
|
1558 |
|
|
"2.25em" => '2.25em',
|
1559 |
|
|
"2.3em" => '2.3em',
|
1560 |
|
|
"2.35em" => '2.35em',
|
1561 |
|
|
"2.4em" => '2.4em',
|
1562 |
|
|
"2.45em" => '2.45em',
|
1563 |
|
|
"2.5em" => '2.5em',
|
1564 |
|
|
"2.55em" => '2.55em',
|
1565 |
|
|
"2.6em" => '2.6em',
|
1566 |
|
|
"2.65em" => '2.65em',
|
1567 |
|
|
"2.7em" => '2.7em',
|
1568 |
|
|
"2.75em" => '2.75em',
|
1569 |
|
|
"2.8em" => '2.8em',
|
1570 |
|
|
"2.85em" => '2.85em',
|
1571 |
|
|
"2.9em" => '2.9em',
|
1572 |
|
|
"2.95em" => '2.95em',
|
1573 |
|
|
"3.0em" => '3.0em',
|
1574 |
|
|
"3.05em" => '3.05em',
|
1575 |
|
|
"3.1em" => '3.1em',
|
1576 |
|
|
"3.15em" => '3.15em',
|
1577 |
|
|
"3.2em" => '3.2em',
|
1578 |
|
|
"3.25em" => '3.25em',
|
1579 |
|
|
"3.3em" => '3.3em',
|
1580 |
|
|
"3.35em" => '3.35em',
|
1581 |
|
|
"3.4em" => '3.4em',
|
1582 |
|
|
"3.45em" => '3.45em',
|
1583 |
|
|
"3.5em" => '3.5em',
|
1584 |
|
|
"3.55em" => '3.55em',
|
1585 |
|
|
"3.6em" => '3.6em',
|
1586 |
|
|
"3.65em" => '3.65em',
|
1587 |
|
|
"3.7em" => '3.7em',
|
1588 |
|
|
"3.75em" => '3.75em',
|
1589 |
|
|
"3.8em" => '3.8em',
|
1590 |
|
|
"3.85em" => '3.85em',
|
1591 |
|
|
"3.9em" => '3.9em',
|
1592 |
|
|
"3.95em" => '3.95em',
|
1593 |
|
|
);
|
1594 |
|
|
|
1595 |
|
|
$form['top'] = array(
|
1596 |
|
|
'#title' => t('Top'),
|
1597 |
|
|
'#type' => 'select',
|
1598 |
|
|
'#default_value' => isset($settings['top']) ? $settings['top'] : '',
|
1599 |
|
|
'#options' => $options,
|
1600 |
|
|
);
|
1601 |
|
|
|
1602 |
|
|
$form['right'] = array(
|
1603 |
|
|
'#title' => t('Right'),
|
1604 |
|
|
'#type' => 'select',
|
1605 |
|
|
'#default_value' => isset($settings['right']) ? $settings['right'] : '',
|
1606 |
|
|
'#options' => $options,
|
1607 |
|
|
);
|
1608 |
|
|
|
1609 |
|
|
$form['bottom'] = array(
|
1610 |
|
|
'#title' => t('Bottom'),
|
1611 |
|
|
'#type' => 'select',
|
1612 |
|
|
'#default_value' => isset($settings['bottom']) ? $settings['bottom'] : '',
|
1613 |
|
|
'#options' => $options,
|
1614 |
|
|
);
|
1615 |
|
|
|
1616 |
|
|
$form['left'] = array(
|
1617 |
|
|
'#title' => t('Left'),
|
1618 |
|
|
'#type' => 'select',
|
1619 |
|
|
'#default_value' => isset($settings['left']) ? $settings['left'] : '',
|
1620 |
|
|
'#options' => $options,
|
1621 |
|
|
);
|
1622 |
|
|
}
|
1623 |
|
|
|
1624 |
|
|
/**
|
1625 |
|
|
* Copy padding selector information into the settings
|
1626 |
|
|
*/
|
1627 |
|
|
function ctools_stylizer_padding_selector_form_submit(&$form, &$form_state, &$values, &$settings) {
|
1628 |
|
|
$settings = $values;
|
1629 |
|
|
}
|
1630 |
|
|
|
1631 |
|
|
function ctools_stylizer_padding_apply_style(&$stylesheet, $selector, $settings) {
|
1632 |
|
|
$css = '';
|
1633 |
|
|
|
1634 |
|
|
if (isset($settings['top']) && $settings['top'] !== '') {
|
1635 |
|
|
$css .= ' padding-top: ' . $settings['top'] . ";\n";
|
1636 |
|
|
}
|
1637 |
|
|
|
1638 |
|
|
if (isset($settings['right']) && $settings['right'] !== '') {
|
1639 |
|
|
$css .= ' padding-right: ' . $settings['right'] . ";\n";
|
1640 |
|
|
}
|
1641 |
|
|
|
1642 |
|
|
if (isset($settings['bottom']) && $settings['bottom'] !== '') {
|
1643 |
|
|
$css .= ' padding-bottom: ' . $settings['bottom'] . ";\n";
|
1644 |
|
|
}
|
1645 |
|
|
|
1646 |
|
|
if (isset($settings['left']) && $settings['left'] !== '') {
|
1647 |
|
|
$css .= ' padding-left: ' . $settings['left'] . ";\n";
|
1648 |
|
|
}
|
1649 |
|
|
|
1650 |
|
|
if ($css) {
|
1651 |
|
|
$stylesheet .= $selector . " {\n" . $css . "}\n";
|
1652 |
|
|
}
|
1653 |
|
|
|
1654 |
|
|
} |