[Dojo-checkins] cal - r3712 - in trunk: src/widget
src/widget/templates tests/widget
dojo-checkins-admin at dojotoolkit.org
dojo-checkins-admin at dojotoolkit.org
Sat Apr 29 15:11:04 MDT 2006
Author: cal
Date: Sat Apr 29 15:11:04 2006
New Revision: 3712
Added:
trunk/tests/widget/test_Menu2_Bar.html (contents, props changed)
Modified:
trunk/src/widget/Menu2.js
trunk/src/widget/templates/HtmlMenu2.css
Log:
added a menu bar widget to simulate window menus
Modified: trunk/src/widget/Menu2.js
==============================================================================
--- trunk/src/widget/Menu2.js (original)
+++ trunk/src/widget/Menu2.js Sat Apr 29 15:11:04 2006
@@ -2,6 +2,7 @@
dojo.provide("dojo.widget.html.Menu2");
dojo.provide("dojo.widget.PopupMenu2");
dojo.provide("dojo.widget.MenuItem2");
+dojo.provide("dojo.widget.MenuBar2");
dojo.require("dojo.html");
dojo.require("dojo.style");
@@ -33,6 +34,7 @@
currentSubmenu: null,
currentSubmenuTrigger: null,
parentMenu: null,
+ parentMenuBar: null,
isShowingNow: false,
menuX: 0,
menuY: 0,
@@ -317,6 +319,10 @@
this.hide();
this.isShowingNow = false;
dojo.widget.html.Menu2Manager.closed(this);
+
+ if (this.parentMenuBar){
+ this.parentMenuBar.closedMenu(this);
+ }
},
onShow: function() {
@@ -860,7 +866,320 @@
}
};
+
+dojo.widget.MenuBar2 = function(){
+ dojo.widget.HtmlWidget.call(this);
+}
+
+dojo.inherits(dojo.widget.MenuBar2, dojo.widget.HtmlWidget);
+
+dojo.lang.extend(dojo.widget.MenuBar2, {
+ widgetType: "MenuBar2",
+ isContainer: true,
+
+ snarfChildDomOutput: true,
+
+ currentItem: null,
+ isExpanded: false,
+
+ currentSubmenu: null,
+ currentSubmenuTrigger: null,
+
+ domNode: null,
+ containerNode: null,
+
+ templateString: '<div class="dojoMenuBar2"><div dojoAttachPoint="containerNode" class="dojoMenuBar2Client"></div></div>',
+ templateCssPath: dojo.uri.dojoUri("src/widget/templates/HtmlMenu2.css"),
+
+ itemHeight: 18,
+ openEvent: null,
+
+
+ postCreate: function(){
+
+ // do something here
+
+ this.layoutMenuSoon();
+ },
+
+ layoutMenuSoon: function(){
+ dojo.lang.setTimeout(this, "layoutMenu", 0);
+ },
+
+ layoutMenu: function(){
+
+ // menu must be attached to DOM for size calculations to work
+
+ var parent = this.domNode.parentNode;
+ if (! parent || parent == undefined) {
+ document.body.appendChild(this.domNode);
+ }
+
+
+ // determine menu height
+
+ var max_label_h = 0;
+
+ for(var i=0; i<this.children.length; i++){
+
+ if (this.children[i].getLabelHeight){
+
+ max_label_h = Math.max(max_label_h, this.children[i].getLabelHeight());
+ }
+ }
+
+ if (isNaN(max_label_h)){
+ // Browser needs some more time to calculate sizes
+ this.layoutMenuSoon();
+ return;
+ }
+
+ var clientLeft = dojo.style.getPixelValue(this.domNode, "padding-left", true)
+ + dojo.style.getPixelValue(this.containerNode, "margin-left", true)
+ + dojo.style.getPixelValue(this.containerNode, "padding-left", true);
+ var clientTop = dojo.style.getPixelValue(this.domNode, "padding-top", true)
+ + dojo.style.getPixelValue(this.containerNode, "padding-top", true);
+
+ if (isNaN(clientLeft) || isNaN(clientTop)){
+ // Browser needs some more time to calculate sizes
+ this.layoutMenuSoon();
+ return;
+ }
+
+ var max_item_height = 0;
+ var x = clientLeft;
+
+ for (var i=0; i<this.children.length; i++){
+
+ var ch = this.children[i];
+
+ ch.layoutItem(max_label_h);
+
+ ch.leftPosition = x;
+ ch.domNode.style.left = x + 'px';
+
+ x += dojo.style.getOuterWidth(ch.domNode);
+ max_item_height = Math.max(max_item_height, dojo.style.getOuterHeight(ch.domNode));
+ }
+
+ dojo.style.setContentHeight(this.containerNode, max_item_height);
+ dojo.style.setContentHeight(this.domNode, dojo.style.getOuterHeight(this.containerNode));
+ },
+
+ openSubmenu: function(submenu, from_item){
+
+ var our_pos = dojo.style.getAbsolutePosition(this.domNode, false);
+
+ var our_h = dojo.style.getOuterHeight(this.domNode);
+ var item_x = from_item.leftPosition;
+
+ var x = our_pos.x + item_x;
+ var y = our_pos.y + our_h;
+
+ this.currentSubmenu = submenu;
+ this.currentSubmenu.open(x, y, this, from_item.domNode);
+ this.currentSubmenu.parentMenuBar = this;
+ },
+
+ closeSubmenu: function(){
+
+ if (this.currentSubmenu == null){ return; }
+
+ var menu = this.currentSubmenu;
+ this.currentSubmenu = null;
+ menu.close();
+ },
+
+ itemHover: function(item){
+
+ if (item == this.currentItem) return;
+
+ if (this.currentItem){
+ this.currentItem.unhighlightItem();
+
+ if (this.isExpanded){
+ this.closeSubmenu();
+ }
+ }
+
+ this.currentItem = item;
+ this.currentItem.highlightItem();
+
+ if (this.isExpanded){
+ this.currentItem.expandMenu();
+ }
+ },
+
+ itemUnhover: function(item){
+
+ if (item != this.currentItem) return;
+
+ if (!this.isExpanded){
+ this.currentItem.unhighlightItem();
+ this.currentItem = null;
+ }
+ },
+
+ itemClick: function(item){
+
+ if (item != this.currentItem){
+
+ this.itemHover(item);
+ }
+
+ if (this.isExpanded){
+
+ this.isExpanded = false;
+ this.closeSubmenu();
+
+ }else{
+
+ this.isExpanded = true;
+ this.currentItem.expandMenu();
+ }
+ },
+
+ closedMenu: function(menu){
+
+ if (this.currentSubmenu == menu){
+
+ this.isExpanded = false;
+ this.itemUnhover(this.currentItem);
+ }
+ }
+});
+
+
+dojo.widget.MenuBarItem2 = function(){
+ dojo.widget.HtmlWidget.call(this);
+}
+
+dojo.inherits(dojo.widget.MenuBarItem2, dojo.widget.HtmlWidget);
+
+dojo.lang.extend(dojo.widget.MenuBarItem2, {
+
+ widgetType: "MenuBarItem2",
+ templateString:
+ '<div class="dojoMenuBarItem2">'
+ +'<span dojoAttachPoint="labelNode" class="dojoMenuBarItem2Label"><span><span></span></span></span>'
+ +'<div dojoAttachPoint="targetNode" class="dojoMenuBarItem2Target" dojoAttachEvent="onMouseOver: onHover; onMouseOut: onUnhover; onClick: _onClick;"> </div>'
+ +'</div>',
+
+ //
+ // nodes
+ //
+
+ domNode: null,
+ labelNode: null,
+ targetNode: null,
+
+ //
+ // internal settings
+ //
+
+ is_hovering: false,
+ hover_timer: null,
+ is_open: false,
+
+ //
+ // options
+ //
+
+ caption: 'Untitled',
+ accelKey: '',
+ iconSrc: '',
+ submenuId: '',
+ disabled: false,
+ eventNaming: "default",
+
+
+ postCreate: function(){
+
+ dojo.html.disableSelection(this.domNode);
+
+ if (this.disabled){
+ this.setDisabled(true);
+ }
+
+ this.labelNode.childNodes[0].appendChild(document.createTextNode(this.caption));
+
+ this.labelShadowNode = this.labelNode.childNodes[0].childNodes[0];
+ this.labelShadowNode.appendChild(document.createTextNode(this.caption));
+
+ if (this.eventNaming == "default") {
+ for (eventName in this.eventNames) {
+ this.eventNames[eventName] = this.widgetId+"/"+eventName;
+ }
+ }
+ },
+
+ layoutItem: function(item_h){
+
+ var label_w = dojo.style.getOuterWidth(this.labelNode);
+
+ var clientLeft = dojo.style.getPixelValue(this.domNode, "padding-left", true);
+ var clientTop = dojo.style.getPixelValue(this.domNode, "padding-top", true);
+
+ this.labelNode.style.left = clientLeft + 'px';
+
+ dojo.style.setOuterHeight(this.labelNode, item_h);
+ dojo.style.setContentWidth(this.domNode, label_w);
+ dojo.style.setContentHeight(this.domNode, item_h);
+
+ this.labelNode.style.left = '0px';
+
+ dojo.style.setOuterWidth(this.targetNode, label_w);
+ dojo.style.setOuterHeight(this.targetNode, item_h);
+ },
+
+ getLabelHeight: function(){
+
+ return dojo.style.getOuterHeight(this.labelNode);
+ },
+
+ onHover: function(){
+ this.parent.itemHover(this);
+ },
+
+ onUnhover: function(){
+ this.parent.itemUnhover(this);
+ },
+
+ _onClick: function(){
+ this.parent.itemClick(this);
+ },
+
+ highlightItem: function(){
+ dojo.html.addClass(this.domNode, 'dojoMenuBarItem2Hover');
+ },
+
+ unhighlightItem: function(){
+ dojo.html.removeClass(this.domNode, 'dojoMenuBarItem2Hover');
+ },
+
+ expandMenu: function(){
+
+ var submenu = dojo.widget.getWidgetById(this.submenuId);
+ if (submenu){
+
+ this.parent.openSubmenu(submenu, this);
+ }
+ },
+
+ setDisabled: function(value){
+ this.disabled = value;
+
+ if (this.disabled){
+ dojo.html.addClass(this.domNode, 'dojoMenuBarItem2Disabled');
+ }else{
+ dojo.html.removeClass(this.domNode, 'dojoMenuBarItem2Disabled');
+ }
+ }
+});
+
// make it a tag
+dojo.widget.tags.addParseTreeHandler("dojo:MenuBar2");
+dojo.widget.tags.addParseTreeHandler("dojo:MenuBarItem2");
dojo.widget.tags.addParseTreeHandler("dojo:PopupMenu2");
dojo.widget.tags.addParseTreeHandler("dojo:MenuItem2");
dojo.widget.tags.addParseTreeHandler("dojo:MenuSeparator2");
Modified: trunk/src/widget/templates/HtmlMenu2.css
==============================================================================
--- trunk/src/widget/templates/HtmlMenu2.css (original)
+++ trunk/src/widget/templates/HtmlMenu2.css Sat Apr 29 15:11:04 2006
@@ -105,8 +105,6 @@
z-index: 10;
font-size: 1px;
background-image: url('images/transparent.gif');
- cursor: pointer;
- _cursor: hand;
}
.dojoMenuSeparator2 {
@@ -127,3 +125,78 @@
margin: 0px 2px;
font-size: 1px;
}
+
+
+
+.dojoMenuBar2 {
+ position: relative;
+ background-color: ThreeDFace;
+ border-bottom: 1px solid ThreeDHighlight;
+}
+
+.dojoMenuBar2Client {
+ padding: 1px;
+ border-top: 1px solid ThreeDHighlight;
+ border-bottom: 1px solid ThreeDShadow;
+}
+
+.dojoMenuBarItem2 {
+ position: absolute;
+ white-space: nowrap;
+ font: menu;
+ color: WindowText;
+ margin: 0;
+}
+
+.dojoMenuBarItem2 span {
+ margin: 0;
+}
+
+.dojoMenuBarItem2Target {
+ position: absolute;
+ z-index: 10;
+ font-size: 1px;
+ background-image: url('images/transparent.gif');
+}
+
+.dojoMenuBarItem2Label {
+ position: absolute;
+ vertical-align: middle;
+ z-index: 1;
+ padding: 3px 8px;
+}
+
+.dojoMenuBarItem2Label span {
+ position: relative;
+ z-index: 2;
+}
+
+.dojoMenuBarItem2Label span span {
+ position: absolute;
+ color: ThreeDHighlight;
+ display: none;
+ left: 1px;
+ top: 1px;
+ z-index: -2;
+}
+
+.dojoMenuBarItem2Hover {
+ background-color: Highlight;
+ color: HighlightText;
+}
+
+.dojoMenuBarItem2Disabled .dojoMenuBarItem2Label span,
+.dojoMenuBarItem2Disabled .dojoMenuBarItem2Accel span {
+ color: ThreeDShadow;
+}
+
+.dojoMenuBarItem2Disabled .dojoMenuBarItem2Label span span,
+.dojoMenuBarItem2Disabled .dojoMenuBarItem2Accel span span {
+ color: ThreeDHighlight;
+ display: block;
+}
+
+.dojoMenuBarItem2Hover .dojoMenuBarItem2Label span span,
+.dojoMenuBarItem2Hover .dojoMenuBarItem2Accel span span {
+ display: none;
+}
Added: trunk/tests/widget/test_Menu2_Bar.html
==============================================================================
--- (empty file)
+++ trunk/tests/widget/test_Menu2_Bar.html Sat Apr 29 15:11:04 2006
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>Menu System Test</title>
+<script type="text/javascript">
+
+ var djConfig = {
+ debugAtAllCosts: true,
+ isDebug: true
+ };
+
+</script>
+<script type="text/javascript" src="../../dojo.js"></script>
+<script type="text/javascript">
+ dojo.require("dojo.widget.Menu2");
+ dojo.require("dojo.fx.html");
+ dojo.hostenv.writeIncludes();
+</script>
+</head>
+<body style="background-color: #3A6EA5; color: white; padding: 0; margin: 0">
+
+<div dojoType="PopupMenu2" widgetId="submenu1" contextMenuForWindow="true">
+ <div dojoType="MenuItem2" caption="One" submenuId="submenu2" disabled="true"></div>
+ <div dojoType="MenuItem2" caption="Two" submenuId="submenu2"></div>
+</div>
+
+<div dojoType="PopupMenu2" widgetId="submenu2">
+ <div dojoType="MenuItem2" caption="Three" onClick="alert('Three!')"></div>
+ <div dojoType="MenuItem2" caption="Four" onClick="alert('Four!')"></div>
+</div>
+
+<div dojoType="MenuBar2">
+ <div dojoType="MenuBarItem2" caption="File" submenuId="submenu1"></div>
+ <div dojoType="MenuBarItem2" caption="Edit" submenuId="submenu2"></div>
+ <div dojoType="MenuBarItem2" caption="View" disabled="true"></div>
+ <div dojoType="MenuBarItem2" caption="Help" submenuId="submenu2"></div>
+</div>
+
+<div style="padding: 1em">
+
+ <h1>This page has a menu bar and context menu</h1>
+
+ <h2>Contextmenu should always apear within browser window, no scrolling needed</h2>
+
+ <h3 style="color: yellow;">In Opera, press ctrl-button while clicking. This is needed as opera doesn't support right-click events</h3>
+
+ <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus risus. Praesent eu lacus et enim laoreet sollicitudin. Quisque mollis mi a lectus. Cras ante. Aliquam tempus justo laoreet justo. Vestibulum egestas feugiat nisi. Nulla ultrices consequat felis. Curabitur dignissim augue vel enim. Fusce tempus tempor mauris. Praesent suscipit pede in nunc. Duis mi neque, malesuada non, volutpat et, nonummy et, ante. Aliquam neque. Nulla rhoncus, turpis eget mattis molestie, magna nulla dictum ligula, quis tempor odio justo vel pede. Donec sit amet tellus. Phasellus sapien. Nulla id massa at nunc condimentum fringilla. Fusce suscipit ipsum et lorem consequat pulvinar. Quisque lacinia sollicitudin tellus.</p>
+
+</div>
+
+</body>
+</html>
\ No newline at end of file
More information about the Dojo-checkins
mailing list