Resizable asset map


(David Schoen) #1

We wanted a resizable asset map (sometimes it's a hassle to scroll around and undocking the asset map isn't always feasible). We did ask for this as a feature request a year ago apparently (it was before I joined my organisation) but we were informed "this is not technically possible".


So on that note I decided to implement it.



I've got a solution that seems to work, a few other people here have done some basic testing. I've developed the code on 3.16.2 SSV in a VM and ported it to 3.14.2 running on our current test server.



I've tested with Firefox 2.0.0.11 and IE 6.0.2900.



I would be interested in getting this integrated into the core if it passes Squiz's coding standards so that we don't have to patch matrix each upgrade and other Matrix customers can be happy that they've recieved a free feature.



Hurdle 1: Make the asset map change size when the frame around it changes size. Easy!



Add this code to "/core/lib/asset_map/asset_map.js":

    // DAVE PATCH: resizable asset map
    function daveResizeAssetMap() {
    	var frameWidth = document.body.clientWidth;
    	var frameHeight = document.body.clientHeight;
    	var assetMap = document.getElementById('sq_asset_map');
    	var newWidth = frameWidth - 5;
    	var newHeight = frameHeight - 70;
    
    	// argh negative size = badness
    	if (newWidth > 0)
    		assetMap.style.width = newWidth;
    	if (newHeight > 0)
    		assetMap.style.height = newHeight;
    }
    // adjust applet size after the frame is resized
    window.onresize = daveResizeAssetMap;
    window.onload = daveResizeAssetMap;



[b]Hurdle 2[/b]: make the frame resizable.
Allowing the browser to manage the resizing of the frame was only problematic from a looks perspective. I ended up with ugly borders on the screen, if someone knows enough css to make the standard browser based resizing work nicely I'd be interested to know what has to happen.

My alternative was to make the the toggle bar in the middle draggable with javascript.

All the code for this was in "/core/include/backend.inc".

To fix some bugs in ie I added noresize to the frames:

    
    				
    					
    					
    						
    						
    						
    					
    				


To make the toggleFrame function work with a frame that was an arbitrary size I made a few changes, I also added some code below it. Note, this bit of code didn't work when I dropped it on 3.14.2, I had to hard code the $am_width value:
    			// DAVE PATCH: resizable asset map
    			function toggleFrame() {
    				var cols = fset.cols.split(',');
    				cols[1] = (parseInt(cols[1]) == 0)?0:10;
    				if (hidden == false) {
    					if (cols[1] == 10) {
    						fset.cols = "0,10,*";
    					} else if (fset.cols == "<?php echo $am_width; ?>,0,*") {
    						fset.cols = "0,0,*";
    					}
    					hidden = true;
    				} else {
    					if (cols[1] == 10) {
    						fset.cols = "<?php echo $am_width; ?>,10,*";
    					} else if (fset.cols == "0,0,*") {
    						fset.cols = "<?php echo $am_width; ?>,0,*";
    					}
    					hidden = false;
    				}
    			}
    			var davesIETest = document.all?true:false;
    			function daveAdjust(amount) {
    				var cols = fset.cols.split(',');
    				cols[0] = parseInt(cols[0]) + amount;
    				cols[1] = (parseInt(cols[1]) == 0)?0:10;
    				cols[2] = "*";
    				fset.cols = cols.join(',');
    			}
    			var daveMouseDown = false;
    			var daveMouseOrigin = 0;
    			function daveDrag(e) {
    				var x;
    				var btnActuallyDown = true;
    				if (davesIETest) {
    					x = event.clientX;
    					// sometimes ie loses track of the mouse and never sends us
    					// a mouse up event, this hack fixes it
    					btnActuallyDown = event.button == 1;
    				} else {
    					// the above bug for ie exists for firefox, but we can't
    					// tell programatically if the left mouse button is down
    					// unless you want to make mouse2 or 3 the drag button your
    					// stuffed.
    					x = e.pageX;
    				}
				if (daveMouseDown && btnActuallyDown) {
					daveAdjust(x - daveMouseOrigin);
				}
			}
			function daveDown(e) {
				if (davesIETest) {
					daveMouseOrigin = event.clientX;
				} else {
					daveMouseOrigin = e.pageX;
				}
				daveMouseDown = true;
			}
			function daveUp(e) {
				daveMouseDown = false;
			}
			document.onmousemove = daveDrag;
			document.onmousedown = daveDown;
			document.onmouseup = daveUp;</pre><br />

I tweaked the table drawing inside the frame to display a sensible cursor (so that the user actually _knows_ they can resize it).:
    		
    		
<<



Edit: added info on browsers i've tested in.
Edit: please note variable names only have "dave" at the front to make sure I didn't clash with any variables already floating around, feel free to change them.

(Nic Hubbard) #2

But the asset map is resizable now. You can change the width of it. what else does your patch achieve?


(David Schoen) #3

You can only change the width of the default size, with this patch each user can just drag it to the size they want.


(David Schoen) #4

Another thing I forgot was that with the std asset map if you change the height of your browser window the asset map can either get lost or not take up the space you would it expect it to. This is not as big a deal though because the frame can just be reloaded, but it does make content editing more efficient when we're not having to work around so many little bugs.


(Nic Hubbard) #5

Ah, cool!

(Avi Miller) #6

David -- are you happy to hand over copyright of this code to Squiz for inclusion in the Core? Did you use any third-party code that you don't hold the copyright for?

(Greg Sherwood) #7

Thanks for this contribution. We'll have a look into incorporating it into the core for a future release.



Just a note that when that request was made, the actual response I gave was that we had already done this but were unable to get it working on all browsers and platforms we had to support. Not all of them allow resizing of Java applets (or didn't at the time). I suggested we could add it in as long as we were careful not to cause JS errors for those browsers that did not support the feature. I guess that didn't filter through properly :slight_smile:


(David Schoen) #8

No third party code, I had to google to find parseint(), split() and how to handle mouse events but the logic surrounding them is mine.



As for the copyright, I'm happy to let you have it (would prefer you put on a "submitted by David Schoen" if possible but not overly fussed). I will have to confirm with my boss that it's only me that has the copyright though as I've done this on time for my organisation I might have to get permission from here first. Will let you know soon.


(David Schoen) #9

No that didn't come through, the quote I gave above was fairly close to what's officially documented here (but I may have changed the words as I wrote it from memory). It's a pitty because if the propper message came through I suspect we would have responded something like below and you guys would have been fine to charge us for it.



If the code fails in other browsers it should be easy enough to either implement the code as a feature that has to be turned on or just sniffing for the useragent in the javascript code.


(David Schoen) #10

Have discussed the copyright issue with management and they intend to contact Squiz through the "Official Channels".


(Avi Miller) #11

Cool.

(David Schoen) #12

We noticed today that we couldn’t set a design on assets which I tracked down to the way I had overwritten (instead of appending to) the onload event. Here’s some code which doesn’t seem to clash for the event adding in asset_map.js:

    window.attachEvent(“onresize”, daveResizeAssetMap);
window.attachEvent(“onload”, daveResizeAssetMap);