diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 9b6a01a0f0db..fc37b38bdffb 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -12,6 +12,8 @@ Drupal 5.0, xxxx-xx-xx (development version) * install pre-made 'install profiles' or distributions * import the database structure with automatic table prefixing * be localized +- added new default Garland theme +- added color module to change some themes' color schemes - included the jQuery JavaScript library 1.0.2 and converted all core JavaScript to use it - introduced the ability to alter mail sent from system - module system: diff --git a/misc/farbtastic/farbtastic.css b/misc/farbtastic/farbtastic.css new file mode 100644 index 000000000000..07d953f2d7ce --- /dev/null +++ b/misc/farbtastic/farbtastic.css @@ -0,0 +1,33 @@ +.farbtastic { + position: relative; +} +.farbtastic * { + position: absolute; + cursor: crosshair; +} +.farbtastic, .farbtastic .wheel { + width: 195px; + height: 195px; +} +.farbtastic .color, .farbtastic .overlay { + top: 47px; + left: 47px; + width: 101px; + height: 101px; +} +.farbtastic .wheel { + background: url(wheel.png) no-repeat; + width: 195px; + height: 195px; +} +.farbtastic .overlay { + background: url(mask.png) no-repeat; +} +.farbtastic .marker { + width: 17px; + height: 17px; + margin: -8px 0 0 -8px; + overflow: hidden; + background: url(marker.png) no-repeat; +} + diff --git a/misc/farbtastic/farbtastic.js b/misc/farbtastic/farbtastic.js new file mode 100644 index 000000000000..361179b756bf --- /dev/null +++ b/misc/farbtastic/farbtastic.js @@ -0,0 +1,326 @@ +// $Id$ +// Farbtastic 1.1 + +jQuery.fn.farbtastic = function (callback) { + $.farbtastic(this, callback); + return this; +}; + +jQuery.farbtastic = function (container, callback) { + var container = $(container).get(0); + return container.farbtastic || (container.farbtastic = new jQuery._farbtastic(container, callback)); +} + +jQuery._farbtastic = function (container, callback) { + // Store farbtastic object + var fb = this; + + // Insert markup + $(container).html('
'); + var e = $('.farbtastic', container); + fb.wheel = $('.wheel', container).get(0); + // Dimensions + fb.radius = 84; + fb.square = 100; + fb.width = 194; + + // Fix background PNGs in IE6 + if (navigator.appVersion.match(/MSIE [0-6]\./)) { + $('*', e).each(function () { + if (this.currentStyle.backgroundImage != 'none') { + var image = this.currentStyle.backgroundImage; + image = this.currentStyle.backgroundImage.substring(5, image.length - 2); + $(this).css({ + 'backgroundImage': 'none', + 'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')" + }); + } + }); + } + + /** + * Link to the given element(s) or callback. + */ + fb.linkTo = function (callback) { + // Unbind previous nodes + if (typeof fb.callback == 'object') { + $(fb.callback).unbind('keyup', fb.updateValue); + } + + // Bind callback or elements + if (typeof callback == 'function') { + fb.callback = callback; + } + else if (typeof callback == 'object' || typeof callback == 'string') { + fb.callback = $(callback); + fb.callback.bind('keyup', fb.updateValue); + if (fb.callback.get(0).value) { + fb.setColor(fb.callback.get(0).value); + } + } + return this; + } + fb.updateValue = function (event) { + if (this.value && this.value != fb.color) { + fb.setColor(this.value); + } + } + + /** + * Change color with HTML syntax #123456 + */ + fb.setColor = function (color) { + var unpack = fb.unpack(color); + if (fb.color != color && unpack) { + fb.color = color; + fb.rgb = unpack; + fb.hsl = fb.RGBToHSL(fb.rgb); + fb.updateDisplay(); + } + return this; + } + + /** + * Change color with HSL triplet [0..1, 0..1, 0..1] + */ + fb.setHSL = function (hsl) { + fb.hsl = hsl; + fb.rgb = fb.HSLToRGB(hsl); + fb.color = fb.pack(fb.rgb); + fb.updateDisplay(); + return this; + } + + ///////////////////////////////////////////////////// + + /** + * Retrieve the coordinates of the given event relative to the center + * of the widget. + */ + fb.widgetCoords = function (event) { + var x, y; + var el = event.target || event.srcElement; + var reference = fb.wheel; + + if (typeof event.offsetX != 'undefined') { + // Use offset coordinates and find common offsetParent + var pos = { x: event.offsetX, y: event.offsetY }; + + // Send the coordinates upwards through the offsetParent chain. + var e = el; + while (e) { + e.mouseX = pos.x; + e.mouseY = pos.y; + pos.x += e.offsetLeft; + pos.y += e.offsetTop; + e = e.offsetParent; + } + + // Look for the coordinates starting from the wheel widget. + var e = reference; + var offset = { x: 0, y: 0 } + while (e) { + if (typeof e.mouseX != 'undefined') { + x = e.mouseX - offset.x; + y = e.mouseY - offset.y; + break; + } + offset.x += e.offsetLeft; + offset.y += e.offsetTop; + e = e.offsetParent; + } + + // Reset stored coordinates + e = el; + while (e) { + e.mouseX = undefined; + e.mouseY = undefined; + e = e.offsetParent; + } + } + else { + // Use absolute coordinates + var pos = fb.absolutePosition(reference); + x = (event.pageX || 0*(event.clientX + $('html').get(0).scrollLeft)) - pos.x; + y = (event.pageY || 0*(event.clientY + $('html').get(0).scrollTop)) - pos.y; + } + // Subtract distance to middle + return { x: x - fb.width / 2, y: y - fb.width / 2 }; + } + + /** + * Mousedown handler + */ + fb.mousedown = function (event) { + // Capture mouse + if (!document.dragging) { + $(document).bind('mousemove', fb.mousemove).bind('mouseup', fb.mouseup); + document.dragging = true; + } + + // Check which area is being dragged + var pos = fb.widgetCoords(event); + fb.circleDrag = Math.max(Math.abs(pos.x), Math.abs(pos.y)) * 2 > fb.square; + + // Process + fb.mousemove(event); + return false; + } + + /** + * Mousemove handler + */ + fb.mousemove = function (event) { + // Get coordinates relative to color picker center + var pos = fb.widgetCoords(event); + + // Set new HSL parameters + if (fb.circleDrag) { + var hue = Math.atan2(pos.x, -pos.y) / 6.28; + if (hue < 0) hue += 1; + fb.setHSL([hue, fb.hsl[1], fb.hsl[2]]); + } + else { + var sat = Math.max(0, Math.min(1, -(pos.x / fb.square) + .5)); + var lum = Math.max(0, Math.min(1, -(pos.y / fb.square) + .5)); + fb.setHSL([fb.hsl[0], sat, lum]); + } + return false; + } + + /** + * Mouseup handler + */ + fb.mouseup = function () { + // Uncapture mouse + $(document).unbind('mousemove', fb.mousemove); + $(document).unbind('mouseup', fb.mouseup); + document.dragging = false; + } + + /** + * Update the markers and styles + */ + fb.updateDisplay = function () { + // Markers + var angle = fb.hsl[0] * 6.28; + $('.h-marker', e).css({ + left: Math.round(Math.sin(angle) * fb.radius + fb.width / 2) + 'px', + top: Math.round(-Math.cos(angle) * fb.radius + fb.width / 2) + 'px' + }); + + $('.sl-marker', e).css({ + left: Math.round(fb.square * (.5 - fb.hsl[1]) + fb.width / 2) + 'px', + top: Math.round(fb.square * (.5 - fb.hsl[2]) + fb.width / 2) + 'px' + }); + + // Saturation/Luminance gradient + $('.color', e).css('backgroundColor', fb.pack(fb.HSLToRGB([fb.hsl[0], 1, 0.5]))); + + // Linked elements or callback + if (typeof fb.callback == 'object') { + // Set background/foreground color + $(fb.callback).css({ + backgroundColor: fb.color, + color: fb.hsl[2] > 0.5 ? '#000' : '#fff' + }); + + // Change linked value + $(fb.callback).each(function() { + if (this.value && this.value != fb.color) { + this.value = fb.color; + } + }); + } + else if (typeof fb.callback == 'function') { + fb.callback.call(fb, fb.color); + } + } + + /** + * Get absolute position of element + */ + fb.absolutePosition = function (el) { + var r = { x: el.offsetLeft, y: el.offsetTop }; + // Resolve relative to offsetParent + if (el.offsetParent) { + var tmp = fb.absolutePosition(el.offsetParent); + r.x += tmp.x; + r.y += tmp.y; + } + return r; + }; + + /* Various color utility functions */ + fb.pack = function (rgb) { + var r = Math.round(rgb[0] * 255); + var g = Math.round(rgb[1] * 255); + var b = Math.round(rgb[2] * 255); + return '#' + (r < 16 ? '0' : '') + r.toString(16) + + (g < 16 ? '0' : '') + g.toString(16) + + (b < 16 ? '0' : '') + b.toString(16); + } + + fb.unpack = function (color) { + if (color.length == 7) { + return [parseInt('0x' + color.substring(1, 3)) / 255, + parseInt('0x' + color.substring(3, 5)) / 255, + parseInt('0x' + color.substring(5, 7)) / 255]; + } + else if (color.length == 4) { + return [parseInt('0x' + color.substring(1, 2)) / 15, + parseInt('0x' + color.substring(2, 3)) / 15, + parseInt('0x' + color.substring(3, 4)) / 15]; + } + } + + fb.HSLToRGB = function (hsl) { + var m1, m2, r, g, b; + var h = hsl[0], s = hsl[1], l = hsl[2]; + m2 = (l <= 0.5) ? l * (s + 1) : l + s - l*s; + m1 = l * 2 - m2; + return [this.hueToRGB(m1, m2, h+0.33333), + this.hueToRGB(m1, m2, h), + this.hueToRGB(m1, m2, h-0.33333)]; + } + + fb.hueToRGB = function (m1, m2, h) { + h = (h < 0) ? h + 1 : ((h > 1) ? h - 1 : h); + if (h * 6 < 1) return m1 + (m2 - m1) * h * 6; + if (h * 2 < 1) return m2; + if (h * 3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * 6; + return m1; + } + + fb.RGBToHSL = function (rgb) { + var min, max, delta, h, s, l; + var r = rgb[0], g = rgb[1], b = rgb[2]; + min = Math.min(r, Math.min(g, b)); + max = Math.max(r, Math.max(g, b)); + delta = max - min; + l = (min + max) / 2; + s = 0; + if (l > 0 && l < 1) { + s = delta / (l < 0.5 ? (2 * l) : (2 - 2 * l)); + } + h = 0; + if (delta > 0) { + if (max == r && max != g) h += (g - b) / delta; + if (max == g && max != b) h += (2 + (b - r) / delta); + if (max == b && max != r) h += (4 + (r - g) / delta); + h /= 6; + } + return [h, s, l]; + } + + // Install mousedown handler (the others are set on the document on-demand) + $('*', e).mousedown(fb.mousedown); + + // Init color + fb.setColor('#000000'); + + // Set linked elements/callback + if (callback) { + fb.linkTo(callback); + } +} \ No newline at end of file diff --git a/misc/farbtastic/marker.png b/misc/farbtastic/marker.png new file mode 100644 index 000000000000..3929bbb51dd9 Binary files /dev/null and b/misc/farbtastic/marker.png differ diff --git a/misc/farbtastic/mask.png b/misc/farbtastic/mask.png new file mode 100644 index 000000000000..b0a4d406fb64 Binary files /dev/null and b/misc/farbtastic/mask.png differ diff --git a/misc/farbtastic/wheel.png b/misc/farbtastic/wheel.png new file mode 100644 index 000000000000..97b343d98c74 Binary files /dev/null and b/misc/farbtastic/wheel.png differ diff --git a/misc/favicon.ico b/misc/favicon.ico index 18e2d52f94af..0ed7df519eab 100644 Binary files a/misc/favicon.ico and b/misc/favicon.ico differ diff --git a/modules/color/color.css b/modules/color/color.css new file mode 100644 index 000000000000..0b532e966247 --- /dev/null +++ b/modules/color/color.css @@ -0,0 +1,77 @@ +/* Farbtastic placement */ +.color-form { + max-width: 50em; + position: relative; +} +#placeholder { + position: absolute; + top: 0; + right: 0; +} + +/* Palette */ +.color-form .form-item { + height: 2em; + line-height: 2em; + padding-left: 1em; + margin: 0.5em 0; +} +.color-form label { + float: left; + clear: left; + width: 10em; +} +.color-form .form-text, .color-form .form-select { + float: left; +} +.color-form .form-text { + text-align: center; + margin-right: 5px; + cursor: pointer; +} + +#palette .hook { + float: left; + margin-top: 3px; + width: 16px; + height: 16px; +} +#palette .down, #palette .up, #palette .both { + background: url('images/hook.png') no-repeat 100% 0; +} +#palette .up { + background-position: 100% -27px; +} +#palette .both { + background-position: 100% -54px; +} + +#palette .lock { + float: left; + position: relative; + top: -1.4em; + left: -10px; + width: 20px; + height: 25px; + background: url('images/lock.png') no-repeat 50% 2px; + cursor: pointer; +} +#palette .unlocked { + background-position: 50% -22px; +} +#palette .form-item { + width: 20em; +} +#palette .item-selected { + background: #eee; +} + +/* Preview */ +#preview { + display: none; +} +html.js #preview { + display: block; + position: relative; + float: left; +} diff --git a/modules/color/color.info b/modules/color/color.info new file mode 100644 index 000000000000..642eae03836f --- /dev/null +++ b/modules/color/color.info @@ -0,0 +1,4 @@ +; $Id$ +name = Color +description = Allows the user to change the color scheme of certain themes. +package = Core - optional diff --git a/modules/color/color.js b/modules/color/color.js new file mode 100644 index 000000000000..5bf26a988795 --- /dev/null +++ b/modules/color/color.js @@ -0,0 +1,245 @@ +if (Drupal.jsEnabled) { + $(document).ready(function () { + var form = $('#color_scheme_form .color-form'); + var inputs = []; + var hooks = []; + var locks = []; + var focused = null; + + // Add Farbtastic + $(form).prepend('
'); + var farb = $.farbtastic('#placeholder'); + + // Decode reference colors to HSL + var reference = Drupal.settings.color.reference; + for (i in reference) { + reference[i] = farb.RGBToHSL(farb.unpack(reference[i])); + } + + // Build preview + $('#preview').append('
'); + var gradient = $('#preview #gradient'); + var h = parseInt(gradient.css('height')) / 10; + for (i = 0; i < h; ++i) { + gradient.append('
'); + } + + // Fix preview background in IE6 + if (navigator.appVersion.match(/MSIE [0-6]\./)) { + var e = $('#preview #img')[0]; + var image = e.currentStyle.backgroundImage; + e.style.backgroundImage = 'none'; + e.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image.substring(5, image.length - 2) + "')"; + } + + // Set up colorscheme selector + $('#edit-scheme', form).change(function () { + var colors = this.options[this.selectedIndex].value; + if (colors != '') { + colors = colors.split(','); + for (i in colors) { + callback(inputs[i], colors[i], false, true); + } + preview(); + } + }); + + /** + * Render the preview. + */ + function preview() { + // Solid background + $('#preview', form).css('backgroundColor', inputs[0].value); + + // Text preview + $('#text', form).css('color', inputs[4].value); + $('#text a, #text h2', form).css('color', inputs[1].value); + + // Set up gradient + var top = farb.unpack(inputs[2].value); + var bottom = farb.unpack(inputs[3].value); + if (top && bottom) { + var delta = []; + for (i in top) { + delta[i] = (bottom[i] - top[i]) / h; + } + var accum = top; + + // Render gradient lines + $('#gradient > div', form).each(function () { + for (i in accum) { + accum[i] += delta[i]; + } + this.style.backgroundColor = farb.pack(accum); + }); + } + } + + /** + * Shift a given color, using a reference pair (ref in HSL). + * + * This algorithm ensures relative ordering on the saturation and luminance + * axes is preserved, and performs a simple hue shift. + * + * It is also symmetrical. If: shift_color(c, a, b) == d, + * then shift_color(d, b, a) == c. + */ + function shift_color(given, ref1, ref2) { + // Convert to HSL + given = farb.RGBToHSL(farb.unpack(given)); + + // Hue: apply delta + given[0] += ref2[0] - ref1[0]; + + // Saturation: interpolate + if (ref1[1] == 0 || ref2[1] == 0) { + given[1] = ref2[1]; + } + else { + var d = ref1[1] / ref2[1]; + if (d > 1) { + given[1] /= d; + } + else { + given[1] = 1 - (1 - given[1]) * d; + } + } + + // Luminance: interpolate + if (ref1[2] == 0 || ref2[2] == 0) { + given[2] = ref2[2]; + } + else { + var d = ref1[2] / ref2[2]; + if (d > 1) { + given[2] /= d; + } + else { + given[2] = 1 - (1 - given[2]) * d; + } + } + + return farb.pack(farb.HSLToRGB(given)); + } + + /** + * Callback for Farbtastic when a new color is chosen. + */ + function callback(input, color, propagate, colorscheme) { + // Set background/foreground color + $(input).css({ + backgroundColor: color, + color: farb.RGBToHSL(farb.unpack(color))[2] > 0.5 ? '#000' : '#fff' + }); + + // Change input value + if (input.value && input.value != color) { + input.value = color; + + // Update locked values + if (propagate) { + var i = input.i; + for (j = i + 1; ; ++j) { + if (!locks[j - 1] || $(locks[j - 1]).is('.unlocked')) break; + var matched = shift_color(color, reference[input.key], reference[inputs[j].key]); + callback(inputs[j], matched, false); + } + for (j = i - 1; ; --j) { + if (!locks[j] || $(locks[j]).is('.unlocked')) break; + var matched = shift_color(color, reference[input.key], reference[inputs[j].key]); + callback(inputs[j], matched, false); + } + + // Update preview + preview(); + } + + // Reset colorscheme selector + if (!colorscheme) { + resetScheme(); + } + } + + } + + /** + * Reset the color scheme selector. + */ + function resetScheme() { + $('#edit-scheme', form).each(function () { + this.selectedIndex = this.options.length - 1; + }); + } + + // Focus the Farbtastic on a particular field. + function focus() { + var input = this; + // Remove old bindings + focused && $(focused).unbind('keyup', farb.updateValue) + .unbind('keyup', preview).unbind('keyup', resetScheme) + .parent().removeClass('item-selected'); + + // Add new bindings + focused = this; + farb.linkTo(function (color) { callback(input, color, true, false) }); + farb.setColor(this.value); + $(focused).keyup(farb.updateValue).keyup(preview).keyup(resetScheme) + .parent().addClass('item-selected'); + } + + // Initialize color fields + $('#palette input.form-text', form) + .each(function () { + // Extract palette field name + this.key = this.id.substring(13); + + // Link to color picker temporarily to initialize. + farb.linkTo(function () {}).setColor('#000').linkTo(this); + + // Add lock + var i = inputs.length; + if (inputs.length) { + var lock = $('
').toggle( + function () { + $(this).addClass('unlocked'); + $(hooks[i - 1]).attr('class', + locks[i - 2] && $(locks[i - 2]).is(':not(.unlocked)') ? 'hook up' : 'hook' + ); + $(hooks[i]).attr('class', + locks[i] && $(locks[i]).is(':not(.unlocked)') ? 'hook down' : 'hook' + ); + }, + function () { + $(this).removeClass('unlocked'); + $(hooks[i - 1]).attr('class', + locks[i - 2] && $(locks[i - 2]).is(':not(.unlocked)') ? 'hook both' : 'hook down' + ); + $(hooks[i]).attr('class', + locks[i] && $(locks[i]).is(':not(.unlocked)') ? 'hook both' : 'hook up' + ); + } + ); + $(this).after(lock); + locks.push(lock); + } + + // Add hook + var hook = $('
'); + $(this).after(hook); + hooks.push(hook); + + $(this).parent().find('.lock').click(); + this.i = i; + inputs.push(this); + }) + .focus(focus); + + $('#palette label', form) + + // Focus first color + focus.call(inputs[0]); + + // Render preview + preview(); + }); +} \ No newline at end of file diff --git a/modules/color/color.module b/modules/color/color.module new file mode 100644 index 000000000000..98b6e337d52c --- /dev/null +++ b/modules/color/color.module @@ -0,0 +1,542 @@ + 'fieldset', + '#title' => t('Color scheme'), + '#weight' => -1, + '#attributes' => array('id' => 'color_scheme_form'), + '#theme' => 'color_scheme_form', + ); + $form['color'] += color_scheme_form(arg(4)); + $form['#submit']['color_scheme_form_submit'] = array(); + } + + // Use the generated screenshot in the theme list + if ($form_id == 'system_theme_select_form' || $form_id == 'system_themes') { + $themes = list_themes(); + foreach (element_children($form) as $theme) { + if ($screenshot = variable_get('color_'. $theme .'_screenshot', NULL)) { + if (isset($form[$theme]['screenshot'])) { + $form[$theme]['screenshot']['#value'] = theme('image', $screenshot, '', '', array('class' => 'screenshot'), FALSE); + } + } + } + } +} + +/** + * Callback for the theme to alter the resources used. + */ +function _color_page_alter(&$vars) { + global $theme_key; + + // Override stylesheet + $path = variable_get('color_'. $theme_key .'_stylesheet', NULL); + if ($path) { + $vars['css']['theme'] = array($path => array('path' => $path, 'media' => 'all')); + $vars['styles'] = drupal_get_css($vars['css']); + } + + // Override logo + $logo = variable_get('color_'. $theme_key .'_logo', NULL); + if ($logo && $vars['logo'] && preg_match('!'. $theme_key .'/logo.png$!', $vars['logo'])) { + $vars['logo'] = $logo; + } + + return $vars; +} + +/** + * Retrieve the color.module info for a particular theme. + */ +function color_get_info($theme) { + $path = drupal_get_path('theme', $theme); + $file = $path .'/color/color.inc'; + if ($path && file_exists($file)) { + include $file; + return $info; + } +} + +/** + * Helper function to retrieve the color palette for a particular theme. + */ +function color_get_palette($theme, $default = false) { + // Fetch and expand default palette + $fields = array('base', 'link', 'top', 'bottom', 'text'); + $info = color_get_info($theme); + foreach (explode(',', array_shift(array_keys($info['schemes']))) as $k => $scheme) { + $palette[$fields[$k]] = $scheme; + } + + // Load variable + return $default ? $palette : variable_get('color_'. $theme .'_palette', $palette); +} + +/** + * Form callback. Returns the configuration form. + */ +function color_scheme_form($theme) { + $base = drupal_get_path('module', 'color'); + $info = color_get_info($theme); + + // Add Farbtastic color picker + drupal_add_css('misc/farbtastic/farbtastic.css'); + drupal_add_js('misc/farbtastic/farbtastic.js'); + + // Add custom CSS/JS + drupal_add_css($base .'/color.css', 'module'); + drupal_add_js($base .'/color.js'); + drupal_add_js(array('color' => array( + 'reference' => color_get_palette($theme, true) + )), 'setting'); + + // See if we're using a predefined scheme + $current = implode(',', variable_get('color_'. $theme .'_palette', array())); + // Note: we use the original theme when the default scheme is chosen. + $current = isset($info['schemes'][$current]) ? $current : ($current == '' ? reset($info['schemes']) : ''); + + // Add scheme selector + $info['schemes'][''] = t('Custom'); + $form['scheme'] = array( + '#type' => 'select', + '#title' => t('Color set'), + '#options' => $info['schemes'], + '#default_value' => $current, + ); + + // Add palette fields + $palette = color_get_palette($theme); + $names = array( + 'base' => t('Base color'), + 'link' => t('Link color'), + 'top' => t('Header top'), + 'bottom' => t('Header bottom'), + 'text' => t('Text color') + ); + $form['palette']['#tree'] = true; + foreach ($palette as $name => $value) { + $form['palette'][$name] = array( + '#type' => 'textfield', + '#title' => $names[$name], + '#default_value' => $value, + '#size' => 8, + ); + } + $form['theme'] = array('#type' => 'value', '#value' => arg(4)); + $form['info'] = array('#type' => 'value', '#value' => $info); + + return $form; +} + +/** + * Theme color form. + */ +function theme_color_scheme_form($form) { + // Include stylesheet + $theme = $form['theme']['#value']; + $info = $form['info']['#value']; + $path = drupal_get_path('theme', $theme) .'/'; + drupal_add_css($path . $info['preview_css']); + + // Wrapper + $output .= '
'; + + // Color Schemes + $output .= drupal_render($form['scheme']); + + // Palette + $output .= '
'; + foreach (element_children($form['palette']) as $name) { + $output .= drupal_render($form['palette'][$name]); + } + $output .= '
'; + + // Preview + $output .= drupal_render($form); + $output .= '

