[Dojo-checkins] bill - r3532 - in trunk: src src/widget src/widget/html tests/widget

dojo-checkins-admin at dojotoolkit.org dojo-checkins-admin at dojotoolkit.org
Fri Apr 14 11:05:07 MDT 2006


Author: bill
Date: Fri Apr 14 11:05:06 2006
New Revision: 3532

Added:
   trunk/src/layout.js
Removed:
   trunk/src/widget/html/LayoutContainer.js
Modified:
   trunk/src/widget/LayoutContainer.js
   trunk/tests/widget/test_LayoutContainer_2.html
Log:
Split layout code into a separate file so that it can be
used independently of LayoutContainer.  Also rewrote
the layout code; reduced the code size quite a bit.

I took out the minSize stuff because it needs to be
reworked anyway; maybe should be part of HtmlWidget.js?

Added: trunk/src/layout.js
==============================================================================
--- (empty file)
+++ trunk/src/layout.js	Fri Apr 14 11:05:06 2006
@@ -0,0 +1,85 @@
+/**
+ * Layout a bunch of child dom nodes within a parent dom node
+ * Input is an array of objects like:
+ * @ container - parent node
+ * @ layoutPriority - "top-bottom" or "left-right"
+ * @ children an array like [ {domNode: foo, layoutAlign: "bottom" }, {domNode: bar, layoutAlign: "client"} ]
+ */
+ 
+dojo.provide("dojo.layout");
+
+dojo.require("dojo.lang");
+dojo.require("dojo.style");
+
+dojo.layout = function(container, children, layoutPriority) {
+	// container has to be either relative or absolute position so that we
+	// can position nodes inside of it
+	if(container.style.position != "absolute"){
+		container.style.position = "relative";
+	}
+
+	// copy input array and remove elements w/out layout
+	children = dojo.lang.filter(children, function(child){
+		return dojo.lang.inArray(["top","bottom","left","right","client","flood"], child.layoutAlign)
+	});
+
+	// order the children according to layoutPriority
+	if(layoutPriority){
+		var rank = function(child){
+			switch(child.layoutAlign){
+				case "flood":
+					return 1;
+				case "left":
+				case "right":
+					return (layoutPriority=="left-right") ? 2 : 3;
+				case "top":
+				case "bottom":
+					return (layoutPriority=="left-right") ? 3 : 2;
+				default:
+					return 4;
+			}
+		};
+		children.sort(function(a,b){ return rank(a)-rank(b); });
+	}
+
+	// record the width/height of all the floating elements added so far (plus padding)
+	var usedSpace={
+		'left': dojo.style.getPixelValue(container, "padding-left", true),
+		'right': dojo.style.getPixelValue(container, "padding-right", true),
+		'top': dojo.style.getPixelValue(container, "padding-top", true),
+		'bottom': dojo.style.getPixelValue(container, "padding-bottom", true)
+	};
+
+	// track how much space is remaining
+	var remainingWidth  = dojo.style.getContentWidth(container);
+	var remainingHeight =  dojo.style.getContentHeight(container);
+
+	// set positions/sizes
+	dojo.lang.forEach(children, function(child){
+		var elm=child.domNode;
+		var position=child.layoutAlign;
+
+		// set two of left/right/top/bottom properties
+		elm.style.position="absolute";
+		var lr = (position=="right")?"right":"left";
+		elm.style[lr]=usedSpace[lr] + "px";
+		var tb = (position=="bottom")?"bottom":"top";
+		elm.style[tb]=usedSpace[tb] + "px";
+
+		// set size && adjust record of remaining space
+		if ( (position=="top")||(position=="bottom") ) {
+			dojo.style.setOuterWidth(elm, remainingWidth);
+			var h = dojo.style.getOuterHeight(elm);
+			usedSpace[position] += h;
+			remainingHeight -= h;
+		} else if(position=="left" || position=="right"){
+			dojo.style.setOuterHeight(elm, remainingHeight);
+			var w = dojo.style.getOuterWidth(elm);
+			usedSpace[position] += w;
+			remainingWidth -= w;
+		} else if(position=="flood" || position=="client"){
+			dojo.style.setOuterWidth(elm, remainingWidth);		
+			dojo.style.setOuterHeight(elm, remainingHeight);
+		}
+	});
+};
\ No newline at end of file

Modified: trunk/src/widget/LayoutContainer.js
==============================================================================
--- trunk/src/widget/LayoutContainer.js	(original)
+++ trunk/src/widget/LayoutContainer.js	Fri Apr 14 11:05:06 2006
@@ -1,7 +1,75 @@
+//
+// this widget provides Delphi-style panel layout semantics
+//
+
 dojo.provide("dojo.widget.LayoutContainer");
+dojo.provide("dojo.widget.html.LayoutContainer");
 
 dojo.require("dojo.widget.*");
