|Home » Learning Curve » Developers Workshop
A few tricks.
Although there were snags encountered in the developers tools in creating Clipothèque not all turned out negative. There were a lot of cool things too. And knowing about them might help in using the program as well.
The first and biggest step between G1 and G3 - the insight that a new version was called for - came after G1 was finished within that 48 hour period.
G1 fit the bill: it was economical and it got that YouTube collection out of hock. But it had a limitation in that clips had to be organised on a per file basis for each provider.
It was incredibly easy to use like that: the base URL and basic embed code were set for each file in advance; the base URL was automatically parsed away from every URL fed into the system; all that was left was an ID which fit snugly into the embed code at runtime. All the user had to do was drag a URL - in particular a YouTube URL - onto the document window.
The program stored everything in the excellent NSDictionary format: base URL, basic embed code, and then an array of clip IDs. It couldn't be simpler.
Unless you wanted for example to put a Brightcove clip in a YouTube file. The design limited how one could organise the clips. If one instead could put any clip from any provider in any file...
Most media sources are set up to work that way. View their clips and then click a button called 'share' and up pops a panel with a direct URL and a full embed code. Even though it's not as efficient it's a lot easier to just drag the two fields into a Clipothèque document window.
Editing clip data with a sheet was preferred over inline editing right in the table view. The latter is messy and conducive to a lot of user error. This way the user can take the time needed to get everything right before clicking that 'save' button.
The original G1 version assumed the user would be dragging a URL to the document window; G3 goes further: it actually inspects what's being dragged before deciding what to do with it.
Dragging a Clipothèque record from one window to another does the expected: puts the record in the target window. But if it's not a Clipothèque record being dragged the program looks at what's coming in.
So the data sheet for editing records opens automatically when something other than a Clipothèque record is dropped. There are three fields in the data sheet: the description, the direct link, and the embed code. One of those fields is going to be filled in automatically.
If the parcel looks like an embed code the embed field is filled in; if it's a URL the direct link field is filled in; in all other cases the description field is filled in. But the fun doesn't stop there.
It's namely possible to override that default behaviour by holding down a shift key when dropping. If you hold down a shift key the field filled in depends on where on the document window you make the drop.
If the drop is at the top of the document window the first field (description) is filled in; if the drop is at the bottom the third field (embed code) is filled in; if the drop is in the middle of the document window the second field (direct link) is filled in.
By holding down shift.
Text fields also have a propensity for not working as one would want. They've been designed from the get-go to share a single NSText editor. Only the currently active (focused) field is responsive to drops etc.
There's a way around that. Simply disable them all as a drag comes in and then continually calculate where the drop point is and enable the drop if it's over one of the text fields; when the drop takes place simply set the entire text field string and then enable all the fields again.
This makes it possible to drag to text fields from the source program without first going to the target program and tabbing to the right control.
Clipothèque uses the ACP technology for document specific settings. Most apps file away user specific settings in ~/Library/Preferences but those are on a per user basis. Not a per document basis. The advent of the extended attribute API with 10.4 Tiger changes all that.
Suddenly it's possible to store settings particular to each file with the file itself. The ACP system also allows for any client application to store its own per document settings.
A document with extended attributes left behind by Rixedit will behave in one way when opened by Rixedit and another way swhen opened by Clipothèque.
Clipothèque namely stores the document window coordinates, the table column widths, and even the table column sort and sort direction in each Clipothèque file. Where you last left the file when you saved it is where you're going to find it next time.
You can have one column exposed; have the document window cover as much or as little of the screen as you want; sort according to any of the three columns either ascending or descending; and when next you look at the file it will be in the same position with the same column widths and sort.
Document specific settings. User specific settings for programs that access any number of files are truly of limited value. They're always there if you want them; but most often you wont and will override them.
Taming the WebKit wasn't easy and provided an opportunity to learn a bit more how that technology works. Most program control comes through delegation. In the case of Clipothèque only one or two delegations are necessary. It was necessary to kill the default context menu, get rid of the forward and back cache, etc. It was also necessary to automatically clear all caches on exit to save the user that trouble as well.
Being sensitive to changes in selection no matter which window is active was also a big consideration. Clipothèque clips load automatically; there is no specific command to do this. Again: user simplicity was the goal. Each time you change selection the clip in the preview window changes.
But it also changes if you remove a selection - if you cut out the selected record or simply cmd-click on it. Or open a new window. Or close the window with the current selection. And so forth.
The preview window has to namely keep close track on who is sending what. Just because a window with a selection is closing doesn't mean the preview window should zap the current clip: the window also has to be the source of the current clip. Otherwise the news it's closing is irrelevant.
And so forth. It sounds complex but from a user POV it's eminently obvious.
The standalone Clipothèque is localised into English, Japanese, and Swedish for now. With time there might be further localisations.
The technique used to share clips is interesting. Nothing is written to disk - the same code used to write to disk is used to assemble a 'dictionary' attached to the mesage. It's put straight away in an attachment to go out with NSMailDelivery. All recipients are serialised - no recipient sees anyone else's address. The sender's list of addresses is provided automatically; the recipient addresses used is saved automatically; and these two fields together with the message field itself come back each time in the same session you're sharing clips to save you even further work.
When clips arrive at the other end they can be clicked right in the mail client to automatically save to disk and open. The format used for file naming is to prevent any possible collisions while at the same time making files easy to sort. The numbers are namely a UTC date/time stamp.
The 'mmm' at the end is the number of milliseconds.
Files aren't merely saved in NSDictionary (property list) format - they're saved in binary with the NSPropertyListSerialization API to partly compensate for the overhead in not economising with base URLs and template embed code. A single record takes about 400 bytes; thus a collection of 1,000 clips will take approximately 400 KB and a single megabyte file will hold 2,500 clips.
One of the cutest things - one of the most essential things - is how the preview window automatically resizes content to fit. This despite your copying over the embed code from the provider (such as YouTube) with specific dimensions given.
<object width="425" height="355"><param name="movie" value="http://www.youtube.com/v/pYL4t8HvhSw&hl=en"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/pYL4t8HvhSw&hl=en" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></embed></object>
Each time you drag at the sizing corner of the preview window (unless you're holding down option) the preview window takes the 'string' that's already been fed into the WebKit control and recalculates what those 'height' and 'width' values should be.
The preview window is set to be a 'HUD' but of course this doesn't show up on Tiger 10.4.
The search technology was pulled straight from the ACP Framework without modification. The beauty of the code is that it is 0% invasive: client code does not have to be adjusted to accept its presence. The code automatically and all by itself susses out what is what and what's to be searched and who to send commands to. Credit Alan Kay with a good idea but also credit Rixstep with a good implementation.
As per usual the artwork is by Graphic Tribe; Dali at GT has again done an overwhelmingly impressive job.
PS. 'Save' and 'send' aren't available in the trial version; the figure of $17 was chosen to keep things cheap and to match Apple's A-class number. Split after the merchant cut leaves $2 per developer. Enough to maybe keep people in muffins. The registered product comes with a full year's updates and support so it's an amazing deal.
The ACP: Clipothèque
The ACP: Xfile Test Drive
Industry Watch: goodies.clip
Rixstep Downloads: Clipothèque
Developers Workshop: Infinite Wisdom
Developers Workshop: Paperback Cliché
Shah Jahan Mumtaz Google Maps & Clipothèque
Rixstep Downloads: Xfile Test Drive with Clipothèque
Developers Workshop: Perfect Pixel Demo Reel Jan 2007
Developers Workshop: 48 Hours — The Clipothèque™ Beta
Learning Curve: Clipothèque Part 1: Add a Clip and Share It
Industry Watch: Clipothèque Scaleable Vector Graphics Test