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