Commits

Luke Plant committed c41a9a2

Implemented tooltips

Comments (0)

Files changed (5)

semanticeditor/media/semanticeditor/javascript/orbitaltooltip.js

+/*
+ * OrbitalTooltip jQuery Plugin (http://www.userfirstinteractive.com/)
+ * @author Scott D. Brooks 
+ * @created by UserFirst Interactive (creations@userfirstinteractive.com)
+ * 
+ * @version 0.1
+ * 
+ * @changelog
+ * v 0.1 	->	Starting release [Nov. 26, 2008]
+ * 
+ */
+(function(jQuery) {
+	
+	// Decalre important math functions
+	Math.cot = function(x) { return 1 / Math.tan(x); }
+	
+	function degrees_to_radians(deg) {
+    	return deg * (Math.PI/180);
+	}
+	
+	function radians_to_degrees(rad) {
+    	return rad * (180/Math.PI);
+	}	
+
+	// calculates the size of the opposite side
+	function calculate_opposite_side(adjacent, degrees) {
+		return Math.round(Math.tan(degrees_to_radians(degrees)) * adjacent);
+	}
+	
+	// calculates the size of the adjacent side
+	function calculate_adjacent_side(opposite, degrees) {
+		return Math.round(Math.cot(degrees_to_radians(degrees)) * opposite);
+	}
+	
+	function calculate_degrees_from_sides(adjacent, opposite) {
+		return radians_to_degrees(Math.atan(opposite / adjacent));
+	}
+	// End Math functions
+	
+    jQuery.extend({
+        orbitaltooltip: {
+            version: 0.1,
+            defaults: {
+	        	orbitalPosition: 	180,								// the tooltip's position in degrees from the center of the object (0 or 360 degrees being top, 90 right, 180 bottom, 270 left... and everything in between).
+	        	tooltipClass: 		'orbitaltooltip-default-bottom',	// class for the tooltip
+	        	spacing: 			5,									// spacing from the edge of the object requesting a tooltip
+	        	offset: 			0, 									// depending on the side of display, move the tooltip closer or further from the top left (so -10 would move the tooltip closer to the left when displayed on top or bottom)
+	        	html:				'<p>sample text</p>',				// HTML within the tooltip
+	        	revealStyle: 		'fade',  							// not currently in use
+	        	orbit:				false,  							// not currently in use
+	        	orbitInterval:		500  								// not currently in use
+            }
+        }
+    });
+    
+    jQuery.fn.extend({
+        orbitaltooltip: function(options) {
+            var options 		= jQuery.extend({}, jQuery.orbitaltooltip.defaults, options);
+            var orbTooltip 		= this;
+            var uniqueID 		= 'orbialtTip_' + this.attr("id");
+            
+            // add divs for each item            
+            jQuery("body").append(jQuery(document.createElement('div')).html(options.html).addClass(options.tooltipClass).attr("id",uniqueID).css("display","none"));
+            
+            // skip initial position calc. if they are choosing to have the tooltip orbit
+        	if (options.orbit != true) {
+        		var tooltipPosition = calculatePosition(orbTooltip, jQuery("#" + uniqueID), options.orbitalPosition, options.spacing, options.offset);
+        	}
+        	
+        	var fly_orbit = false;
+            return this.hover(
+                function(e) {
+                	if (options.orbit == true) {
+                		/*  Causing lock-up at the moment.  Will investigate further at a later date
+                		var position = options.orbitalPosition;
+                		fly_orbit = true;
+                		while (fly_orbit) {
+                			position = position + 1;
+                			if (position > 360) { position = 1; }
+                			tooltipPosition = calculatePosition(orbTooltip, jQuery("#" + uniqueID), position, options.spacing);
+                			setTimeout("move_along_orbit(jQuery('#' + uniqueID), tooltipPosition)", options.orbitInterval);
+                		}
+                		*/
+                		alert('orbiting functionality is not currently functioning');
+                  	} else {
+                		position(jQuery("#" + uniqueID), tooltipPosition[0], tooltipPosition[1]);
+                	}
+                },
+                function(e) {
+					// off hover
+					fly_orbit = false;
+					hideTooltip(jQuery("#" + uniqueID));
+                }
+            );
+        }
+    });
+    
+	function move_along_orbit(tooltip, tooltipPosition)
+	{	
+		tooltip.fadeOut(50);
+		tooltip.css("position","absolute");
+		tooltip.css("top",tooltipPosition[1]);
+		tooltip.css("left",tooltipPosition[0]);
+		tooltip.fadeIn(50);		
+	}
+
+	function position_top(element_to_add_tooltip, tooltip, spacing)
+	{	
+		// var element_width = element_to_add_tooltip.width() + get_horizontal_padding(element_to_add_tooltip);
+		// var element_height = element_to_add_tooltip.height() + get_vertical_padding(element_to_add_tooltip);
+	
+		var tooltip_width = tooltip.width();
+		var tooltip_height = tooltip.height();
+
+		var coordinates = element_to_add_tooltip.offset()
+		var x = coordinates.left + ((element_width / 2) - (tooltip_width / 2));
+		var y = coordinates.top - tooltip_height;
+		
+		position(tooltip, x, y);
+	}
+	
+	function get_vertical_padding(element)
+	{	
+		var vertical_padding = parseInt(element.css('padding-top')) + parseInt(element.css('padding-bottom'));
+		vertical_padding = vertical_padding + parseInt(element.css('border-top-width')) + parseInt(element.css('border-bottom-width'));
+		
+		return vertical_padding;
+	}
+	
+	
+	function get_horizontal_padding(element)
+	{	
+		var horizontal_padding = parseInt(element.css('padding-right')) + parseInt(element.css('padding-left'));
+		horizontal_padding = horizontal_padding + parseInt(element.css('border-right-width')) + parseInt(element.css('border-left-width'));
+		
+		return horizontal_padding;
+	}
+	
+	function calculatePosition(element_to_add_tooltip, tooltip, orbitalPosition, spacing, offset)
+	{
+		var position = new Array();		// x=[0], y=[1]
+				
+		var element_center = get_element_center_coordinates(element_to_add_tooltip);
+		var tooltip_center = get_element_center_coordinates(tooltip);
+		
+		// error checking on degrees
+		if (orbitalPosition > 360 || orbitalPosition < 0 ) {
+			alert('You have misconfigured your orbitalTooltip - please choose from an orbit between 0-360 degrees for the object: #' + orbitalTooltip.attr("id"));
+			position[0] = 0;
+			position[1] = 0;
+			return position;
+		}
+		
+		var adjacent = element_to_add_tooltip.height() / 2;
+		var opposite = element_to_add_tooltip.width() / 2;
+		
+		var angle_to_corner = calculate_degrees_from_sides(adjacent, opposite);
+				
+		var topleft_indegrees = Math.round(360 - angle_to_corner);
+		var topright_indegrees = Math.round(angle_to_corner);
+		var bottomright_indegrees = Math.round(180 - angle_to_corner);
+		var bottomleft_indegrees = Math.round(180 + angle_to_corner);
+
+		switch (true)
+		{
+			// All right angles within element
+			case ((orbitalPosition == 0) || (orbitalPosition == 360)):  // top
+				position[0] = element_center[0] - Math.round(tooltip.width() / 2);
+				position[1] = element_center[1] - Math.round(element_to_add_tooltip.height() / 2) - (tooltip.height() + spacing);
+				break;
+			case (orbitalPosition == 90):  // right
+				position[0] = element_center[0] + Math.round(element_to_add_tooltip.width() / 2) +  spacing;
+				position[1] = element_center[1] - Math.round(tooltip.height() / 2);
+				break;
+			case (orbitalPosition == 180):  // bottom
+				position[0] = element_center[0] - Math.round(tooltip.width() / 2);
+				position[1] = element_center[1] + Math.round(element_to_add_tooltip.height() / 2) + spacing;
+				break;
+			case (orbitalPosition == 270):  // left
+				position[0] = element_center[0] - Math.round(element_to_add_tooltip.width() / 2) - (tooltip.width() + spacing);
+				position[1] = element_center[1] - Math.round(tooltip.height() / 2);
+				break;
+			// Quadrants - between angles bisecting the corners of the object
+			case (((orbitalPosition >= topleft_indegrees) && (orbitalPosition < 360)) || (orbitalPosition < topright_indegrees)):  		// top
+				if (orbitalPosition >= topleft_indegrees) {
+					degrees_from_bisector = 360 - orbitalPosition;
+					var tt_shift = 1 - calculate_opposite_side((element_to_add_tooltip.height()/2), degrees_from_bisector);
+					tt_shift = tt_shift - calculate_opposite_side((tooltip.height()/2), degrees_from_bisector);
+				} 
+				if (orbitalPosition < topright_indegrees) {  
+					degrees_from_bisector = orbitalPosition;
+					var tt_shift = calculate_opposite_side((element_to_add_tooltip.height()/2), degrees_from_bisector);
+					tt_shift = tt_shift + calculate_opposite_side((tooltip.height()/2), degrees_from_bisector);
+				}
+				position[0] = element_center[0] + offset + tt_shift - Math.round(tooltip.width()/2); 
+				position[1] = element_center[1] - Math.round(element_to_add_tooltip.height() / 2) - (tooltip.height() + spacing);
+				break;
+			case ((orbitalPosition >= topright_indegrees) && (orbitalPosition < bottomright_indegrees)):  	// right
+				if (orbitalPosition < 90) {  
+					degrees_from_bisector = 90 - orbitalPosition;
+					var tt_shift = 1 - calculate_opposite_side((element_to_add_tooltip.width()/2), degrees_from_bisector);
+				} else {  
+					degrees_from_bisector = orbitalPosition - 90;
+					var tt_shift = calculate_opposite_side((element_to_add_tooltip.width()/2), degrees_from_bisector);
+				}		
+				position[0] = element_center[0] + Math.round(element_to_add_tooltip.width() / 2) + spacing;
+				position[1] = element_center[1] + offset + tt_shift - Math.round(tooltip.height()/2); 
+				break;
+			case ((orbitalPosition >= bottomright_indegrees) && (orbitalPosition < bottomleft_indegrees)):  // bottom
+				if (orbitalPosition < 180) {  
+					degrees_from_bisector = 180 - orbitalPosition;
+					var tt_shift = calculate_opposite_side((element_to_add_tooltip.height()/2), degrees_from_bisector);
+				} else {  
+					degrees_from_bisector = orbitalPosition - 180;
+					var tt_shift = 1 - calculate_opposite_side((element_to_add_tooltip.height()/2), degrees_from_bisector);
+				}
+				position[0] = element_center[0] + offset + tt_shift - Math.round(tooltip.width()/2); 
+				position[1] = element_center[1] + Math.round(element_to_add_tooltip.height()/2) + spacing;
+				break;
+			case ((orbitalPosition >= bottomleft_indegrees) && (orbitalPosition < topleft_indegrees)):  	// left
+				if (orbitalPosition < 270) {  
+					degrees_from_bisector = 270 - orbitalPosition;
+					var tt_shift = calculate_opposite_side((element_to_add_tooltip.width()/2), degrees_from_bisector); 
+				} else {  
+					degrees_from_bisector = orbitalPosition - 270;
+					var tt_shift = 1 - calculate_opposite_side((element_to_add_tooltip.width()/2), degrees_from_bisector); 
+				}	
+				position[0] = element_center[0] - Math.round(element_to_add_tooltip.width() / 2) - (tooltip.width() + spacing);
+				position[1] = element_center[1] + offset + tt_shift - Math.round(tooltip.height()/2); 
+				break;
+		}
+		
+		return position;
+	}
+	
+	function position(element,x,y)
+	{
+		element.stop(true, true);		
+		element.css("position","absolute");
+		element.css("top",y);
+		element.css("left",x);
+		revealTooltip(element);
+	}
+	
+	function get_element_center_coordinates(element)
+	{	
+		var center_of_element = new Array();
+		
+		var element_top_left_coords = element.offset()		
+		center_of_element[0] = element_top_left_coords.left + Math.round((element.width() + get_horizontal_padding(element)) / 2);
+		center_of_element[1] = element_top_left_coords.top + Math.round((element.height() + get_vertical_padding(element)) / 2);
+		
+		return center_of_element;
+	}	
+	
+	function revealTooltip(tooltip)
+	{
+		tooltip.fadeIn(200);
+	}
+	
+	function hideTooltip(tooltip)
+	{	
+		tooltip.fadeOut(200);
+	}
+		    
+})(jQuery);

