| Commit | Line | Data |
|---|---|---|
| f2e5a0c5 EM |
1 | <?php |
| 2 | // $Id$ | |
| 3 | ||
| f2e5a0c5 | 4 | /** |
| fc8f8fa8 | 5 | * Implementation of hook_panels_layouts() |
| f2e5a0c5 EM |
6 | */ |
| 7 | function panels_flexible_panels_layouts() { | |
| 8 | $items['flexible'] = array( | |
| 9 | 'title' => t('Flexible'), | |
| fc8f8fa8 | 10 | 'icon' => 'flexible.png', |
| f2e5a0c5 | 11 | 'theme' => 'panels_flexible', |
| fc8f8fa8 | 12 | 'css' => 'flexible.css', |
| f2e5a0c5 EM |
13 | 'settings form' => 'panels_flexible_settings_form', |
| 14 | 'settings submit' => 'panels_flexible_settings_submit', | |
| 2edbdf2c | 15 | 'settings validate' => 'panels_flexible_settings_validate', |
| f2e5a0c5 EM |
16 | 'panels function' => 'panels_flexible_panels', |
| 17 | ); | |
| 18 | ||
| 19 | return $items; | |
| 20 | } | |
| 21 | ||
| 22 | function panels_flexible_default_panels() { | |
| 23 | return array( | |
| 24 | 'percent_width' => 100, | |
| 25 | 'rows' => 3, | |
| 26 | 'width_type' => '%', | |
| 27 | 'row_1' => array( | |
| 28 | 'columns' => 1, | |
| 29 | 'width_1' => 100, | |
| 30 | 'names' => array(t('Top')), | |
| 31 | ), | |
| 32 | 'row_2' => array( | |
| 33 | 'columns' => 3, | |
| 34 | 'width_1' => 25, | |
| 35 | 'width_2' => 50, | |
| 36 | 'width_3' => 25, | |
| 37 | 'names' => array(t('Left'), t('Middle'), t('Right')), | |
| 38 | ), | |
| 39 | // row 3 | |
| 40 | 'row_3' => array( | |
| 41 | 'columns' => 1, | |
| 42 | 'width_1' => 100, | |
| 43 | 'names' => array(t('Bottom')), | |
| 44 | ), | |
| 45 | 'sidebars' => array( | |
| 46 | 'left' => FALSE, | |
| 47 | 'left_width' => 200, | |
| 48 | 'right' => FALSE, | |
| 49 | 'right_width' => 200, | |
| 50 | 'width_type' => 'px', | |
| 51 | ), | |
| 52 | ); | |
| 53 | } | |
| 54 | ||
| 55 | function panels_flexible_settings_form($display, $layout, $settings) { | |
| 56 | if (empty($settings)) { | |
| 57 | // default for a new flexible layout | |
| 58 | $settings = panels_flexible_default_panels(); | |
| 59 | } | |
| 60 | ||
| 61 | // Special check for updating: | |
| 62 | if (empty($settings['width_type'])) { | |
| 63 | $settings['width_type'] = '%'; | |
| 64 | $settings['percent_width'] = 100; | |
| 65 | $settings['sidebars']['left'] = FALSE; | |
| 66 | $settings['sidebars']['left_width'] = 200; | |
| 67 | $settings['sidebars']['right'] = FALSE; | |
| 68 | $settings['sidebars']['right_width'] = 200; | |
| 69 | $settings['sidebars']['width_type'] = 'px'; | |
| 70 | } | |
| 71 | ||
| 72 | $form['instructions'] = array( | |
| 73 | '#value' => t('<p>Here you may determine the number of rows and columns your layout may have. Each row can have its own number of columns, and each column can have its width set independently. When changing the number of rows or columns, click Save to update the form so you can set the widths for new cells properly.</p><p><strong>Note: Removing cells which contain panes will cause those panes to be disappear. Please move any content you wish to keep.</strong></p>'), | |
| 74 | ); | |
| 75 | ||
| 76 | $form['width_type'] = array( | |
| 77 | '#type' => 'select', | |
| 78 | '#title' => t('Width unit type'), | |
| 79 | '#options' => array('%' => t('% (percentage)'), 'px' => t('px (pixels)'), 'em' => t('em (current)')), | |
| 80 | '#description' => t('The width unit type this layout can have: %, px or em. When using percentage, your layout will be fluid; when using px or em, your layout will be fixed.'), | |
| 81 | '#default_value' => $settings['width_type'], | |
| 82 | ); | |
| 83 | ||
| 84 | $form['percent_width'] = array( | |
| 85 | '#type' => 'textfield', | |
| 86 | '#size' => 2, | |
| 87 | '#width' => 10, | |
| 88 | '#title' => t('Total width'), | |
| 89 | '#description' => t('If using the percentage width, choose the total width that this layout must add up to; if you are having problems with your flexible layout having columns fall off, try lowering this number and adjusting the width of individual columns to match.'), | |
| 90 | '#default_value' => $settings['percent_width'], | |
| 91 | ); | |
| 92 | ||
| 93 | $form['rows'] = array( | |
| 94 | '#type' => 'textfield', | |
| 95 | '#size' => 2, | |
| 96 | '#width' => 10, | |
| 97 | '#title' => t('Rows'), | |
| 98 | '#description' => t('The number of rows this layout can have.'), | |
| 99 | '#default_value' => $settings['rows'], | |
| 100 | ); | |
| 101 | ||
| 102 | for ($row = 1; $row <= intval($settings['rows']); $row++) { | |
| 103 | $form["row_$row"] = array( | |
| 104 | '#type' => 'fieldset', | |
| 105 | '#title' => t('Row @d', array('@d' => $row)), | |
| 106 | ); | |
| 107 | $form["row_$row"]["columns"] = array( | |
| 108 | '#prefix' => '<div style="float: left; padding-right: 2em">', | |
| 109 | '#suffix' => '</div>', | |
| 110 | '#type' => 'textfield', | |
| 111 | '#size' => 2, | |
| 112 | '#width' => 10, | |
| 113 | '#title' => t('Columns'), | |
| 114 | // '#description' => t('The number of columns in row @d.', array('@d' => $row)), | |
| 115 | '#default_value' => $settings["row_$row"]["columns"], | |
| 116 | ); | |
| 117 | for ($col = 1; $col <= intval($settings["row_$row"]["columns"]); $col++) { | |
| 6c09ec8c | 118 | $form["row_$row"]["width_$col"] = array( |
| f2e5a0c5 EM |
119 | '#prefix' => '<div style="float: left; padding-right: 2em">', |
| 120 | '#suffix' => '</div>', | |
| 121 | '#type' => 'textfield', | |
| 122 | '#size' => 2, | |
| 123 | '#width' => 10, | |
| 124 | '#title' => t('Width @d', array('@d' => $col)), | |
| 125 | '#default_value' => $settings["row_$row"]["width_$col"], | |
| 126 | ); | |
| 127 | } | |
| 128 | if (is_array($settings["row_$row"]["names"])) { | |
| 129 | $names = implode(', ', $settings["row_$row"]["names"]); | |
| 130 | } | |
| 131 | else { | |
| 132 | $names = ''; | |
| 133 | } | |
| 134 | $form["row_$row"]['names'] = array( | |
| 135 | '#prefix' => '<div style="float: left;">', | |
| 136 | '#suffix' => '</div>', | |
| 137 | '#type' => 'textfield', | |
| 138 | '#title' => t('Column titles, separated by commas'), | |
| 139 | '#default_value' => $names, | |
| 140 | ); | |
| 141 | } | |
| 142 | ||
| 143 | $form['sidebars'] = array( | |
| 144 | '#type' => 'fieldset', | |
| 145 | '#title' => t('Sidebars'), | |
| 146 | ); | |
| 147 | ||
| 148 | $form['sidebars']['left_aligner_start'] = array( | |
| 149 | '#value' => '<div class="option-text-aligner">', | |
| 150 | '#tree' => TRUE, | |
| 151 | ); | |
| 152 | $form['sidebars']['left'] = array( | |
| 153 | '#type' => 'checkbox', | |
| 154 | '#id' => 'sidebar-left-checkbox', | |
| 155 | '#title' => t('Sidebar left'), | |
| 156 | '#default_value' => $settings['sidebars']['left'], | |
| 157 | ); | |
| 158 | $form['sidebars']['left_width'] = array( | |
| 159 | '#type' => 'textfield', | |
| 160 | '#id' => 'sidebar-left-width', | |
| 161 | '#size' => 2, | |
| 162 | '#width' => 10, | |
| 163 | '#default_value' => $settings['sidebars']['left_width'], | |
| 164 | ); | |
| 165 | $form['sidebars']['right'] = array( | |
| 166 | '#type' => 'checkbox', | |
| 167 | '#id' => 'sidebar-right-checkbox', | |
| 168 | '#title' => t('Sidebar right'), | |
| 169 | '#default_value' => $settings['sidebars']['right'], | |
| 170 | ); | |
| 171 | ||
| 172 | $form['sidebars']['right_width'] = array( | |
| 173 | '#type' => 'textfield', | |
| 174 | '#id' => 'sidebar-right-width', | |
| 175 | '#size' => 2, | |
| 176 | '#width' => 10, | |
| 177 | '#default_value' => $settings['sidebars']['right_width'], | |
| 178 | ); | |
| 179 | $form['sidebars']['left_aligner_stop'] = array( | |
| 180 | '#value' => '</div><div style="clear: both; padding: 0; margin: 0"></div>', | |
| 181 | ); | |
| 182 | $form['sidebars']['left_title_markup'] = array( | |
| 183 | '#prefix' => '<div class="description">', | |
| 184 | '#suffix' => '</div>', | |
| 185 | '#value' => t('If a sidebar is selected, enter the width of the sidebar.'), | |
| 186 | ); | |
| 187 | ||
| 188 | $form['sidebars']['width_type'] = array( | |
| 189 | '#type' => 'select', | |
| 190 | '#title' => t('Width unit type'), | |
| 191 | '#options' => array('%' => t('% (percentage)'), 'px' => t('px (pixels)'), 'em' => t('em (current)')), | |
| 192 | '#description' => t('The width unit type activated sidebars will have: %, px or em. When using percentage, your sidebars will be fluid; when using px or em, your sidebars will be fixed.'), | |
| 193 | '#default_value' => $settings['sidebars']['width_type'], | |
| 194 | ); | |
| 195 | ||
| 196 | $js_settings = array('panels' => array('checkboxes' => array( | |
| 197 | '#sidebar-left-checkbox' => array('#sidebar-left-width'), | |
| 198 | '#sidebar-right-checkbox' => array('#sidebar-right-width'), | |
| 199 | ))); | |
| 6c09ec8c EM |
200 | // not needed, automatically happens on the layout settings page. |
| 201 | // drupal_add_js(panels_get_path('js/checkboxes.js')); | |
| f2e5a0c5 EM |
202 | drupal_add_js($js_settings, 'setting'); |
| 203 | return $form; | |
| 204 | } | |
| 205 | ||
| 206 | function panels_flexible_settings_validate($values, $form, $display, $layout, $settings) { | |
| 6c09ec8c EM |
207 | if (empty($settings)) { |
| 208 | $settings = panels_flexible_default_panels(); | |
| 209 | } | |
| 210 | ||
| f2e5a0c5 EM |
211 | if ($values['rows'] < 1) { |
| 212 | form_error($form['rows'], t('Rows must be a positive integer.')); | |
| 213 | return; | |
| 214 | } | |
| 215 | ||
| 216 | // Validate that percentages add up to the stated maximum. | |
| dd58fceb | 217 | if ($values['width_type'] == '%') { |
| f2e5a0c5 EM |
218 | for ($row = 1; $row <= intval($values['rows']); $row++) { |
| 219 | // This takes into account whether or even had a previous setting here. | |
| 220 | if ($settings['rows'] >= $row) { | |
| 221 | if ($values["row_$row"]['columns'] < 1) { | |
| 222 | form_error($form["row_$row"]['columns'], t('Columns must be a positive integer.')); | |
| 223 | return; | |
| 224 | } | |
| 225 | $total = 0; | |
| 226 | for ($col = 1; $col <= intval($values["row_$row"]["columns"]); $col++) { | |
| 227 | $total += $values["row_$row"]["width_$col"]; | |
| 228 | } | |
| 7ac7b2cb EM |
229 | if ($total != $values['percent_width']) { |
| 230 | form_error($form["row_$row"]['columns'], t('Column widths must add up to @count.', array('@count' => $values['percent_width']))); | |
| f2e5a0c5 EM |
231 | } |
| 232 | } | |
| 233 | } | |
| 234 | } | |
| 235 | } | |
| 236 | ||
| 237 | function panels_flexible_settings_submit(&$values, $display, $layout, $settings) { | |
| 6c09ec8c EM |
238 | if (empty($settings)) { |
| 239 | $settings = panels_flexible_default_panels(); | |
| 240 | } | |
| 241 | ||
| f2e5a0c5 EM |
242 | for ($row = 1; $row <= $values['rows']; $row++) { |
| 243 | if ($row > $settings['rows'] && empty($values["row_$row"]['columns'])) { | |
| 244 | $values["row_$row"]['columns'] = 1; | |
| 245 | $values["row_$row"]['width_1'] = 100; | |
| 246 | } | |
| 247 | if (!empty($values["row_$row"]['names'])) { | |
| 248 | $names = explode(',', $values["row_$row"]['names']); | |
| 249 | foreach ($names as $nid => $name) { | |
| 250 | $names[$nid] = trim($name); | |
| 251 | } | |
| 252 | $values["row_$row"]['names'] = $names; | |
| 253 | } | |
| 254 | } | |
| 255 | } | |
| 256 | ||
| 257 | /** | |
| 258 | * Define the actual list of columns and rows for this flexible panel. | |
| 259 | */ | |
| 260 | function panels_flexible_panels($display, $settings) { | |
| 261 | $panels = array(); | |
| 262 | if (empty($settings)) { | |
| 263 | $settings = panels_flexible_default_panels(); | |
| 264 | } | |
| 265 | ||
| 266 | if (!empty($settings['sidebars']['left'])) { | |
| 267 | $panels['sidebar_left'] = t('Left sidebar'); | |
| 268 | } | |
| 269 | ||
| 270 | if (!empty($settings['sidebars']['right'])) { | |
| 271 | $panels['sidebar_right'] = t('Right sidebar'); | |
| 272 | } | |
| 273 | ||
| 274 | for ($row = 1; $row <= intval($settings['rows']); $row++) { | |
| 275 | for ($col = 1; $col <= intval($settings["row_$row"]['columns']); $col++) { | |
| 276 | if (!empty($settings["row_$row"]['names'][$col - 1])) { | |
| 277 | $panels["row_${row}_$col"] = $settings["row_$row"]['names'][$col - 1]; | |
| 278 | } | |
| 279 | else { | |
| 280 | $panels["row_${row}_$col"] = t("Row @row, Column @col", array('@row' => $row, '@col' => $col)); | |
| 281 | } | |
| 282 | } | |
| 283 | } | |
| 284 | return $panels; | |
| 285 | } | |
| 286 | ||
| 287 | /** | |
| 288 | * This function uses heredoc notation to make it easier to convert | |
| 289 | * to a template. | |
| 290 | */ | |
| 291 | function theme_panels_flexible($id, $content, $settings) { | |
| 292 | if (empty($settings)) { | |
| 293 | $settings = panels_flexible_default_panels(); | |
| 294 | } | |
| 295 | ||
| 296 | // Special check for updating. | |
| 297 | if (empty($settings['width_type'])) { | |
| 298 | $settings['width_type'] = '%'; | |
| 299 | $settings['percent_width'] = 100; | |
| 300 | } | |
| 301 | ||
| 302 | if ($id) { | |
| 303 | $idstr = " id='$id'"; | |
| 304 | $idcss = "#$id"; | |
| 305 | } | |
| 306 | else { | |
| 6c09ec8c | 307 | $idstr = ''; |
| f2e5a0c5 EM |
308 | $idcss = "div.panel-flexible"; |
| 309 | } | |
| 310 | ||
| 311 | $css = ''; | |
| 312 | $output = ''; | |
| 313 | ||
| 314 | for ($row = 1; $row <= intval($settings['rows']); $row++) { | |
| 315 | $output .= "<div class=\"panel-row panel-row-$row clear-block\">\n"; | |
| 316 | for ($col = 1; $col <= intval($settings["row_$row"]["columns"]); $col++) { | |
| 317 | // We do a width reduction formula to help IE out a little bit. If width is 100%, we take 1% | |
| 318 | // off the total; by dividing by the # of columns, that gets us the reduction overall. | |
| 319 | $reduce = 0; | |
| 320 | if ($settings['width_type'] == '%' && $settings['percent_width'] == 100) { | |
| 321 | $reduce = 1 / $settings["row_$row"]["columns"]; | |
| 322 | } | |
| 323 | if ($col == 1) { | |
| 324 | if (intval($settings["row_$row"]["columns"]) == 1) { | |
| 325 | $class = 'panel-col-only'; | |
| 326 | } | |
| 327 | else { | |
| 328 | $class = 'panel-col-first'; | |
| 329 | } | |
| 330 | } | |
| 331 | elseif ($col == intval($settings["row_$row"]["columns"])) { | |
| 332 | $class = 'panel-col-last'; | |
| 333 | } | |
| 334 | else { | |
| 335 | $class = 'panel-col-inside'; | |
| 336 | } | |
| 337 | $output .= "<div class=\"panel-col panel-col-$col $class\">\n"; | |
| 338 | $output .= "<div class=\"inside\">" . $content["row_${row}_$col"] . "</div>\n"; | |
| 339 | $output .= "</div>\n"; // panel-col-$col | |
| 340 | $css .= "$idcss div.panel-row-$row div.panel-col-$col { width: " . ((intval($settings["row_$row"]["width_$col"])) - $reduce) . $settings["width_type"] ."; }\n"; | |
| 341 | } | |
| 342 | $output .= "</div>\n"; // panel-row-$row | |
| 343 | } | |
| 344 | ||
| 345 | // Add our potential sidebars | |
| 346 | if (!empty($settings['sidebars']['left']) || !empty($settings['sidebars']['right'])) { | |
| 347 | // provide a wrapper if we have a sidebar | |
| 348 | $output = "<div class=\"panel-sidebar-middle panel-sidebar\">\n$output</div>\n"; | |
| 349 | if ($settings['sidebars']['width_type'] == '%') { | |
| 350 | $css .= "$idcss div.panel-flexible-sidebars div.panel-sidebar-middle { width: " . (intval($settings['percent_width']) - intval($settings['sidebars']['left_width']) - intval($settings['sidebars']['right_width'])) . "; }\n"; | |
| 351 | } | |
| 352 | } | |
| 353 | ||
| 354 | if (!empty($settings['sidebars']['left'])) { | |
| 355 | $size = intval($settings['sidebars']['left_width']) . $settings['sidebars']['width_type']; | |
| 356 | $output = "<div class=\"panel-sidebar panel-sidebar-left panel-col panel-col-first\"><div class=\"inside\">\n" . $content["sidebar_left"] . "</div>\n</div>\n" . $output; | |
| 357 | $css .= "$idcss div.panel-flexible-sidebars div.panel-sidebar-left { width: $size; margin-left: -$size; }\n"; | |
| 358 | $css .= "$idcss div.panel-flexible-sidebars { padding-left: $size; }\n"; | |
| 359 | // IE hack | |
| 360 | $css .= "* html $idcss div.panel-flexible-sidebars div.panel-sidebar-left { left: $size; }\n"; | |
| 361 | } | |
| 362 | ||
| 363 | if (!empty($settings['sidebars']['right'])) { | |
| 364 | $size = intval($settings['sidebars']['right_width']) . $settings['sidebars']['width_type']; | |
| 365 | $output .= "<div class=\"panel-sidebar panel-sidebar-right panel-col panel-col-last\"><div class=\"inside\">\n" . $content["sidebar_right"] . "</div>\n</div>\n"; | |
| 366 | $css .= "$idcss div.panel-flexible-sidebars div.panel-sidebar-right { width: $size; margin-right: -$size; }\n"; | |
| 367 | $css .= "$idcss div.panel-flexible-sidebars { padding-right: $size; }\n"; | |
| 368 | } | |
| 369 | ||
| 370 | // Wrap the whole thing up nice and snug | |
| 371 | $output = "<div class=\"panel-flexible clear-block\" $idstr>\n<div class=\"panel-flexible-sidebars\">\n" . $output . "</div>\n</div>\n"; | |
| 372 | drupal_set_html_head("<style type=\"text/css\" media=\"all\">\n$css</style>\n"); | |
| 373 | return $output; | |
| 374 | } | |
| 375 |