'. t('Preview') .'

'; + $output .= '

Lorem ipsum dolor

Sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

'; + + $output .= '
'; + + return $output; +} + +/** + * Submit handler for color change form. + */ +function color_scheme_form_submit($form_id, $values) { + // Get theme coloring info + if (!isset($values['info'])) { + return; + } + $theme = $values['theme']; + $info = $values['info']; + + // Resolve palette + $palette = $values['palette']; + if ($values['scheme'] != '') { + $scheme = explode(',', $values['scheme']); + foreach ($palette as $k => $color) { + $palette[$k] = array_shift($scheme); + } + } + + // Delete old files + foreach (variable_get('color_'. $theme .'_files', array()) as $file) { + @unlink($file); + } + if ($file = dirname($file)) { + @rmdir($file); + } + + // Don't render the default colorscheme, use the standard theme instead. + if (implode(',', color_get_palette($theme, true)) == implode(',', $palette) + || $values['op'] == t('Reset to defaults')) { + variable_del('color_'. $theme .'_palette'); + variable_del('color_'. $theme .'_stylesheet'); + variable_del('color_'. $theme .'_logo'); + variable_del('color_'. $theme .'_files'); + variable_del('color_'. $theme .'_screenshot'); + return; + } + + // Prepare target locations for generated files + $id = $theme .'-'. substr(md5(serialize($palette) . microtime()), 0, 8); + $paths['target'] = variable_get('file_directory_path', 'files') .'/color/'. $id .'/'; + foreach ($paths as $path) { + if (!is_dir($path)) { + mkdir($path); + } + } + $paths['id'] = $id; + $paths['source'] = drupal_get_path('theme', $theme) .'/'; + $paths['stylesheet'] = $paths['target'] .'style.css'; + $paths['files'] = $paths['map'] = array(); + + // Save palette and stylesheet location + variable_set('color_'. $theme .'_palette', $palette); + variable_set('color_'. $theme .'_stylesheet', $paths['stylesheet']); + variable_set('color_'. $theme .'_logo', $paths['target'] .'logo.png'); + + // Copy over neutral images + foreach ($info['copy'] as $file) { + $base = basename($file); + copy($paths['source'] . $file, $paths['target'] . $base); + $paths['map'][$file] = $base; + $paths['files'][] = $paths['target'] . $base; + } + + // Render new images + _color_render_images($theme, $info, $paths, $palette); + + // Rewrite stylesheet + _color_rewrite_stylesheet($theme, $info, $paths, $palette); + + // Maintain list of files + variable_set('color_'. $theme .'_files', $paths['files']); +} + +/** + * Rewrite the stylesheet to match the colors in the palette. + */ +function _color_rewrite_stylesheet($theme, &$info, &$paths, $palette) { + // Load stylesheet + $style = file_get_contents($paths['source'] .'style.css'); + + // Prepare color conversion table + $conversion = $palette; + unset($conversion['base']); + foreach ($conversion as $k => $v) { + $conversion[$k] = drupal_strtolower($v); + } + $default = color_get_palette($theme, true); + + // Split off the "Don't touch" section of the stylesheet. + list($style, $fixed) = explode("Color Module: Don't touch", $style); + + // Look for @import commands and insert the referenced stylesheets. + $cwd = getcwd(); + chdir(drupal_get_path('theme', $theme)); + $style = preg_replace_callback('/@import\s*["\']([^"\']+)["\'];/', '_color_import_stylesheet', $style); + chdir($cwd); + + // Find all colors in the stylesheet and the chunks in between. + $style = preg_split('/(#[0-9a-f]{6}|#[0-9a-f]{3})/i', $style, -1, PREG_SPLIT_DELIM_CAPTURE); + $is_color = false; + $output = ''; + $base = 'base'; + + // Iterate over all parts + foreach ($style as $chunk) { + if ($is_color) { + $chunk = drupal_strtolower($chunk); + // Check if this is one of the colors in the default palette + if ($key = array_search($chunk, $default)) { + $chunk = $conversion[$key]; + } + // Not a pre-set color. Extrapolate from the base. + else { + $chunk = _color_shift($palette[$base], $default[$base], $chunk, $info['blend_target']); + } + } + else { + // Determine the most suitable base color for the next color. + + // 'a' declarations. Use link. + if (preg_match('@[^a-z0-9_-](a)[^a-z0-9_-][^/{]*{[^{]+$@i', $chunk)) { + $base = 'link'; + } + // 'color:' styles. Use text. + else if (preg_match('/(? $after) { + $output = str_replace($before, $after, $output); + } + + // Write new stylesheet + $file = fopen($paths['stylesheet'], 'w+'); + fwrite($file, $output); + fclose($file); + $paths['files'][] = $paths['stylesheet']; +} + +/** + * Helper function for _color_rewrite_stylesheet. + */ +function _color_import_stylesheet($matches) { + return preg_replace('/url\(([\'"]?)(?![a-z]+:)/i', 'url(\1'. dirname($matches[1]) .'/', file_get_contents($matches[1])); +} + +/** + * Render images that match a given palette. + */ +function _color_render_images($theme, &$info, &$paths, $palette) { + + // Prepare template image + $source = $paths['source'] .'/'. $info['base_image']; + $source = imagecreatefrompng($source); + + // Prepare target buffer + $width = imagesx($source); + $height = imagesy($source); + $target = imagecreatetruecolor($width, $height); + imagealphablending($target, true); + + // Fill regions of solid color. + foreach ($info['fill'] as $color => $fill) { + imagefilledrectangle($target, $fill[0], $fill[1], $fill[0] + $fill[2], $fill[1] + $fill[3], _color_gd($target, $palette[$color])); + } + + // Render gradient + for ($y = 0; $y < $info['gradient'][3]; ++$y) { + $color = _color_blend($target, $palette['top'], $palette['bottom'], $y / ($info['gradient'][3] - 1)); + imagefilledrectangle($target, $info['gradient'][0], $info['gradient'][1] + $y, $info['gradient'][2], $info['gradient'][1] + $y + 1, $color); + } + + // Blend over template + imagecopy($target, $source, 0, 0, 0, 0, $width, $height); + + // Cut out slices + foreach ($info['slices'] as $file => $coord) { + list($x, $y, $width, $height) = $coord; + $base = basename($file); + $image = $paths['target'] . $base; + + // Cut out slice + if ($file == 'screenshot.png') { + $slice = imagecreatetruecolor(150, 90); + imagecopyresampled($slice, $target, 0, 0, $x, $y, 150, 90, $width, $height); + variable_set('color_'. $theme .'_screenshot', $image); + } + else { + $slice = imagecreatetruecolor($width, $height); + imagecopy($slice, $target, 0, 0, $x, $y, $width, $height); + } + + // Save image + imagepng($slice, $image); + imagedestroy($slice); + $paths['files'][] = $image; + + // Build before/after map of image paths. + $paths['map'][$file] = $base; + } + + // Clean up + imagedestroy($source); + imagedestroy($target); +} + +/** + * Shift a given color, using a reference pair and a target blend color. + * + * Note: this function is significantly different from the JS version, as it + * is written to match the blended images perfectly. + * + * Constraint: if (ref2 == target + (ref1 - target) * delta) for some fraction delta + * then (return == target + (given - target) * delta) + * + * Loose constraint: Preserve relative positions in saturation and luminance + * space. + */ +function _color_shift($given, $ref1, $ref2, $target) { + + // We assume that ref2 is a blend of ref1 and target and find + // delta based on the length of the difference vectors: + + // delta = 1 - |ref2 - ref1| / |white - ref1| + $target = _color_unpack($target, true); + $ref1 = _color_unpack($ref1, true); + $ref2 = _color_unpack($ref2, true); + for ($i = 0; $i < 3; ++$i) { + $numerator += ($ref2[$i] - $ref1[$i]) * ($ref2[$i] - $ref1[$i]); + $denominator += ($target[$i] - $ref1[$i]) * ($target[$i] - $ref1[$i]); + } + $delta = ($denominator > 0) ? (1 - sqrt($numerator / $denominator)) : 0; + + // Calculate the color that ref2 would be if the assumption was true. + for ($i = 0; $i < 3; ++$i) { + $ref3[$i] = $target[$i] + ($ref1[$i] - $target[$i]) * $delta; + } + + // If the assumption is not true, there is a difference between ref2 and ref3. + // We measure this in HSL space. Notation: x' = hsl(x). + $ref2 = _color_rgb2hsl($ref2); + $ref3 = _color_rgb2hsl($ref3); + for ($i = 0; $i < 3; ++$i) { + $shift[$i] = $ref2[$i] - $ref3[$i]; + } + + // Take the given color, and blend it towards the target. + $given = _color_unpack($given, true); + for ($i = 0; $i < 3; ++$i) { + $result[$i] = $target[$i] + ($given[$i] - $target[$i]) * $delta; + } + + // Finally, we apply the extra shift in HSL space. + // Note: if ref2 is a pure blend of ref1 and target, then |shift| = 0. + $result = _color_rgb2hsl($result); + for ($i = 0; $i < 3; ++$i) { + $result[$i] = min(1, max(0, $result[$i] + $shift[$i])); + } + $result = _color_hsl2rgb($result); + + // Return hex color. + return _color_pack($result, true); +} + +/** + * Convert a hex triplet into a GD color. + */ +function _color_gd($img, $hex) { + $c = array_merge(array($img), _color_unpack($hex)); + return call_user_func_array('imagecolorallocate', $c); +} + +/** + * Blend two hex colors and return the GD color. + */ +function _color_blend($img, $hex1, $hex2, $alpha) { + $in1 = _color_unpack($hex1); + $in2 = _color_unpack($hex2); + $out = array($img); + for ($i = 0; $i < 3; ++$i) { + $out[] = $in1[$i] + ($in2[$i] - $in1[$i]) * $alpha; + } + return call_user_func_array('imagecolorallocate', $out); +} + +/** + * Convert a hex color into an RGB triplet. + */ +function _color_unpack($hex, $normalize = false) { + if (strlen($hex) == 4) { + $hex = $hex[1] . $hex[1] . $hex[2] . $hex[2] . $hex[3] . $hex[3]; + } + $c = hexdec($hex); + for ($i = 16; $i >= 0; $i -= 8) { + $out[] = (($c >> $i) & 0xFF) / ($normalize ? 255 : 1); + } + return $out; +} + +/** + * Convert an RGB triplet to a hex color. + */ +function _color_pack($rgb, $normalize = false) { + foreach ($rgb as $k => $v) { + $out |= (($v * ($normalize ? 255 : 1)) << (16 - $k * 8)); + } + return '#'. str_pad(dechex($out), 6, 0, STR_PAD_LEFT); +} + +/** + * Convert a HSL triplet into RGB + */ +function _color_hsl2rgb($hsl) { + $h = $hsl[0]; + $s = $hsl[1]; + $l = $hsl[2]; + $m2 = ($l <= 0.5) ? $l * ($s + 1) : $l + $s - $l*$s; + $m1 = $l * 2 - $m2; + return array(_color_hue2rgb($m1, $m2, $h + 0.33333), + _color_hue2rgb($m1, $m2, $h), + _color_hue2rgb($m1, $m2, $h - 0.33333)); +} + +/** + * Helper function for _color_hsl2rgb(). + */ +function _color_hue2rgb($m1, $m2, $h) { + $h = ($h < 0) ? $h + 1 : (($h > 1) ? $h - 1 : $h); + if ($h * 6 < 1) return $m1 + ($m2 - $m1) * $h * 6; + if ($h * 2 < 1) return $m2; + if ($h * 3 < 2) return $m1 + ($m2 - $m1) * (0.66666 - $h) * 6; + return $m1; +} + +/** + * Convert an RGB triplet to HSL. + */ +function _color_rgb2hsl($rgb) { + $r = $rgb[0]; + $g = $rgb[1]; + $b = $rgb[2]; + $min = min($r, min($g, $b)); + $max = max($r, max($g, $b)); + $delta = $max - $min; + $l = ($min + $max) / 2; + $s = 0; + if ($l > 0 && $l < 1) { + $s = $delta / ($l < 0.5 ? (2 * $l) : (2 - 2 * $l)); + } + $h = 0; + if ($delta > 0) { + if ($max == $r && $max != $g) $h += ($g - $b) / $delta; + if ($max == $g && $max != $b) $h += (2 + ($b - $r) / $delta); + if ($max == $b && $max != $r) $h += (4 + ($r - $g) / $delta); + $h /= 6; + } + return array($h, $s, $l); +} \ No newline at end of file diff --git a/modules/color/images/hook.png b/modules/color/images/hook.png new file mode 100644 index 000000000000..664f0915b847 Binary files /dev/null and b/modules/color/images/hook.png differ diff --git a/modules/color/images/lock.png b/modules/color/images/lock.png new file mode 100644 index 000000000000..6903a9db777a Binary files /dev/null and b/modules/color/images/lock.png differ diff --git a/modules/system/system.install b/modules/system/system.install index f18b2ff87709..c94a05234622 100644 --- a/modules/system/system.install +++ b/modules/system/system.install @@ -1010,7 +1010,7 @@ function system_install() { } db_query("INSERT INTO {system} (filename, name, type, description, status, throttle, bootstrap, schema_version) VALUES ('themes/engines/phptemplate/phptemplate.engine', 'phptemplate', 'theme_engine', '', 1, 0, 0, 0)"); - db_query("INSERT INTO {system} (filename, name, type, description, status, throttle, bootstrap, schema_version) VALUES ('themes/bluemarine/page.tpl.php', 'bluemarine', 'theme', 'themes/engines/phptemplate/phptemplate.engine', 1, 0, 0, 0)"); + db_query("INSERT INTO {system} (filename, name, type, description, status, throttle, bootstrap, schema_version) VALUES ('themes/garland/page.tpl.php', 'garland', 'theme', 'themes/engines/phptemplate/phptemplate.engine', 1, 0, 0, 0)"); db_query("INSERT INTO {users} (uid,name,mail) VALUES(0,'','')"); @@ -1020,10 +1020,10 @@ function system_install() { db_query("INSERT INTO {permission} VALUES (1,'access content',0)"); db_query("INSERT INTO {permission} VALUES (2,'access comments, access content, post comments, post comments without approval',0)"); - db_query("INSERT INTO {variable} (name,value) VALUES('theme_default', 's:10:\"bluemarine\";')"); + db_query("INSERT INTO {variable} (name,value) VALUES('theme_default', 's:7:\"garland\";')"); - db_query("INSERT INTO {blocks} (module,delta,theme,status) VALUES('user', 0, 'bluemarine', 1)"); - db_query("INSERT INTO {blocks} (module,delta,theme,status) VALUES('user', 1, 'bluemarine', 1)"); + db_query("INSERT INTO {blocks} (module,delta,theme,status) VALUES('user', 0, 'garland', 1)"); + db_query("INSERT INTO {blocks} (module,delta,theme,status) VALUES('user', 1, 'garland', 1)"); db_query("INSERT INTO {node_access} VALUES (0, 0, 'all', 1, 0, 0)"); diff --git a/profiles/default/default.profile b/profiles/default/default.profile index 158477e56953..f62b01aa56c8 100644 --- a/profiles/default/default.profile +++ b/profiles/default/default.profile @@ -8,7 +8,7 @@ * An array of modules to be enabled. */ function default_profile_modules() { - return array('block', 'comment', 'filter', 'help', 'menu', 'node', 'system', 'taxonomy', 'user', 'watchdog'); + return array('block', 'color', 'comment', 'filter', 'help', 'menu', 'node', 'system', 'taxonomy', 'user', 'watchdog'); } /** diff --git a/themes/garland/block.tpl.php b/themes/garland/block.tpl.php new file mode 100644 index 000000000000..01aca06ec424 --- /dev/null +++ b/themes/garland/block.tpl.php @@ -0,0 +1,8 @@ +
+ +subject): ?> +

