Hallo,
vielen Dank für euer Lob und eure Geduld. Ich musste mir ersteinmal 2 Wochen Urlaub gönnen 🙂.
Zur Händlersuche: Ja die Sache läuft über Längen- und Breitengrade. Eine entsprechende Extension werde ich bei Gelegenheit auch fertigstellen. Momentan ist die Ext noch zu "spezifisch". Falls es wichtig ist -> PN.
So habe den Code für das Menu mal etwas überarbeitet. Das ganz funtkioniert nach folgendem Prinzip:
Das Menu ist ein normales HMENU mit einem GMENU und mehreren TMENUs. Diese schicken über die IProcFunc Function ihre Information an ein eigenes PHP Skript, welches die Informationen umwandelt und den nötigen JS Code erzeugt. Die Tiefe ist dabei beliebig erweiterbar.
// Achtung!
Das gesamte Skript ist genau an die Bedürfnisse der Meade Seite angepasst und nicht sehr flexibel. Es klappt momentan also "nur" mit einem horizontalen GMENU und mehreren TMENUs. Das soll sich zwar noch ändern, aber im aktuellen Stadium wird es wahrscheinlich nicht klappen (untested). Für Verbesserungsvorschläge bin ich immer offen 😉
Zuerst zum TS:
# include ypMenu script
page.includeLibs.ypMenu = fileadmin/.../ypMenu.php
...
lib.mainMenu >
lib.mainMenu = HMENU
lib.mainMenu.1 = GMENU
lib.mainMenu.1 {
IProcFunc = user_menu->firstLevel
expAll = 1
wrap = |
IFSUB = 1
IFSUB {
wrap = |
XY = [50.w]+20, 25
backColor = #cccccc
50 = TEXT
50 {
text.field = title
fontSize = 12
fontFile = fileadmin/xyz.ttf
fontColor = #222222
offset = 10,17
niceText = 1
}
100 = || IMAGE
100.file = fileadmin/spacer.gif
}
NO {
wrap = |
XY = [50.w]+20, 25
backColor = #cccccc
50 = TEXT
50 {
text.field = title
fontSize = 12
fontFile = xyz.ttf
fontColor = #222222
offset = 10,17
niceText = 1
}
100 = || IMAGE
100.file = fileadmin/spacer.gif
}
RO < lib.mainMenu.1.NO
RO = 1
RO {
backColor = #ffca51
}
IFSUBRO < lib.mainMenu.1.NO
IFSUBRO = 1
IFSUBRO {
backColor = #ffca51
}
}
lib.mainMenu.2 = TMENU
lib.mainMenu.2 {
IProcFunc = user_menu->secondLevel
expAll = 1
NO.linkWrap = <li>|</li>
}
lib.mainMenu.3 = TMENU
lib.mainMenu.3 {
IProcFunc = user_menu->thirdLevel
expAll = 1
NO.linkWrap = <li>|</li>
}
lib.mainMenu.4 = TMENU
lib.mainMenu.4 {
IProcFunc = user_menu->fourthLevel
expAll = 1
NO.linkWrap = <li>|</li>
}
...
# append Menu JS to page
page.11 = USER
page.11.userFunc = user_menu->menuEnd
Dann wird das ganze durch die ypMenu Datei gejagt:
<?php
/***************************************************************
* Copyright notice
*
* (c) 2003 Andreas Tschirpke (tschirpke@at-mediendesign.de)
* All rights reserved
*
* This script is part of the Typo3 project. The Typo3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
/**
* User class to build Javascript Menu (www.meade.de)
*
* @author Andreas Tschirpke <tschirpke@at-mediendesign.de>
*/
class user_menu {
var $offsetY = 70; // inital offset values for the first level elements
var $offsetX = 65;
var $sublevelWidth = 140; // width and height values for sublevel items
var $sublevelHeight = 26;
var $padding = 5;
var $fontSize = 11;
var $breakpoint = 14; // recalculate width of text after x characters
var $secPadding = 16;
var $fontFile = 'fileadmin/../verdana.ttf'; // font file needed to calculate linebreaks
var $transBg = 'fileadmin/../menu_bg.png'; // transparent PNG file - needed to fix a transparency bug in Mac IE 5
/**
* Dummy function to pass values to buildIndex
*
* @param array Menu array including all needed menu items (created by TMENU)
* @param array Configuration array
* @return array returns modified $I array
* @access private
*/
function firstLevel($I,$conf) {
return $this->buildIndex($I, $conf, 1);
}
/**
* Dummy function to pass values to buildIndex
*
* @param array Menu array including all needed menu items (created by TMENU)
* @param array Configuration array
* @return array returns modified $I array
* @access private
*/
function secondLevel($I,$conf) {
return $this->buildIndex($I, $conf, 2);
}
/**
* Dummy function to pass values to buildIndex
*
* @param array Menu array including all needed menu items (created by TMENU)
* @param array Configuration array
* @return array returns modified $I array
* @access private
*/
function thirdLevel($I,$conf) {
return $this->buildIndex($I, $conf, 3);
}
/**
* Dummy function to pass values to buildIndex
*
* @param array Menu array including all needed menu items (created by TMENU)
* @param array Configuration array
* @return array returns modified $I array
* @access private
*/
function fourthLevel($I, $conf) {
return $this->buildIndex($I, $conf, 4);
}
/**
* Returns true if there is a submenu with items for the page id, $uid
* Used by the item states "IFSUB" and "ACTIFSUB" to check if there is a submenu
*
* @param integer Page uid for which to search for a submenu
* @return boolean Returns true if there was a submenu with items found
* @access private
*/
// copy from tslib_menu
function isSubMenu($uid) {
// Looking for a mount-pid for this UID since if that exists we should look for a subpages THERE and not in the input $uid;
$mount_info = $GLOBALS['TSFE']->sys_page->getMountPointInfo($uid);
if (is_array($mount_info)) {
$uid = $mount_info['mount_pid'];
}
$recs = $GLOBALS['TSFE']->sys_page->getMenu($uid,'uid,pid,doktype,mount_pid,mount_pid_ol');
foreach($recs as $theRec) {
if (!t3lib_div::inList('5,6',$theRec['doktype']) && !$theRec['nav_hide']) { // If a menu item seems to be another type than 'Not in menu', then return true (there were items!)
return TRUE;
}
}
}
/**
* Breaks textarea text into lines of specified width in order to feed Gifbuilder (see function makeTextImage)
*
* @param string $text: input text
* @param integer $size: specified font size
* @param string $font: absolute path to specified font file
* @param integer $width: specified width of the image box
* @return array array of lines of text
*/
// copy from sr_sendcard
// thanks and credits go to Peter Bowyer <peter@sendcard.org>
function text_to_lines($text, $size, $font, $width) {
$words = t3lib_div::trimExplode(' ', str_replace("
", ' <br> ', str_replace("
", ' <br> ', str_replace("|", ' <br> ', $text))), 0);
$p = 0;
$lines = array();
$lines[0] = '';
for($i = 0; $i < count($words); $i++) {
($lines[$p] ) ? $test = $lines[$p].' '.$words[$i] : $test = $words[$i];
$bbox = imagettfbbox($size, 0, $font, $test);
if ($words[$i] == '<br>') {
$p++;
$lines[$p] = '';
} elseif (($bbox[4] - $bbox[6]) > $width ) {
$p++;
$lines[$p] = $words[$i];
} else {
$lines[$p] = $test;
}
}
return count($lines);
}
/**
* Collects all needed information (width, height, x, y, level etc.) and structural information for the ypMenu.
* Information are stored in $GLOBALS['TSFE']->applicationData['ypMenus']
*
* @param array $I: Array created by TMENU including all menu elements for the current level
* @param integer $conf: Configuration array
* @param integer $level: hierarchical depth
* @return array $I: modified $I array
*/
function buildIndex($I, $conf, $level) {
// fix IE 5.0 on windows
$clientAdjust = 0;
$clientinfo = t3lib_div::clientInfo();
if($clientinfo['SYSTEM'] == 'win' AND $clientinfo['BROWSER'] == 'msie' AND $clientinfo['VERSION'] < 5.5) {
$clientAdjust = 2;
}
switch($level) {
case "1":
// only wrap in ypSlide Action if submenu is present
if($this->isSubMenu($I['uid'])) {
// JS actions
$onmouseover = "ypSlideOutMenu.showMenu('menu" .$I['uid']. "'); over('" .$I['theName']. "');";
$onmouseout = "ypSlideOutMenu.hideMenu('menu" .$I['uid']. "');";// out('" .$I['theName']. "');";
// collect data for correct positions
$GLOBALS['TSFE']->applicationData['ypMenus'][$I['uid']]['level'] = $level;
$GLOBALS['TSFE']->applicationData['ypMenus'][$I['uid']]['uid'] = $I['uid'];
$GLOBALS['TSFE']->applicationData['ypMenus'][$I['uid']]['imgwidth'] = $I['val']['output_w'];
$GLOBALS['TSFE']->applicationData['ypMenus'][$I['uid']]['imgheight'] = $I['val']['output_h'];
$GLOBALS['TSFE']->applicationData['ypMenus'][$I['uid']]['width'] = $this->sublevelWidth;
$GLOBALS['TSFE']->applicationData['ypMenus'][$I['uid']]['height'] = $this->sublevelHeight;
$GLOBALS['TSFE']->applicationData['ypMenus'][$I['uid']]['dir'] = 'down';
$GLOBALS['TSFE']->applicationData['ypMenus'][$I['uid']]['top'] = $this->offsetY;
$GLOBALS['TSFE']->applicationData['ypMenus'][$I['uid']]['left'] = $GLOBALS['TSFE']->applicationData['ypTemp']['x'] + $this->offsetX;
// build ypMenu JS
$GLOBALS['TSFE']->applicationData['ypTemp']['js'] .= "
menu". $I['uid'] .".onactivate = new Function("document.images['" .$I['theName']. "'].src = " .$I['theName']. "_h.src");
menu". $I['uid'] .".ondeactivate = new Function("document.images['" .$I['theName']. "'].src = " .$I['theName']. "_n.src");
";
} else { // no ypMenu needed
$onmouseover = "over('" .$I['theName']. "');";
$onmouseout = "out('" .$I['theName']. "'); ";
}
// move right
$GLOBALS['TSFE']->applicationData['ypTemp']['x'] += $I['val']['output_w'];
$I['parts']['ATag_begin'] = '<a href="' .$I['linkHREF']['HREF']. '" onfocus="' . $I['linkHREF']['onFocus']. '" onmouseover="'. $onmouseover .'" onmouseout="'. $onmouseout .'" id="act'. $I['uid'] .'">';
$I['parts']['ATag_end'] = '</a>';
break;
default: // every other level (TMENU)
$title = $I['title'];
// count lines if more than $this->breakpoint chars
if(strlen($title) > $this->breakpoint) {
$lines = $this->text_to_lines($I['title'], t3lib_div::freetypeDpiComp($this->fontSize), $this->fontFile, ($this->sublevelWidth - 2*$this->padding));
} else {
$lines = 1;
}
// if another submenu is present wrap link with JS actions an collect data
if($this->isSubMenu($I['uid'])) {
$href = $I['linkHREF']['HREF'];
$onmouseover = "ypSlideOutMenu.showMenu('menu" .$I['uid']. "');";
$onmouseout = "ypSlideOutMenu.hideMenu('menu" .$I['uid']. "');";
$link = sprintf('<a href="%s" onmouseover="%s" onmouseout="%s" class="submenu">%s</a>',$href, $onmouseover, $onmouseout, $title);
$GLOBALS['TSFE']->applicationData['ypMenus'][$I['uid']]['level'] = $level;
$GLOBALS['TSFE']->applicationData['ypMenus'][$I['uid']]['uid'] = $I['uid'];
$GLOBALS['TSFE']->applicationData['ypMenus'][$I['uid']]['width'] = $this->sublevelWidth;
$GLOBALS['TSFE']->applicationData['ypMenus'][$I['uid']]['height'] = $this->sublevelHeight;
$GLOBALS['TSFE']->applicationData['ypMenus'][$I['uid']]['dir'] = 'right';
$GLOBALS['TSFE']->applicationData['ypMenus'][$I['uid']]['top'] = intval($GLOBALS['TSFE']->applicationData['ypMenus'][$I['pid']]['top']) + (($I['key']) * $this->sublevelHeight);
$GLOBALS['TSFE']->applicationData['ypMenus'][$I['uid']]['left'] = intval($GLOBALS['TSFE']->applicationData['ypMenus'][$I['pid']]['left']) + intval($GLOBALS['TSFE']->applicationData['ypMenus'][$I['pid']]['width']);
$GLOBALS['TSFE']->applicationData['ypMenus'][$I['uid']]['parentId'] = $I['pid'];
} else { // nothing to be done here :)
$link = $I['parts']['ATag_begin']. $title .$I['parts']['ATag_end'];
}
// move down
if($I['key'] == 0) {
$GLOBALS['TSFE']->applicationData['ypTemp'][$I['pid']]['y'] = intval($GLOBALS['TSFE']->applicationData['ypMenus'][$I['pid']]['top']);
} else {
$GLOBALS['TSFE']->applicationData['ypTemp'][$I['pid']]['y'] += $this->sublevelHeight + ($this->secPadding * ($lines-1)) + $clientAdjust;
}
$GLOBALS['TSFE']->applicationData['ypMenus'][$I['pid']]['items'][$I['uid']]['link'] = $link;
$GLOBALS['TSFE']->applicationData['ypMenus'][$I['pid']]['items'][$I['uid']]['height'] = $this->sublevelHeight + ($this->secPadding * ($lines-1));
$GLOBALS['TSFE']->applicationData['ypMenus'][$I['pid']]['items'][$I['uid']]['top'] = $GLOBALS['TSFE']->applicationData['ypTemp'][$I['pid']]['y'] - ($this->secPadding * ($lines-1));
// save link in output array
$I['parts']['ATag_begin'] = '
<a href="' .$I['linkHREF']['HREF']. '"
onfocus="' . $I['linkHREF']['onFocus']. '"
onMouseOver="ypSlideOutMenu.showMenu('menu'.$I['uid'].'');"
onMouseOut="ypSlideOutMenu.hideMenu('menu'.$I['uid'].'');"
id="level1id'.$I['uid'].'">';
//$GLOBALS['TSFE']->applicationData['ypMenu'][$level][$I['pid']]['parts']['items'][] = implode('', $I['parts']);
$I['parts'] = array();
break;
}
return $I;
}
/**
* Builds all HTML/JS Code to initialize all ypMenu layers. Must be writen at the end of the document
*
* @return string html/js code
*/
function menuEnd() {
// all relevant data stored in applicationData['ypMenus'];
if(is_array($GLOBALS["TSFE"]->applicationData['ypMenus'])) {
// fix differnet browser bugs to get a transparency effect
$clientinfo = t3lib_div::clientInfo();
$pngimg = false;
$pngbg = false;
$filter = false;
$appendix = '';
$bg = false;
// ie >= 5.5 on win and mozilla can render transparency by css
if(($clientinfo['SYSTEM'] == 'win' AND $clientinfo['BROWSER'] == 'msie' AND $clientinfo['VERSION'] >= 5.5) OR ($clientinfo['SYSTEM'] == 'win' AND $clientinfo['BROWSER'] == 'net')) {
$filter = true;
$style = 'style="-moz-opacity:.8; filter:alpha(opacity=80); background-color: #d3d3d3"';
// Mr. IE on Mac needs a special treatment - a transparent png in a img tag in the background
} elseif($clientinfo['SYSTEM'] == 'mac' AND ($clientinfo['BROWSER'] == 'msie')) {
$pngimg = true;
$style = 'style="background-color: transparent"';
// Opera and Mozilla on Mac can handle transparent pngs
} elseif(($clientinfo['SYSTEM'] == 'mac' AND $clientinfo['BROWSER'] == 'net') OR ($clientinfo['BROWSER'] == 'opera')){
$pngbg = true;
$style = 'style="background-image: url(''. $this->transBg .'');"';
// no transparency for the rest - go get firefox!
} else {
$bg = true;
$style = 'style="background-color: transparent"';
$appendix = 'b';
}
// loop through all collected data (buildIndex) and render js
foreach($GLOBALS["TSFE"]->applicationData['ypMenus'] as $menu) {
$uid = $menu['uid'];
$level = $menu['level'];
$dir = $menu['dir'];
$parentId = ($menu['parentId']) ? '"menu'.$menu['parentId'].'"' : 'null';
$x = $menu['left'];
$y = ($menu['parentId']) ? $GLOBALS['TSFE']->applicationData['ypMenus'][$menu['parentId']]['items'][$uid]['top'] : $this->offsetY;
$width = $menu['width'];
$items = '';
$wholeHeight = 0;
if(is_array($menu['items'])) {
$itemcount = count($menu['items']);
foreach($menu['items'] as $item) {
$items .= '<li>'. $item['link'] ."</li>
";
$wholeHeight = $wholeHeight + $item['height'];
}
}
if($clientinfo['SYSTEM'] == 'win' AND $clientinfo['BROWSER'] == 'msie' AND $clientinfo['VERSION'] < 5.5) {
$wholeHeight = $wholeHeight + 2 * $itemcount;
}
$height = ($menu['height']) * count($menu['items']);
$output[] = sprintf('<div id="menu%dContainer" class="mmContainer"><div id="menu%dContent" class="mmContent%s" %s>', $uid, $uid, $appendix, $style); // L%d / $level
$output[] = sprintf('<ul class="mmLevel%d">%s</ul>', $level, $items);
// trick Mac IE to display our transparent PNG
if($pngimg) {
$output[] = '<img src="' . $this->transBg .'" width="'. $width .'" height="'. $wholeHeight .'" class="menuBackground">';
}
$output[] = '</div></div>';
$menus[] = sprintf('menu%d = new ypSlideOutMenu("menu%d", "%s", %d, %d, %d, %d, %s)', $uid, $uid, $dir, $x, $y, $width, $wholeHeight, $parentId);
}
}
if(is_array($output) && is_array($menus)) {
$output = implode("
", $output);
d $output .= "
<script type="text/javascript">
"
. implode("
", $menus) ."
ypSlideOutMenu.writeCSS();
". $GLOBALS['TSFE']->applicationData['ypTemp']['js'] ."
</script>
";
return $output;
}
}
}
?>
So, dazu kommen natürlich noch die benötigten Javascript Dateien von youngpup.net und CSS Formatierungen. Das kann ich jetzt hier leider nicht alles wiedergeben, kann man sich jedoch zusammensuchen 🙂
Falls Fragen sind wagt es ja nicht mir eine PN zu schreiben 😉