Developer
Introduction
The main aim of this 'web application' is to allow the viewing of images in a structured way. Simple. How this is achieved, is in some ways, not so simple.
The slideshow is written using JavaScript, CSS and standard HTML. There are a few clever techniques used (I would say that, though :) ), but nothing too taxing on the mind. I'll run you through how things are done in quite some detail, giving links to relevant methods etc along the way. You'll notice there are a lot of code snippets here, but if you don't understand something, check the code from the downloadable slideshow, and look at the comments to see if it makes more sense there...
As always, feel free to e-mail me if you have any troubles, questions or suggestions. I've more than likely pissed something up along the way or done a Microsoft (used bloated code) somewhere...
A point to note is that if you wish to use this web app (thats what it's intended for) don't view the source code of the demo, but instead download the base slideshow which has a few images in and stuff to help you on your way. There's a few things in the slideshow demo that I've put in which are irrelevant, except to me and my mates, so it's easier in the long run to download the full thing in zip or sit format. If you want any help customising it, or removing any unnecessary parts, please e-mail me and I'll lend a hand (if I have time).
Right. Let's get on with the good stuff.
Swapping The Images
At the end of the day, this is what a slideshow is - something that goes through a set of images. How I achieved this, is by iterating through arrays. Nice and simple. As a side-line, a couple of years ago I made a thing for my mum which showed all the images in a specified folder that my dad e-mailed to us when he was in Oz. This was done using the filesystem object available in MSIE 5+. (That was before my conversion to Mac's and subsequent desertion of MSIE...). This was good, and the meant i didn't have to type out all the images I wanted into seperate arrays... etc
looking at the code, you'll see that all is done is telling the container image what source I want it to have, depending on where in the array the slideshow has gotten to.

Example

function nextImage() {

 document.getElementById("container").src = pictureArray[i];
 i++;

}


where container is the <img> whose src is changed to display the different pics, pictureArray is the array which has all the image names in, and i is the variable used to iterate though it (notice that i is incremented by 1 after the image is displayed).
You'll notice that this isn't a function I've used, but have instead put in a variable 'direction' into the function and told the function to increase i if the direction is set to 'next' or decrease it by 1 if it is set to 'prev'. This is just done to have less code... Also, since there are multiple arrays (due to pictures being put into sets), I have added in extra bits to tell it whether or not to go to the next set: set_num++. Also incorporated into this function is the fade effect (if desired).
Retrieving The Images
What I mean by this is finding which array to use. Let me go into a bit more depth:
The sets are displayed in the sets' quickjump menu with the corresponding pictures shown in the pictures' quickjump menu. This is done by having the sets[] array made to correspond with the arrays made in the .js file. You can have capital letters (and possibly white space, when i get round to it) in the sets[] array, but not in the corresponding array. Having these correspond like this allows the iteration of the sets[] array in order to find which set you want to display (also, we have to evaluate (eval()) what comes out of the sets[] array so that it see's it as the array we want, rather than a string of the same name...
Over and above this is geting the catagories. rather than having one big set of arrays, I decided to break down the catagories into individual .js files which are loaded when selected from the menu. All that's basically done is changing the src of the <script> so that it now looks at the relevant .js file.
So now we have all the data, and all that is needed is to populate this data into the quickjumps and reset the variables which are used for iteration so it starts at the beginning of the set...
To do this, something like the following can be use:

function populateSets() {

var set_sel = document.getElementById("set_select");
if (set_sel.options.length > 0) set_sel.options.length = 0;

 for (var c=0; c < sets.length; c++) {

  var opt = document.createElement("OPTION");

  opt.text = sets[c];

  set_sel.appendChild(opt);

 }

}


Here, the appropriate <select> is obtained and all of its options removed (if it has any). It is then populated with <options> whose text is obtained from the sets[] array in the current .js file.
Nice. We can now see all the images we want in order, or we have the choice to jump to any image we desire. Shall we make it fancy so it's a true web app?
The Fade Effect
Opacity is a marvellous thing. Well, you know what I mean. Opacity in MSIE5+ is handled in CSS with filter. Below 5.5 it is implemented by filter: alpha(opacity=0-100) and in 5.5+ using the progid thingy-me-bob. This is proprietry stuff and so isn't in Mozilla. Damn. However, what is in Moz is it's own proprietry hoo-je-me-flip under the name of -moz-opacity. Lovely. Set the value between 0 and 1 (where 1 is fully opaque) from script using element.style.MozOpacity=whatever and you're away. To actually make it appear to fade, however, you need to perform a setTimeout() or setInerval() with the opacity changing in value (increment a variable in the same way as the iteration through arrays earlier) and then use clearTimeout() or clearInterval to stop the effect happening when its done. And that, as they say, is that.
The Preferences Window
One of the main challenges here is to get and set the variables from the main window. This can be achieved quite easily using window.opener. What I've done, in order to pass the variables from the parent window to the preferences window is to assign the parents windows variables to variables with match it in the preferences window. e.g.

obg_color = window.opener.bg_colour;

Where bg_colour is just the background colour of the parent window (the slideshow itself)

Note:
This is how to read in the variables, done in the init() function. The opposite is done in the apChanges() function in order to change the parent windows variables.
I've used variables which are different in the preferences window (rather than assigning the variables to the window.opener ones straight away), so that 'apply' or 'OK' has to be clicked in order for any changes to occur.

You'll notice that the preferences window is set out in tabs, made to look like Mozilla in its modern theme. This is just done with CSS, not hard. The only unusual ting about them is using Mozilla's proprietry -moz-border-radius in order to get the rounded corner effect in the buttons and the tabs themselves. OS X's 'DigitalColor Meter' was very helpful in getting the right colours.
Actually making the tabs work has been done in a very specific way (something I'm not too fond of - I like making re-usable widgets rather than doing this), with tabs being changed and panes being swapped using id's. It works, but maybe I'll change it... There's a few things in here involving making the checkbox's and select's disbaled when they're not in use, but apart from that, the only thing that needs to be talked about is the background colour picker.
There's an absolutely huge array here which includes all the standard CSS colours by name. I orignially had these populating a select, but in order to make selection easier, I now have little 10px by 10px <span>'s which are used for the select. In order to get these to display in the way they have, I did the following:

var catcher = 0;
var toppos = 40;
var leftpos = 0;
var sHTML = new String();

 for (var i=0; i < colourArray.length; i++) {

  if (i > (catcher + 19) ) {

   toppos+=10;
   leftpos = 0;
   catcher = i;
  }

  sHTML += '<span style="position: absolute; top: ' + toppos + 'px; left: ' + leftpos + 'px; display: block; height: 10px; width: 10px; background: ' + colourArray[i] + '" onmouseover="showBgColour(this)" onclick="changeBgColour(this)"></span>';

  leftpos += 10;

 }

 document.getElementById("colour_container").innerHTML = sHTML;

}


So what's going on there then? Well, toppos and leftpos are the positions of the spans. leftpos is increased by 10 everytime, so that the <span>'s go side by side, and when there are 19 of them in a row, toppos goes up by 10, and leftpos goes back to 0, so that a new row is started below the previous one. (Note that the variable 'catcher' is used as an indication as to which row we are on). The for loop cycles through colourArray, each time ading a new <span> to the string sHTML. Once all the colours have been gone through, the innerHTML of colourContainer (the <div> into which I want this to go) is set to be sHTML. The onmouseover puts the colour you are hovering over into the preview span, and onclick for the span you are hovering over sets the colour that will be used when you click 'OK' or 'Apply'.
Oh, also, sizing the preferences window is done using window.resizeTo(width, height). But thats by-the-by. What is good, is the checking of whether or not the window exists so that the slideshow will either open a new preferences window or just focus the existing preferences window. i.e.

var wind;

function showPreferences() {

 if (!wind) {

  wind = window.open('preferences-web.html','','toolbar=no, resize=no');
  wind.resizeTo(450,265);

 } else { // if wind does exist, focus it

  wind.focus();

 }

}



where wind is the reference to the preferences window.
Re-using Customisations
Cookies basically. These are set everytime you exit the slideshow app, and are read everytime you go there (except the first time, or if you've deleted them, since they wont be there to be read...). You can see quite easily from the code how this is done. For more info on cookies, click here.
But why bother doing this? Becuase, as I found out from using the slideshow all the time, it's a pain the arse changing the settings to what you want them to be everytime you go to use it... Simple :)