subject ?>

+ + +
content ?>
+
diff --git a/themes/garland/color/base.png b/themes/garland/color/base.png new file mode 100644 index 000000000000..4a31efed02ae Binary files /dev/null and b/themes/garland/color/base.png differ diff --git a/themes/garland/color/color.inc b/themes/garland/color/color.inc new file mode 100644 index 000000000000..15f7db37c1e4 --- /dev/null +++ b/themes/garland/color/color.inc @@ -0,0 +1,61 @@ + array( + '#0072b9,#027ac6,#2385c2,#5ab5ee,#494949' => t('Blue Lagoon (Default)'), + '#d5b048,#6c420e,#331900,#971702,#494949' => t('Belgian Chocolate'), + '#d0cb9a,#917803,#efde01,#e6fb2d,#494949' => t('Citrus Blast'), + '#c9c497,#0c7a00,#03961e,#7be000,#494949' => t('Greenbeam'), + '#ffe23d,#a9290a,#fc6d1d,#a30f42,#494949' => t('Mediterrano'), + '#788597,#3f728d,#a9adbc,#d4d4d4,#707070' => t('Mercury'), + '#666993,#85000f,#960335,#fb2d28,#696969' => t('Red Velour'), + ), + + // Images to copy over + 'copy' => array( + 'images/menu-collapsed.gif', + 'images/menu-expanded.gif', + 'images/menu-leaf.gif', + ), + + // Coordinates of gradient (x, y, width, height) + 'gradient' => array(0, 37, 760, 121), + + // Color areas to fill (x, y, width, height) + 'fill' => array( + 'base' => array(0, 0, 760, 568), + 'link' => array(107, 533, 41, 23), + ), + + // Coordinates of all the theme slices (x, y, width, height) + // with their filename as used in the stylesheet. + 'slices' => array( + 'images/body.png' => array(0, 37, 1, 280), + 'images/bg-bar.png' => array(202, 530, 76, 14), + 'images/bg-bar-white.png' => array(202, 506, 76, 14), + 'images/bg-tab.png' => array(107, 533, 41, 23), + 'images/bg-navigation.png' => array(0, 0, 7, 37), + 'images/bg-content-left.png' => array(40, 117, 50, 352), + 'images/bg-content-right.png' => array(510, 117, 50, 352), + 'images/bg-content.png' => array(299, 117, 7, 200), + 'images/bg-navigation-item.png' => array(32, 37, 17, 12), + 'images/bg-navigation-item-hover.png' => array(54, 37, 17, 12), + 'images/gradient-inner.png' => array(646, 307, 112, 42), + + 'logo.png' => array(622, 51, 64, 73), + 'screenshot.png' => array(0, 37, 400, 240), + ), + + // Reference color used for blending. Matches the base.png's colors. + 'blend_target' => '#ffffff', + + // Preview files + 'preview_image' => 'color/preview.png', + 'preview_css' => 'color/preview.css', + + // Base file for image generation + 'base_image' => 'color/base.png', +); diff --git a/themes/garland/color/preview.css b/themes/garland/color/preview.css new file mode 100644 index 000000000000..8ba587609194 --- /dev/null +++ b/themes/garland/color/preview.css @@ -0,0 +1,58 @@ +/* $Id$ */ + +/* Positioning */ +#preview { + overflow: hidden; + max-width: 100%; +} +#preview, #preview #img { + width: 596px; + height: 371px; +} +#preview #gradient { + position: absolute; + left: 0; + right: 0; + top: 19px; + height: 120px; + z-index: 2; +} +#preview #text { + position: absolute; + left: 80px; + width: 436px; + top: 160px; + height: 120px; + z-index: 4; +} +#preview #img { + position: relative; + z-index: 3; +} +#preview #gradient .gradient-line { + height: 10px; + overflow: hidden; +} + +/* Basic styles to match */ +#preview { + font: 12px/170% Verdana; +} +#preview h2 { + margin: 0; + padding: 0; + font-weight: normal; + font-family: Helvetica, Arial, sans-serif; + font-size: 160%; + line-height: 130%; +} +#preview p { + margin: .5em 0; +} +#preview a:link, #preview a:visited { + text-decoration: none; + font-weight: normal; +} +#preview a:hover { + text-decoration: underline; +} \ No newline at end of file diff --git a/themes/garland/color/preview.png b/themes/garland/color/preview.png new file mode 100644 index 000000000000..3403ee8dd034 Binary files /dev/null and b/themes/garland/color/preview.png differ diff --git a/themes/garland/comment.tpl.php b/themes/garland/comment.tpl.php new file mode 100644 index 000000000000..65237e89c221 --- /dev/null +++ b/themes/garland/comment.tpl.php @@ -0,0 +1,22 @@ +
+ + + + theme('username', $comment), '!date' => format_date($comment->timestamp))); ?> + + +new) : ?> + + + + +