semanticeditor/media/semanticeditor/javascript/wymeditor/plugins/semantic/wymeditor.semantic.js

 	// TODO name, value
 	// TODO - tooltip with description
 	var val = flattenPresStyle(item);
-	self.optsbox.append("<div style=\"clear: left;\"><div><label><input type=\"checkbox\" value=\"" + escapeHtml(val) + "\" /> " + escapeHtml(item.verbose_name) + "</label></div></div>");
+	self.optsbox.append("<div><label><input type=\"checkbox\" value=\"" +
+			    escapeHtml(val) + "\" /> " +
+			    escapeHtml(item.verbose_name) +
+			    "</label></div>");
+	// Attach tooltip to label we just added:
+	self.optsbox.find("input[value='" + val + "']").parent().each(function() {
+	    // Assign an id, because orbitaltooltip
+            // doesn't work without it.
+	    var help = item.description;
+	    if (help == "") {
+		help = "(No help available)";
+	    }
+	    help = "<h1>" + escapeHtml(item.verbose_name) + "</h1>" + help;
+	    $(this).attr('id', 'id_optsbox_label_' + i);
+	    $(this).orbitaltooltip({
+		orbitalPosition: 270,
+		spacing:         10,
+		tooltipClass: 	 'orbitaltooltip-simplebox',
+		html:            help
+	    });
+	});
     });
 };
 
 			input.checked = true;
 		    }
 		});