-dojo.requireAfterIf("html", "dojo.widget.html.LayoutContainer");
-dojo.widget.tags.addParseTreeHandler("dojo:LayoutContainer");
+dojo.require("dojo.layout");
+
+dojo.widget.html.LayoutContainer = function(){
+	dojo.widget.HtmlWidget.call(this);
+}
+
+dojo.inherits(dojo.widget.html.LayoutContainer, dojo.widget.HtmlWidget);
+
+dojo.lang.extend(dojo.widget.html.LayoutContainer, {
+	widgetType: "LayoutContainer",
+	isContainer: true,
+
+	layoutChildPriority: 'top-bottom',
+
+	postCreate: function(){
+		debugger;
+		dojo.layout(this.domNode, this.children, this.layoutChildPriority);
+	},
+
+	addChild: function(child, overrideContainerNode, pos, ref, insertIndex){
+		dojo.widget.html.LayoutContainer.superclass.addChild.call(this, child, overrideContainerNode, pos, ref, insertIndex);
+		dojo.layout(this.domNode, this.children, this.layoutChildPriority);
+	},
 
-// NOTE: there's no stub file for this widget
+	removeChild: function(pane){
+		dojo.widget.html.LayoutContainer.superclass.removeChild.call(this,pane);
+		dojo.layout(this.domNode, this.children, this.layoutChildPriority);
+	},
+
+	onResized: function(){
+		if ( !this.isShowing() ) {
+			return;
+		}
+		
+		// TODO: this code should be somewhere else
+		var w = dojo.style.getOuterWidth(this.domNode);
+		var h = dojo.style.getOuterWidth(this.domNode);
+		if( h == this.height && w == this.width ) { return; }
+		this.height = h; this.width = w;
+
+		//dojo.debug(this.widgetId + ": resized to " + w + ", " + h);
+		dojo.layout(this.domNode, this.children, this.layoutChildPriority);
+
+		// notify children that they have been moved/resized
+		this.notifyChildrenOfResize();
+	},
+
+	show: function(){
+		// If this node was created while display=="none" then it
+		// hasn't been laid out yet.  Do that now.
+		this.domNode.style.display="";
+		this.onResized();
+		this.domNode.style.display="none";
+		this.domNode.style.visibility="";
+
+		dojo.widget.html.LayoutContainer.superclass.show.call(this);
+	}
+});
+
+// This argument can be specified for the children of a LayoutContainer.
+// Since any widget can be specified as a LayoutContainer child, mix it
+// into the base widget class.  (This is a hack, but it's effective.)
+dojo.lang.extend(dojo.widget.Widget, {
+	layoutAlign: 'none'
+});
+
+dojo.widget.tags.addParseTreeHandler("dojo:LayoutContainer");

Modified: trunk/tests/widget/test_LayoutContainer_2.html
==============================================================================
--- trunk/tests/widget/test_LayoutContainer_2.html	(original)
+++ trunk/tests/widget/test_LayoutContainer_2.html	Fri Apr 14 11:05:06 2006
@@ -15,14 +15,10 @@
 <script language="JavaScript" type="text/javascript">
 
 	dojo.require("dojo.widget.LayoutContainer");
+	dojo.require("dojo.widget.ContentPane");
 	dojo.require("dojo.widget.ResizeHandle");
 
 	dojo.hostenv.writeIncludes();
-
-	//dojo.addOnLoad(function(){
-	//	dojo.debug('status bar min width: '+dojo.widget.getWidgetById('statusBar').getMinWidth());
-	//	dojo.debug('window thing min width: '+dojo.widget.getWidgetById('mywindow').getMinWidth());
-	//});
 </script>
 <style>
 
@@ -52,15 +48,15 @@
 	minHeight="20"
 	style="border: 2px solid black; width: 90%; height: 200px;"
 >
-	<div dojoType="LayoutContainer" layoutAlign="bottom" class="statusBar" minHeight="28" widgetId="statusBar">
+	<div dojoType="LayoutContainer" layoutAlign="bottom" class="statusBar" style="height: 28px" widgetId="statusBar">
 
-		<div dojoType="LayoutContainer" layoutAlign="left" class="statusPanel">
+		<div dojoType="ContentPane" layoutAlign="left" class="statusPanel">
 			panel 1
 		</div>
-		<div dojoType="LayoutContainer" layoutAlign="left" class="statusPanel">
+		<div dojoType="ContentPane" layoutAlign="left" class="statusPanel">
 			panel 2
 		</div>
-		<div dojoType="LayoutContainer" layoutAlign="client" class="statusPanel" style="padding-right: 0px; z-index: 1;" minWidth="80">
+		<div dojoType="ContentPane" layoutAlign="client" class="statusPanel" style="padding-right: 0px; z-index: 1;">
 			panel 3
 		</div>
 		<div dojoType="ResizeHandle" targetElmId="mywindow"></div>


More information about the Dojo-checkins mailing list