+ +
+ +
+ + + + +
diff --git a/themes/garland/fix-ie.css b/themes/garland/fix-ie.css new file mode 100644 index 000000000000..c45020c9533a --- /dev/null +++ b/themes/garland/fix-ie.css @@ -0,0 +1,54 @@ +/** + * Themetastic, for Drupal 5.0 + * Stefan Nagtegaal, iStyledThis [dot] nl + * Steven Wittens, acko [dot] net + * + */ + +body { + /* Center layout */ + text-align: center; + /* Allow text resizing */ + font-size: 80%; +} + +#wrapper #container { + /* Reset text alignment */ + text-align: left; +} + +#wrapper #container #center { + /* Reduce amount of damage done by extremely wide content */ + overflow: hidden; +} + +#wrapper #container #center .right-corner .left-corner { + /* Because of the lack of min-height, we use height as an alternative */ + height: 400px; +} + +fieldset { + /* Don't draw backgrounds on fieldsets in IE, as they look really bad. */ + background: none; +} + +ul.primary { + /* Fix missing top margin */ + position: relative; +/* top: 0.5em; */ +} + +/* Prevent fieldsets from shifting when changing collapsed state. */ +html.js fieldset.collapsible { + position: relative; + top: -1em; +} +html.js fieldset.collapsed { + top: 0; + margin-bottom: 1em; +} + +td.menu-disabled { + /* Use filter to emulate CSS3 opacity */ + filter: alpha(opacity=50); +} diff --git a/themes/garland/images/bg-bar-white.png b/themes/garland/images/bg-bar-white.png new file mode 100644 index 000000000000..256ea31b12a2 Binary files /dev/null and b/themes/garland/images/bg-bar-white.png differ diff --git a/themes/garland/images/bg-bar.png b/themes/garland/images/bg-bar.png new file mode 100644 index 000000000000..1fbcae04367d Binary files /dev/null and b/themes/garland/images/bg-bar.png differ diff --git a/themes/garland/images/bg-content-left.png b/themes/garland/images/bg-content-left.png new file mode 100644 index 000000000000..a64b346e650c Binary files /dev/null and b/themes/garland/images/bg-content-left.png differ diff --git a/themes/garland/images/bg-content-right.png b/themes/garland/images/bg-content-right.png new file mode 100644 index 000000000000..f07ebb5cdef3 Binary files /dev/null and b/themes/garland/images/bg-content-right.png differ diff --git a/themes/garland/images/bg-content.png b/themes/garland/images/bg-content.png new file mode 100644 index 000000000000..d55828ed2277 Binary files /dev/null and b/themes/garland/images/bg-content.png differ diff --git a/themes/garland/images/bg-navigation-item-hover.png b/themes/garland/images/bg-navigation-item-hover.png new file mode 100644 index 000000000000..c783d718b7b2 Binary files /dev/null and b/themes/garland/images/bg-navigation-item-hover.png differ diff --git a/themes/garland/images/bg-navigation-item.png b/themes/garland/images/bg-navigation-item.png new file mode 100644 index 000000000000..d2452ac4f22e Binary files /dev/null and b/themes/garland/images/bg-navigation-item.png differ diff --git a/themes/garland/images/bg-navigation.png b/themes/garland/images/bg-navigation.png new file mode 100644 index 000000000000..18b9559de682 Binary files /dev/null and b/themes/garland/images/bg-navigation.png differ diff --git a/themes/garland/images/bg-tab.png b/themes/garland/images/bg-tab.png new file mode 100644 index 000000000000..18554b04d176 Binary files /dev/null and b/themes/garland/images/bg-tab.png differ diff --git a/themes/garland/images/body.png b/themes/garland/images/body.png new file mode 100644 index 000000000000..b361e7b38058 Binary files /dev/null and b/themes/garland/images/body.png differ diff --git a/themes/garland/images/gradient-inner.png b/themes/garland/images/gradient-inner.png new file mode 100644 index 000000000000..7ca1413f67f0 Binary files /dev/null and b/themes/garland/images/gradient-inner.png differ diff --git a/themes/garland/images/menu-collapsed.gif b/themes/garland/images/menu-collapsed.gif new file mode 100644 index 000000000000..3dc9ca77087a Binary files /dev/null and b/themes/garland/images/menu-collapsed.gif differ diff --git a/themes/garland/images/menu-expanded.gif b/themes/garland/images/menu-expanded.gif new file mode 100644 index 000000000000..126ccc11afd2 Binary files /dev/null and b/themes/garland/images/menu-expanded.gif differ diff --git a/themes/garland/images/menu-leaf.gif b/themes/garland/images/menu-leaf.gif new file mode 100644 index 000000000000..b7811910ef8b Binary files /dev/null and b/themes/garland/images/menu-leaf.gif differ diff --git a/themes/garland/logo.png b/themes/garland/logo.png new file mode 100644 index 000000000000..3529fef3189a Binary files /dev/null and b/themes/garland/logo.png differ diff --git a/themes/garland/minnelli/color/base.png b/themes/garland/minnelli/color/base.png new file mode 100644 index 000000000000..17974b8f70b6 Binary files /dev/null and b/themes/garland/minnelli/color/base.png differ diff --git a/themes/garland/minnelli/color/color.inc b/themes/garland/minnelli/color/color.inc new file mode 100644 index 000000000000..d7b0a99f3ac2 --- /dev/null +++ b/themes/garland/minnelli/color/color.inc @@ -0,0 +1,61 @@ + array( + '#0072b9,#027ac6,#2385c2,#5ab5ee,#494949' => t('Blue Lagoon (Default)'), + '#d5b048,#6c420e,#331900,#971702,#494949' => t('Belgian Chocolate'), + '#d0cb9a,#917803,#efde01,#e6fb2d,#494949' => t('Citrus Blast'), + '#c9c497,#0c7a00,#03961e,#7be000,#494949' => t('Greenbeam'), + '#ffe23d,#a9290a,#fc6d1d,#a30f42,#494949' => t('Mediterrano'), + '#788597,#3f728d,#a9adbc,#d4d4d4,#707070' => t('Mercury'), + '#666993,#85000f,#960335,#fb2d28,#696969' => t('Red Velour'), + ), + + // Images to copy over + 'copy' => array( + '../images/menu-collapsed.gif', + '../images/menu-expanded.gif', + '../images/menu-leaf.gif', + ), + + // Coordinates of gradient (x, y, width, height) + 'gradient' => array(0, 37, 760, 121), + + // Color areas to fill (x, y, width, height) + 'fill' => array( + 'base' => array(0, 0, 760, 568), + 'link' => array(107, 533, 41, 23), + ), + + // Coordinates of all the theme slices (x, y, width, height) + // with their filename as used in the stylesheet. + 'slices' => array( + '../images/body.png' => array(0, 37, 1, 280), + '../images/bg-bar.png' => array(202, 530, 76, 14), + '../images/bg-bar-white.png' => array(202, 506, 76, 14), + '../images/bg-tab.png' => array(107, 533, 41, 23), + '../images/bg-navigation.png' => array(0, 0, 7, 37), + '../images/bg-content-left.png' => array(40, 117, 50, 352), + '../images/bg-content-right.png' => array(510, 117, 50, 352), + '../images/bg-content.png' => array(299, 117, 7, 200), + '../images/bg-navigation-item.png' => array(32, 37, 17, 12), + '../images/bg-navigation-item-hover.png' => array(54, 37, 17, 12), + '../images/gradient-inner.png' => array(646, 307, 112, 42), + + 'logo.png' => array(622, 51, 64, 73), + 'screenshot.png' => array(0, 37, 400, 240), + ), + + // Reference color used for blending. Matches the base.png's colors. + 'blend_target' => '#ffffff', + + // Preview files + 'preview_image' => 'color/preview.png', + 'preview_css' => '../color/preview.css', + + // Base file for image generation + 'base_image' => 'color/base.png', +); diff --git a/themes/garland/minnelli/color/preview.png b/themes/garland/minnelli/color/preview.png new file mode 100644 index 000000000000..51012b3de7c7 Binary files /dev/null and b/themes/garland/minnelli/color/preview.png differ diff --git a/themes/garland/minnelli/logo.png b/themes/garland/minnelli/logo.png new file mode 100644 index 000000000000..3529fef3189a Binary files /dev/null and b/themes/garland/minnelli/logo.png differ diff --git a/themes/garland/minnelli/screenshot.png b/themes/garland/minnelli/screenshot.png new file mode 100644 index 000000000000..e858b38bfea6 Binary files /dev/null and b/themes/garland/minnelli/screenshot.png differ diff --git a/themes/garland/minnelli/style.css b/themes/garland/minnelli/style.css new file mode 100644 index 000000000000..11d260fa2266 --- /dev/null +++ b/themes/garland/minnelli/style.css @@ -0,0 +1,20 @@ +/** + * Themetastic, for Drupal 5.0 + * Stefan Nagtegaal, iStyledThis [dot] nl + * Steven Wittens, acko [dot] net + */ + +@import "../style.css"; + +body #wrapper #container { + width: 560px; +} + +body.sidebars #wrapper #container { + width: 980px; +} + +body.sidebar-left #wrapper #container, +body.sidebar-right #wrapper #container { + width: 770px; +} diff --git a/themes/garland/node.tpl.php b/themes/garland/node.tpl.php new file mode 100644 index 000000000000..56af236540ad --- /dev/null +++ b/themes/garland/node.tpl.php @@ -0,0 +1,31 @@ +type); ?> + +
+ + + + +