-	    // Add event handler
+	    // Add event handlers
+	    // Change
 	    jQuery(this).change(function(event) {
 				    var style = expandPresStyle(input.value);
 				    if (input.checked) {

semanticeditor/media/semanticeditor/javascript/wymeditor/skins/semanticeditor/skin.css

 	.prescontrol td             { padding: 0; }
 	.prescontrolheadings        {  }
 	.prescontrolheadings select { min-width: 150px; }
-	.prescontroloptsboxcont     {  }
+	.prescontroloptsboxcont div { clear:left; }
 	.prescontroloptsbox         { overflow-y: scroll; }
 	.prescontrolrefresh         {  }
 	.prescontrolerror           { color: red; text-align: center; padding-top: 5px; }
 	/* TODO - styling for checkboxes and labels in prescontroloptsbox */
+
+/* TOOLTIPS */
+
+	.orbitaltooltip-simplebox {
+	    background: #ddd;
+	    width: 400px;
+	    height: auto;
+	    min-height: 100px;
+	    max-height: 400px;
+	    overflow-y: scroll;
+	    overflow-x: hidden;
+	    border: 2px solid #607e98;
+	}

semanticeditor/utils/presentation.py

 
 NEWROW = PresentationCommand('newrow',
                              verbose_name = "New row",
-                             description = "TODO")
+                             description = """
+<p>Use this command to start a new row.</p>
+
+<p>This must be used in conjunction with 'New column'
+to create a column layout.</p>.
+
+<p>Please note that new rows and columns cannot be started at any
+point in the document.  Within a given row, new columns can only be
+started on section headings of the same level.  The 'New row' command
+must be applied to the first section heading for which a column layout
+is required and subsequent headings of the same level may be given
+a 'New column' command.</p>
+
+""")
 
 NEWCOL = PresentationCommand('newcol',
                              verbose_name = "New column",
-                             description = "TODO")
+                             description = """
+<p>Use this command to start a new column, after a 'New row'
+command has been used to start a set of columns.</p>
+
+""")
 
 ## General utilities
 

semanticeditor/widgets.py

         js = [join(settings.SE_MEDIA_URL, path) for path in
               ('javascript/wymeditor/plugins/semantic/wymeditor.semantic.js',
                'javascript/json2.js',
+               'javascript/orbitaltooltip.js',
                )]
 
     def render_extra(self, name, value, attrs=None):