+ + + + theme('username', $node), '!date' => format_date($node->created))); ?> + + +
+ +
+ +
+
+ +
+ +
+ + + + +
+ +
\ No newline at end of file diff --git a/themes/garland/page.tpl.php b/themes/garland/page.tpl.php new file mode 100644 index 000000000000..e4682228ff98 --- /dev/null +++ b/themes/garland/page.tpl.php @@ -0,0 +1,92 @@ + + + + <?php print $head_title ?> + + + + + + > + + + + +
+
+ + + + + + + +
+ + '. $mission .'
'; endif; ?> + + '; endif; ?> + '. $title .''; endif; ?> + '; endif; ?> + + + + + + + + +
+ + + + + +
+ + + + + + \ No newline at end of file diff --git a/themes/garland/screenshot.png b/themes/garland/screenshot.png new file mode 100644 index 000000000000..7a9dcc19f392 Binary files /dev/null and b/themes/garland/screenshot.png differ diff --git a/themes/garland/style.css b/themes/garland/style.css new file mode 100644 index 000000000000..68fc5841081b --- /dev/null +++ b/themes/garland/style.css @@ -0,0 +1,924 @@ +/** + * Themetastic, for Drupal 5.0 + * Stefan Nagtegaal, iStyledThis [dot] nl + * Steven Wittens, acko [dot] net` + * + * If you use a customized color scheme, you must regenerate it after + * modifying this file. + */ + +/** + * Generic elements + */ +body { + margin: 0; + padding: 0; + background: #edf5fa; + font: 12px/170% Verdana; + color: #494949; +} + +input { + font: 12px/100% "Verdana"; + color: #494949; +} + +textarea, select { + font: 12px/160% "Verdana"; + color: #494949; +} + +h1, h2, h3, h4, h5, h6 { + margin: 0; + padding: 0; + font-weight: normal; + font-family: Helvetica, Arial, sans-serif; +} + +h1 { + font-size: 170%; +} + +h2 { + font-size: 160%; + line-height: 130%; +} + +h3 { + font-size: 140%; +} + +h4 { + font-size: 130%; +} + +h5 { + font-size: 120%; +} + +h6 { + font-size: 110%; +} + +ul, quote, code, fieldset { + margin: .5em 0; +} + +p { + margin: 0.6em 0 1.2em; + padding: 0; +} + +a:link, a:visited { + color: #027AC6; + text-decoration: none; +} + +a:hover { + color: #0062A0; + text-decoration: underline; +} + +a:active, a.active { + color: #5895be; +} + +hr { + margin: 0; + padding: 0; + border: none; + height: 1px; + background: #5294c1; +} + +ul { + margin: 0.5em 0 1em; + padding: 0; +} + +ul li { + margin: 0.4em 0 0.4em .5em; +} + +ul.menu, .item-list ul { + margin: 0.35em 0 0 -0.5em; + padding: 0; +} + +ul.menu ul, .item-list ul ul { + margin-left: 0em; +} + +ul li, ul.menu li, .item-list ul li, li.leaf { + margin: 0.15em 0 0.15em .5em; +} + +ul li, ul.menu li, .item-list ul li, li.leaf { + padding: 0 0 .2em 1.5em; + list-style-type: none; + list-style-image: none; + background: transparent url("images/menu-leaf.gif") no-repeat 1px .35em; +} + +ul li.expanded { + background: transparent url("images/menu-expanded.gif") no-repeat 1px .35em; +} + +ul li.collapsed { + background: transparent url("images/menu-collapsed.gif") no-repeat 0px .35em; +} + +ul li.leaf a, ul li.expanded a, ul li.collapsed a { + display: block; +} + +ul.inline li { + background: none; + margin: 0; + padding: 0 1em 0 0; +} + +fieldset ul.clear-block li { + margin: 0; + padding: 0; + background-image: none; +} + +dl { + margin: 0.5em 0 1em 1.5em; +} + +dl dt { +} + +dl dd { + margin: 0 0 .5em 1.5em; +} + +img, a img { + border: none; +} + +table { + margin: 1em 0; + width: 100%; +} + +thead th { + border-bottom: 2px solid #d3e7f4; + color: #494949; + font-weight: bold; +} + +th a:link, th a:visited { + color: #6f9dbd; +} + +td, th { + padding: .3em .5em; +} + +tr.even, tr.odd, tbody th { + border: solid #d3e7f4; + border-width: 1px 0; +} + +tr.odd, tr.info { + background-color: #edf5fa; +} + +tr.even { + background-color: #fff; +} + +tr.odd td.active { + background-color: #ddecf5; +} + +tr.even td.active { + background-color: #e6f1f7; +} + +td.region, td.module, td.container { + border-top: 1.5em solid #fff; + border-bottom: 1px solid #b4d7f0; + background-color: #d4e7f3; + color: #455067; + font-weight: bold; +} + +tr:first-child td.region, tr:first-child td.module, tr:first-child td.container { + border-top-width: 0; +} + +span.form-required { + color: #ffae00; +} + +span.submitted, .description { + font-size: 0.92em; + color: #898989; +} + +.description { + line-height: 150%; + margin-bottom: 0.75em; + color: #898989; +} + +.messages, .preview { + margin: .75em 0 .75em; + padding: .5em 1em; +} + +.messages ul { + margin: 0; +} + +.form-checkboxes, .form-radios, .form-checkboxes .form-item, .form-radios .form-item { + margin: 0.25em 0; +} + +#center form { + margin-bottom: 2em; +} + +.form-button, .form-submit { + margin: 2em 0.5em 1em 0; +} + +.poll .form-submit, +fieldset .form-button, fieldset .form-submit, +.sidebar .form-button, .sidebar .form-submit, +table .form-button, table .form-submit { + margin: 0; +} + +.box { + margin-bottom: 2.5em; +} + +/** + * Layout + */ + +#navigation { + height: 1em; + background: url("images/bg-navigation.png") repeat-x 50% 100%; +} + +#wrapper { + background: #edf5fa url("images/body.png") repeat-x 50% 0; +} + +#wrapper #container { + margin: 0 auto; + padding: 0 20px; + max-width: 1270px; +} + +#wrapper #container #header { + height: 80px; +} + +#wrapper #container #header #logo-floater { + position: absolute; +} + +#wrapper #container #header h1, #wrapper #container #header h1 a:link, #wrapper #container #header h1 a:visited { + line-height: 120px; + position: relative; + z-index: 2; + white-space: nowrap; +} + +#wrapper #container #header h1 span { + font-weight: bold; +} + +#wrapper #container #header h1 img { + padding-top: 16px; + padding-right: 20px; + float: left; +} + +/* With 3 columns, require a minimum width of 1000px to ensure there is enough horizontal space. */ +body.sidebars { + min-width: 980px; +} +/* With 2 columsn, require a minimum width of 800px. */ +body.sidebar-left, body.sidebar-right { + min-width: 780px; +} + +/* We must define 100% width to avoid the body being too narrow for near-empty pages */ +#wrapper #container #center { + float: left; + width: 100%; +} + +/* So we move the #center container over the sidebars to compensate */ +body.sidebar-left #center { + margin-left: -210px; +} +body.sidebar-right #center { + margin-right: -210px; +} +body.sidebars #center { + margin: 0 -210px; +} + +/* And add blanks left and right for the sidebars to fill */ +body.sidebar-left #squeeze { + margin-left: 210px; +} +body.sidebar-right #squeeze { + margin-right: 210px; +} +body.sidebars #squeeze { + margin: 0 210px; +} + +/* We ensure the sidebars are still clickable using z-index */ +#wrapper #container .sidebar { + margin: 60px 0 5em; + width: 210px; + float: left; + z-index: 2; + position: relative; +} + +#wrapper #container .sidebar .block { + margin: 0 0 1.5em 0; +} + +#sidebar-left .block { + padding: 0 15px 0 0px; +} + +#sidebar-right .block { + padding: 0 0px 0 15px; +} + +.block .content { + margin: 0.5em 0; +} + +/* Now we add the backgrounds for the main content shading */ +#wrapper #container #center #squeeze { + background: #fff url("images/bg-content.png") repeat-x 50% 0; + position: relative; +} + +#wrapper #container #center .right-corner { + background: transparent url("images/bg-content-right.png") no-repeat 100% 0; + position: relative; + left: 10px; +} + +#wrapper #container #center .right-corner .left-corner { + padding: 60px 25px 5em 35px; + background: transparent url("images/bg-content-left.png") no-repeat 0 0; + margin-left: -10px; + position: relative; + left: -10px; + min-height: 400px; +} + +#wrapper #container #footer { + float: none; + clear: both; + text-align: center; + margin: 4em 0 -3em; + color: #898989; +} + +#wrapper #container .breadcrumb { + position: absolute; + top: 15px; + left: 35px; + z-index: 3; +} + +body.sidebar-left #footer { + margin-left: -210px; +} + +body.sidebar-right #footer { + margin-right: -210px; +} + +body.sidebars #footer { + margin: 0 -210px; +} + +/** + * Header + */ +#wrapper #container #header h1, #wrapper #container #header h1 a:link, #wrapper #container #header h1 a:visited { + color: #fff; + font-weight: normal; + text-shadow: #1659ac 0px 1px 3px; + font-size: 1.5em; +} + +#wrapper #container #header h1 a:hover { + text-decoration: none; +} + +#wrapper #container .breadcrumb { + font-size: 0.92em; +} + +#wrapper #container .breadcrumb, #wrapper #container .breadcrumb a { + color: #529ad6; +} + +#mission { + padding: 1em; + background-color: #fff; + border: 1px solid #e0e5fb; + margin-bottom: 2em; +} + +/** + * Primary navigation + */ +ul.primary-links { + margin: 0; + padding: 0; + float: right; + position: relative; + z-index: 4; +} + +ul.primary-links li { + margin: 0; + padding: 0; + float: left; + background-image: none; +} + +ul.primary-links li a, ul.primary-links li a:link, ul.primary-links li a:visited { + display: block; + margin: 0 1em; + padding: .75em 0 0; + color: #fff; + background: transparent url("images/bg-navigation-item.png") no-repeat 50% 0; +} + +ul.primary-links li a:hover, ul.primary-links li a.active { + color: #fff; + background: transparent url("images/bg-navigation-item-hover.png") no-repeat 50% 0; +} + +/** + * Secondary navigation + */ +ul.secondary-links { + margin: 0; + padding: 20px 0 0; + float: right; + clear: right; + position: relative; + z-index: 4; +} + +ul.secondary-links li { + margin: 0; + padding: 0; + float: left; + background-image: none; +} + +ul.secondary-links li a, ul.secondary-links li a:link, ul.secondary-links li a:visited { + display: block; + margin: 0 1em; + padding: .75em 0 0; + color: #cde3f1; + background: transparent; +} + +ul.secondary-links li a:hover, ul.secondary-links li a.active { + color: #cde3f1; + background: transparent; +} + +/** + * Local tasks + */ +ul.primary, ul.primary li, ul.secondary, ul.secondary li { + border: 0; + background: none; + margin: 0; + padding: 0; +} + +#tabs-wrapper { + margin: 0 -26px 1em; + padding: 0 26px; + border-bottom: 1px solid #e9eff3; + position: relative; +} +ul.primary { + padding: 0.5em 0 10px; + float: left; +} +ul.secondary { + clear: both; + text-align: left; + border-bottom: 1px solid #e9eff3; + margin: -0.2em -26px 1em; + padding: 0 26px 0.6em; +} +h2.with-tabs { + float: left; + margin: 0 2em 0 0; + padding: 0; +} + +ul.primary li a, ul.primary li.active a, ul.primary li a:hover, ul.primary li a:visited, +ul.secondary li a, ul.secondary li.active a, ul.secondary li a:hover, ul.secondary li a:visited { + border: 0; + background: transparent; + padding: 4px 1em; + margin: 0 0 0 1px; + height: auto; + text-decoration: none; + position: relative; + top: -1px; +} +ul.primary li.active a, ul.primary li.active a:link, ul.primary li.active a:visited, ul.primary li a:hover, +ul.secondary li.active a, ul.secondary li.active a:link, ul.secondary li.active a:visited, ul.secondary li a:hover { + background: url('images/bg-tab.png') repeat-x 0 50%; + color: #fff; +} +ul.primary li.active a, +ul.secondary li.active a { + font-weight: bold; +} + +/** + * Nodes & comments + */ +.node { + border-bottom: 1px solid #e9eff3; + margin: -1.5em -26px 1.5em; + padding: 1.5em 26px; +} + +ul.links li, ul.inline li { + margin-left: 0; + margin-right: 0; + padding-left: 0; + padding-right: 1em; + background-image: none; +} + +.node .links, .comment .links { + text-align: left; +} + +.node .links ul.links li, .comment .links ul.links li {} +.terms ul.links li { + margin-left: 0; + margin-right: 0; + padding-right: 0; + padding-left: 1em; +} + +.picture, .comment .submitted { + float: right; + clear: right; + padding-left: 1em; +} + +.new { + color: #ffae00; + font-size: 0.92em; + font-weight: bold; + float: right; +} + +.terms { + float: right; +} + +.preview .node, .preview .comment, .sticky { + margin: 0; + padding: 0.5em 0; + border: 0; + background: 0; +} + +.sticky { + padding: 1em; + background-color: #fff; + border: 1px solid #e0e5fb; + margin-bottom: 2em; +} + +#comments { + position: relative; + top: -1px; + border-bottom: 1px solid #e9eff3; + margin: -1.5em -25px 0; + padding: 0 25px; +} + +#comments h2.comments { + margin: 0 -25px; + padding: .5em 25px; + background: #fff url("images/gradient-inner.png") repeat-x 0 0; +} + +.comment { + margin: 0 -25px; + padding: 1.5em 25px 1.5em; + border-top: 1px solid #e9eff3; +} + +.indented { + margin-left: 25px; +} + +.comment h3 a.active { + color: #494949; +} + +.node .content, .comment .content { + margin: 0.6em 0; +} + +/** + * Aggregator.module + */ +#aggregator { + margin-top: 1em; +} +#aggregator .feed-item-title { + font-size: 160%; + line-height: 130%; +} +#aggregator .feed-item { + border-bottom: 1px solid #e9eff3; + margin: -1.5em -31px 1.75em; + padding: 1.5em 31px; +} +#aggregator .feed-item-categories { + font-size: 0.92em; +} +#aggregator .feed-item-meta { + font-size: 0.92em; + color: #898989; +} + +/** + * Color.module + */ +#palette .form-item { + border: 1px solid #fff; +} +#palette .item-selected { + background: #fff url("images/gradient-inner.png") repeat-x 0 0; + border: 1px solid #d9eaf5; +} + +/** + * Menu.module + */ +tr.odd td.menu-disabled { + background-color: #edf5fa; +} +tr.even td.menu-disabled { + background-color: #fff; +} +td.menu-disabled { + opacity: 0.5; +} + +/** + * Poll.module + */ +.poll .bar { + background: #fff url("images/bg-bar-white.png") repeat-x 0 0; + border: solid #f0f0f0; + border-width: 0 1px 1px; +} + +.poll .bar .foreground { + background: #71a7cc url("images/bg-bar.png") repeat-x 0 100%; +} + +.poll .percent { + font-size: .9em; +} + +/** + * Autocomplete. + */ +#autocomplete li { + cursor: default; + padding: 2px; + margin: 0; +} + +/** + * Collapsible fieldsets + */ +fieldset { + margin: 1em 0; + padding: 1em; + border: 1px solid #d9eaf5; + background: #fff url("images/gradient-inner.png") repeat-x 0 0; +} + +html.js fieldset.collapsed { + background: transparent; + padding-top: 0; + padding-bottom: 3px; +} + +html.js fieldset.collapsible legend a { + padding-left: 2em; + background: url("images/menu-expanded.gif") no-repeat 0% 50%; +} + +html.js fieldset.collapsed legend a { + background: url("images/menu-collapsed.gif") no-repeat 0% 50%; +} + +/** + * Syndication Block + */ +#block-node-0 h2 { + float: left; + padding-right: 20px; +} + +#block-node-0 img { + float: right; + padding-top: 4px; +} + +#block-node-0 .content { + clear: right; +} + +/** + * Login Block + */ +#user-login-form { + text-align: center; +} +#user-login-form ul { + text-align: left; +} + +/** + * Admin Styles + */ +div.admin-panel, +div.admin-panel .description, +div.admin-panel .body, +div.admin, +div.admin .left, +div.admin .right, +div.admin .expert-link, +div.item-list, +.menu { + margin: 0; + padding: 0; +} + +div.admin .left { + float: left; + width: 48%; +} +div.admin .right { + float: right; + width: 48%; +} + +div.admin-panel { + background: #fff url("images/gradient-inner.png") repeat-x 0 0; + padding: 1em 1em 1.5em; +} +div.admin-panel .description { + margin-bottom: 1.5em; +} +div.admin-panel dl { + margin: 0; +} +div.admin-panel dd { + color: #898989; + font-size: 0.92em; + line-height: 1.3em; + margin-top: -.2em; + margin-bottom: .65em; +} + +table.system-status-report th { + border-color: #d3e7f4; +} + +/** + * CSS support + */ +span.clear { + display: block; + clear: both; + height: 1px; + line-height: 0px; + font-size: 0px; + margin-bottom: -1px; +} + +/******************************************************************* + * Color Module: Don't touch * + *******************************************************************/ + +/** + * Generic elements. + */ +.messages { + background-color: #fff; + border: 1px solid #b8d3e5; +} + +.preview { + background-color: #fcfce8; + border: 1px solid #e5e58f; +} + +div.status { + color: #3a3; + border-color: #c7f2c8; +} + +div.error { + color: #c52020; +} + +.form-item input.error, .form-item textarea.error { + border: 1px solid #c52020; + color: #494949; +} + +/** + * Watchdog.module + */ +tr.watchdog-user { + background-color: #fcf9e5; +} + +tr.watchdog-user td.active { + background-color: #fbf5cf; +} + +tr.watchdog-content { + background-color: #fefefe; +} + +tr.watchdog-content td.active { + background-color: #f5f5f5; +} + +tr.watchdog-warning { + background-color: #fdf5e6; +} + +tr.watchdog-warning td.active { + background-color: #fdf2de; +} + +tr.watchdog-error { + background-color: #fbe4e4; +} + +tr.watchdog-error td.active { + background-color: #fbdbdb; +} +tr.watchdog-page-not-found, tr.watchdog-access-denied { + background: #d7ffd7; +} +tr.watchdog-page-not-found td.active, tr.watchdog-access-denied td.active { + background: #c7eec7; +} + +/** + * Status report colors. + */ +table.system-status-report tr.error, table.system-status-report tr.error th { + background-color: #fcc; + border-color: #ebb; + color: #200; +} +table.system-status-report tr.warning, table.system-status-report tr.warning th { + background-color: #ffd; + border-color: #eeb; +} +table.system-status-report tr.ok, table.system-status-report tr.ok th { + background-color: #dfd; + border-color: #beb; +} diff --git a/themes/garland/template.php b/themes/garland/template.php new file mode 100644 index 000000000000..b7b18be5c04b --- /dev/null +++ b/themes/garland/template.php @@ -0,0 +1,87 @@ +'. implode(' › ', $breadcrumb) .''; + } +} + +/** + * Allow themable wrapping of all comments. + */ +function phptemplate_comment_wrapper($content, $type = null) { + static $node_type; + if (isset($type)) $node_type = $type; + + if (!$content || $node_type == 'forum') { + return '
'. $content . '
'; + } + else { + return '

Comments

'. $content .'
'; + } +} + +/** + * Override or insert PHPTemplate variables into the templates. + */ +function _phptemplate_variables($hook, $vars) { + if ($hook == 'page') { + + if ($secondary = menu_secondary_local_tasks()) { + $output = ''; + $output .= "\n"; + $vars['tabs2'] = $output; + } + + // Hook into color.module + if (module_exists('color')) { + return _color_page_alter($vars); + } + } + return array(); +} + +/** + * Returns the rendered local tasks. The default implementation renders + * them as tabs. + * + * @ingroup themeable + */ +function phptemplate_menu_local_tasks() { + $output = ''; + + if ($primary = menu_primary_local_tasks()) { + $output .= "\n"; + } + + return $output; +}