<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.0.1" -->
<rss version="2.0" 
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>tomas.epineer.se</title>
	<link>http://tomas.epineer.se</link>
	<description>Macs, Rails, PHP and general nerdery</description>
	<pubDate>Fri, 15 Feb 2008 23:40:42 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.0.1</generator>
	<language>en</language>
			<item>
		<title>Jamtris new version ideas</title>
		<link>http://tomas.epineer.se/archives/12</link>
		<comments>http://tomas.epineer.se/archives/12#comments</comments>
		<pubDate>Fri, 30 Jun 2006 00:12:51 +0000</pubDate>
		<dc:creator>Tomas Larsson</dc:creator>
		
	<category>Games</category>
	<category>J2ME</category>
		<guid isPermaLink="false">http://tomas.epineer.se/archives/12</guid>
		<description><![CDATA[For the next version of Jamtris I would very much like to have some feedback from you!
I want to know which features you want to see in the next version of this popular game.
Features that definitely will make it into the next version are


The ability to turn off the game and continue at a later [...]]]></description>
			<content:encoded><![CDATA[<p><!--adsense#halfheight-->For the next version of Jamtris I would very much like to have some feedback from you!
I want to know which features you want to see in the next version of this popular game.
Features that definitely will make it into the next version are</p>

<ul>
<li>The ability to turn off the game and continue at a later time</li>
<li>A small indicator of current time (for when you&#8217;re playing Jamtris while waiting for the bus, for example)</li>
<li>An alternative pause button (for phones that don&#8217;t properly map the current pause button)</li>
</ul>

<p>Please add a comment below with your other wishes for the next version!<!--9d25b3e3869da88b6508a52e17862605--></p>
]]></content:encoded>
			<wfw:commentRSS>http://tomas.epineer.se/archives/12/feed/</wfw:commentRSS>
		</item>
		<item>
		<title>Upload update</title>
		<link>http://tomas.epineer.se/archives/11</link>
		<comments>http://tomas.epineer.se/archives/11#comments</comments>
		<pubDate>Sun, 23 Apr 2006 14:47:37 +0000</pubDate>
		<dc:creator>Tomas Larsson</dc:creator>
		
	<category>PHP</category>
	<category>AJAX</category>
		<guid isPermaLink="false">http://tomas.epineer.se/archives/11</guid>
		<description><![CDATA[

Due to the great interest in my little php-upload-with-progress-bar script I have now created a sourceforge project for it and released a new version of the code, based on all the great feedback in the original blog post. The new version can be downloaded here. The changes are mostly to make it easier to get [...]]]></description>
			<content:encoded><![CDATA[<!--adsense#halfheight-->

<p>Due to the great interest in my little <a href="http://tomas.epineer.se/archives/3">php-upload-with-progress-bar script</a> I have now created a sourceforge project for it and released a new version of the code, based on all the great feedback in the original blog post. The new version can be downloaded <a href="http://prdownloads.sourceforge.net/tesupload/tesUpload-1_0.tar.gz?download">here</a>. The changes are mostly to make it easier to get started with the script. If you&#8217;ve already got it working, don&#8217;t bother downloading this one.</p>

<p>If you&#8217;ve got ideas for the next version, please leave a message in the comments or on the <a href="http://sourceforge.net/projects/tesupload/">Sourceforge project page</a>. Already planned features for next version are ability to print progress (in percentages), as suggested by Travis, and download speed.</p>

<p>The script has also been given a name, tesUpload, and a <a href="http://tomas.epineer.se/tesupload/">permanent home</a>.<!--6bba34c18c21bf8b26c878eb4a4b013e--></p>
]]></content:encoded>
			<wfw:commentRSS>http://tomas.epineer.se/archives/11/feed/</wfw:commentRSS>
		</item>
		<item>
		<title>Chaining the DHTML Spinbox</title>
		<link>http://tomas.epineer.se/archives/8</link>
		<comments>http://tomas.epineer.se/archives/8#comments</comments>
		<pubDate>Sun, 26 Mar 2006 17:50:50 +0000</pubDate>
		<dc:creator>Tomas Larsson</dc:creator>
		
	<category>Javascript</category>
	<category>DHTML</category>
		<guid isPermaLink="false">http://tomas.epineer.se/archives/8</guid>
		<description><![CDATA[
After a great suggestion in the comments to the original article I have now added the ability to chain several spinboxes so that when one reaches it max value, another one is updated. To do this, simply create two spinboxes and then call registerOverflowObserver() on the first one with the second one as an argument. [...]]]></description>
			<content:encoded><![CDATA[<p><!--adsense#halfheight-->
After a great suggestion in the comments to the <a href="/archive/6">original article</a> I have now added the ability to chain several spinboxes so that when one reaches it max value, another one is updated. To do this, simply create two spinboxes and then call registerOverflowObserver() on the first one with the second one as an argument. An example:</p>

<pre><code> m = new SpinBox('minutes',0,59);
 h  = new SpinBox('hours',0,23);
 m.registerOverflowObserver(h);
</code></pre>

<p>Now whenever the first spinbox gets below 0 or above 59, the second one will be decreased or increased by 1. This is useful when you want to use spinboxes to enter time, which is one of the most common things spinboxes are used for.</p>

<p>The <a href="/tesSpinbox/demo.html">demo</a> has been updated to display this new functionality. I have also created a sourceforge project for the spinbox which can be found <a href="http://www.sourceforge.net/projects/tesspinbox/">here</a>, so if you need any kind of support or want to file a bug then please go there.</p>

<p>The complete archive can be downloaded <a href="http://prdownloads.sourceforge.net/tesspinbox/tesSpinbox-1_1.tar.gz?download">here</a>.<!--9f44f41274fafa3c461e8e2ae314d457--></p>
]]></content:encoded>
			<wfw:commentRSS>http://tomas.epineer.se/archives/8/feed/</wfw:commentRSS>
		</item>
		<item>
		<title>Creating a DHTML Spinbox</title>
		<link>http://tomas.epineer.se/archives/6</link>
		<comments>http://tomas.epineer.se/archives/6#comments</comments>
		<pubDate>Mon, 20 Mar 2006 23:02:42 +0000</pubDate>
		<dc:creator>Tomas Larsson</dc:creator>
		
	<category>Javascript</category>
	<category>DHTML</category>
		<guid isPermaLink="false">http://tomas.epineer.se/archives/6</guid>
		<description><![CDATA[
Recently I was asked by a client if it would be possible to use a spinbox for a certain value in a web application I was building. Being totally sure this was going to be a piece of cake I said yes (it&#8217;s just a textbox with two arrows, right?). As it turns out, it [...]]]></description>
			<content:encoded><![CDATA[<p><!--adsense-->
Recently I was asked by a client if it would be possible to use a spinbox for a certain value in a web application I was building. Being totally sure this was going to be a piece of cake I said yes (it&#8217;s just a textbox with two arrows, right?). As it turns out, it is possible, only a little bit more complicated than I first thought.
<h2>The Spinbox</h2></p>

<p><img src="http://tomas.epineer.se/wp-content/uploads/2006/03/spinbox.png" align="right"></p>

<p>The spinbox is also called spinbutton, spincontrol or UpDown button. You can see it in the picture on the right. It is commonly used to enter, for example, time and dates in desktop applications but isn&#8217;t available as an HTML form element.
<h2>Placing the arrows</h2></p>

<p>The greatest challenge by far was positioning the arrow images. I started trying to do it using css, but soon gave up when I encountered too many browser inconsistensies, bugs and missing features (such as missing inline-block in Firefox), and decided to do it the old-fashioned way instead: using tables. In my solution, a table is created dynamically around the textbox and made inline so that more than one spinbox can be laid out on the same line. Only problem is, Firefox and IE both don&#8217;t understand display:inline-table, they want display:inline instead, which Safari &amp; Opera don&#8217;t like. The solution to that:</p>

<pre><code>table.style.display='inline';
try {
    table.style.display = 'inline-table';
} catch(e) {}
</code></pre>

<p>Firefox just silently drops the inline-table declaration that it doesn&#8217;t understand but IE throws and error. That&#8217;s why the try/catch statement is needed.
<h2>PeriodicalExecuter</h2></p>

<p>When one of the arrows is clicked, the value in the textbox should increase or decrease while the mouse button is held down. To accomplish this I created a <a href="http://prototype.conio.net">Prototype</a> PeriodicalExecuter  which updates the textbox with increasing frequency. Only problem is, for some reason they&#8217;ve decided to not include a stop method for the PeriodicalExecuter. Luckily, <a href="http://www.metalmadness.co.uk/Blog/archive/2006/01/09/801.aspx">someone else</a> also ran into this problem. I&#8217;ve included that solution in my source. 
<h2>Disable context menu</h2></p>

<p>In Firefox on Mac, the context menu pops up when you hold down the left mouse button for a second or so anywhere in the window. This is obviously a bit annoying when you are trying to use the spinbox. Turns out that you can stop it from happening by denying the onContextMenu action from firing. In Prototype code:</p>

<pre><code>Event.observe(img,'contextmenu',function(evt){Event.stop(evt);});
</code></pre>

<p>In HTML this would be:</p>

<pre><code>&lt;img src="pic.gif" oncontextmenu="return false;"&gt;
</code></pre>

<h2>Files</h2>

<p>Download the files here: <a href="http://prdownloads.sourceforge.net/tesspinbox/tesSpinbox-1_0.tar.gz?download">tesSpinbox</a>.
You can try a live demo here: <a href="/tesSpinbox/demo.html">Demo</a>.
<h2>Usage</h2></p>

<p>Include prototype first, and then spinbox.js. Change the path to the images in spinbox.js (sb_imgpath) to point to where you uploaded the images.
Then to convert any textbox into a spinbox:</p>

<pre><code>new SpinBox(id_of_textbox,min_value,max_value,padded_length);
</code></pre>

<p>Padded_length is the desired length of the string in the textbox. If the string is shorter than this value, it will be padded with zeros. A padded_length of 3 would mean that 7 becomes 007, for example.
A spinbox example:</p>

<pre><code>&lt;input type="text" id="myspin" size="2"&gt;
&lt;script language="javascript"&gt;
    new SpinBox('myspin',0,59);
&lt;/script&gt;
</code></pre>

<p>Will turn the textbox into a spinbox with a minimum value of 0, maximum value of 59 which is not zero-padded at all.<!--b727fffa41e3fa979688b363d2631f5f--></p>
]]></content:encoded>
			<wfw:commentRSS>http://tomas.epineer.se/archives/6/feed/</wfw:commentRSS>
		</item>
		<item>
		<title>Sort by Artist,Year,Album in iTunes</title>
		<link>http://tomas.epineer.se/archives/5</link>
		<comments>http://tomas.epineer.se/archives/5#comments</comments>
		<pubDate>Sun, 12 Mar 2006 21:51:25 +0000</pubDate>
		<dc:creator>Tomas Larsson</dc:creator>
		
	<category>Music</category>
	<category>Apple</category>
		<guid isPermaLink="false">http://tomas.epineer.se/archives/5</guid>
		<description><![CDATA[
I really like iTunes. In fact, after the first time I saw it running on a Mac I desperately searched for a similar application for Linux and almost considered writing one myself (not being 100% happy with Rhythmbox). I instantly knew that was the way I wanted my music organised. After my switch I find [...]]]></description>
			<content:encoded><![CDATA[<p><!--adsense#halfheight-->
I really like iTunes. In fact, after the first time I saw it running on a Mac I desperately searched for a similar application for Linux and almost considered writing one myself (not being 100% happy with <a href="http://www.gnome.org/projects/rhythmbox/">Rhythmbox</a>). I instantly knew that was the way I wanted my music organised. After my <a href="http://www.apple.com/switch/">switch</a> I find that, while good, iTunes is not perfect. My main problem with it is that while you can decide which column you want to order your music by, you can&#8217;t select which column it looks at when two songs have the same value in that column. For example, if you order by Artist it will order the songs by Artist, Album. This means that the albums by a certain artist will be sorted alphabetically, while I want them sorted by year. I find that that&#8217;s how I order the albums in my head, so it takes a while for me to find the album I&#8217;m looking for when they are sorted alphabetically.
<h2>The Solution</h2></p>

<p>If you right click a column header in iTunes, you are able to select which fields are shown. My idea was to put the sort information I wanted into one of these fields. I settled for Grouping, since it&#8217;s one of the fields you can change when you edit the properties of a song. If I put the name of the artist followed by year and then by album into this field, sorting by this field should mean the songs are sorted the way I want them to be. Naturally, manually entering the information into this field would be quite tedious, so I wrote a quick Applescript to do it for me.
<h2>The Code</h2></p>

<p><style type="text/css">
.applescript .de1, .applescript .de2 {font-family: &#8216;Courier New&#8217;, Courier, monospace; font-weight: normal;color: #000020;}
.applescript  {color: #000066; border: 1px solid #d0d0d0; background-color: #f0f0f0;}
.applescript a:link {color: #000060;}
.applescript a:hover {background-color: #f0f000;}
.applescript .head {font-family: Verdana, Arial, sans-serif; color: #808080; font-size: 70%; font-weight: bold; background-color: #f0f0ff; border-bottom: 1px solid #d0d0d0; padding: 2px;}
.applescript .foot {font-family: Verdana, Arial, sans-serif; color: #808080; font-size: 70%; font-weight: bold; background-color: #f0f0ff; border-top: 1px solid #d0d0d0; padding: 2px;}
.applescript .imp {font-weight: bold; color: red;}
.applescript li {font-family: &#8216;Courier New&#8217;, Courier, monospace; color: black; font-weight: normal; font-style: normal;font: normal normal 95% &#8216;Courier New&#8217;, Courier, monospace; color: #003030;}
.applescript li.li2 {font-weight: bold;font-weight: bold; color: #006060;}
.applescript .kw1 {color: #b1b100;}
.applescript .kw2 {color: #000000; font-weight: bold;}
.applescript .kw3 {color: #000066;}
.applescript .co1 {color: #808080; font-style: italic;}
.applescript .coMULTI {color: #808080; font-style: italic;}
.applescript .es0 {color: #000099; font-weight: bold;}
.applescript .br0 {color: #66cc66;}
.applescript .st0 {color: #ff0000;}
.applescript .nu0 {color: #cc66cc;}
.applescript .me1 {color: #006600;}
.applescript .me2 {color: #006600;}
.applescript .re0 {color: #0000ff;}
.applescript .re4 {color: #009999;}
</style></p>

<pre class="applescript" style="overflow: auto; color: #000066; border: 1px solid #d0d0d0; background-color: #f0f0f0;"><ol>
<li class="li1"><div class="de1"><span class="kw1">tell</span> application <span class="st0">&#8220;iTunes&#8221;</span></div></li><li class="li1"><div class="de1">  <span class="kw1">if</span> selection <span class="kw1">is</span> <span class="kw3">not</span> <span class="br0">&#123;</span><span class="br0">&#125;</span> <span class="kw1">then</span></div></li><li class="li1"><div class="de1">    <span class="kw1">repeat</span> <span class="kw1">with</span> this_track <span class="kw1">in</span> selection</div></li><li class="li1"><div class="de1">      <span class="kw1">set</span> this_year <span class="kw1">to</span> <span class="br0">&#40;</span><span class="kw1">get</span> this_track&#8217;s year<span class="br0">&#41;</span></div></li><li class="li2"><div class="de2">      <span class="kw1">set</span> this_artist <span class="kw1">to</span> <span class="br0">&#40;</span><span class="kw1">get</span> this_track&#8217;s artist<span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">      <span class="kw1">set</span> this_album <span class="kw1">to</span> <span class="br0">&#40;</span><span class="kw1">get</span> this_track&#8217;s album<span class="br0">&#41;</span></div></li><li class="li1"><div class="de1">      <span class="kw1">if</span> this_year &gt; <span class="nu0">0</span> <span class="kw1">then</span></div></li><li class="li1"><div class="de1">        <span class="kw1">set</span> this_track&#8217;s grouping <span class="kw1">to</span> this_artist &amp; <span class="st0">&#8220;,&#8221;</span> &amp; this_year &amp; <span class="st0">&#8220;,&#8221;</span> &amp; this_album</div></li><li class="li1"><div class="de1">      <span class="kw1">else</span></div></li><li class="li2"><div class="de2">        <span class="kw1">set</span> this_track&#8217;s grouping <span class="kw1">to</span> this_artist &amp; <span class="st0">&#8220;,&#8221;</span> &amp; this_album</div></li><li class="li1"><div class="de1">      <span class="kw1">end</span> <span class="kw1">if</span></div></li><li class="li1"><div class="de1">    <span class="kw1">end</span> <span class="kw1">repeat</span></div></li><li class="li1"><div class="de1">  <span class="kw1">else</span></div></li><li class="li1"><div class="de1">    display dialog <span class="st0">&#8220;Select some tracks first&#8230;&#8221;</span> buttons <span class="br0">&#123;</span><span class="st0">&#8220;Cancel&#8221;</span><span class="br0">&#125;</span> default button <span class="nu0">1</span> <span class="kw1">with</span> icon <span class="nu0">2</span></div></li><li class="li2"><div class="de2">  <span class="kw1">end</span> <span class="kw1">if</span></div></li><li class="li1"><div class="de1"><span class="kw1">end</span> <span class="kw1">tell</span> </div></li></ol></pre>

<h2>Instructions</h2>

<p>Copy and paste this code into a file (or download it <a href="/files/SetSortField.scpt">here</a>). Save the file to Library/iTunes/Scripts/ in your home directory (you might have to create the Scripts directory if it doesn&#8217;t exist). The script should now show up in the scripts menu in iTunes. Select a few songs and then select the script from the scripts menu. The songs&#8217; artist, year and album should be written to the grouping field. To sort by this field, right-click a column header and click grouping in the list that pops up. Click the grouping header once to sort by this field. Done!
To get easier access to this script you can bind it to a shortcut key, see <a href="http://www.dougscripts.com/itunes/itinfo/shortcutkeys.php">here</a>.<!--dc041b77c738aba241a5fa6fc526e719--></p>
]]></content:encoded>
			<wfw:commentRSS>http://tomas.epineer.se/archives/5/feed/</wfw:commentRSS>
		</item>
		<item>
		<title>Asynchronous file upload with AJAX progress bar in PHP</title>
		<link>http://tomas.epineer.se/archives/3</link>
		<comments>http://tomas.epineer.se/archives/3#comments</comments>
		<pubDate>Sun, 12 Mar 2006 19:24:45 +0000</pubDate>
		<dc:creator>Tomas Larsson</dc:creator>
		
	<category>PHP</category>
	<category>AJAX</category>
		<guid isPermaLink="false">http://tomas.epineer.se/archives/3</guid>
		<description><![CDATA[

One of the few things that I find lacking in PHP is the ability to report the progress of a file upload. This means that file uploads, especially uploads of larger files, can be extremely frustrating for end users when they don&#8217;t know if the upload is progressing or if it has stalled or if [...]]]></description>
			<content:encoded><![CDATA[<p><img align="right" src="/images/upload.png" />
<!--adsense-->
One of the few things that I find lacking in PHP is the ability to report the progress of a file upload. This means that file uploads, especially uploads of larger files, can be extremely frustrating for end users when they don&#8217;t know if the upload is progressing or if it has stalled or if it has even started. There are two ways around this. One is to patch PHP, <a href="http://pdoru.from.ro/">Pdoru</a> provides such a patch. Not everyone can patch PHP though. You can&#8217;t use a patch if you&#8217;re on a shared server, if you want to use ready-made binaries, if you don&#8217;t want to risk stability by using a patch or if you just don&#8217;t want to have to remember to apply the patch again every time you upgrade PHP. The other option is to use a perl script to receive the file when it&#8217;s uploaded. This is the approach used by <a href="http://www.devpro.it/upload_progress/">MegaUpload</a>. MegaUpload is what I have based my solution on, but I have added asynchronous file upload support and an AJAX upload progress bar, instead of the refreshing popup used by MegaUpload.</p>

<h2>Asynchronous file upload</h2>

<p>I wanted to use an asynchronous file upload, like the one on <a href="http://gmail.com/">gmail</a>. This means that the file is uploaded in the background, allowing you to still use the page while the file is being uploaded. Since the XMLHttpRequest object doesn&#8217;t support file uploads, this had to be done using iframes. Whenever the file input changes, the file is uploaded to the cgi-script in a hidden iframe. The cgi-script writes the total size of the upload and the actual uploaded file to temporary files.</p>

<h2>The progress bar</h2>

<p>When the upload starts, a <a href="http://prototype.conio.net">Prototype</a> <a href="http://sergiopereira.com/articles/prototype.js.html#Ajax.PeriodicalUpdater">Ajax.PeriodicalUpdater</a> object is created. This object calls a PHP file twice every second using AJAX. The PHP file checks the temporary files while they are being written by the perl file, and returns the total progress in percentage of total upload size. The percentage value is used to set the width of the progress bar.</p>

<h2>File &amp; Links</h2>

<p>You can download the complete source code <a href="http://tomas.epineer.se/tesupload/">here</a>. There is no live demo at this point (sorry!). Similar projects are <a href="http://www.devpro.it/upload_progress/">PHP Upload Progress</a> which can&#8217;t report total file size and therefore can&#8217;t be used to create a progress bar, and <a href="http://www.air4web.com/files/upload/">Asynchronous image file upload without AJAX</a> (seems to be down at the moment) which has asynchronous upload of files, but no progress bar. Since it always comes up, I&#8217;m also going to mention <a href="http://encodable.com/filechucker/">Filechucker</a>, which is pure perl, doesn&#8217;t do asynchronous file uploads and isn&#8217;t free.</p>

<h2>Limitations &amp; Possible improvements</h2>

<p>It can&#8217;t currently upload two files concurrently in IE or Firefox, but it can in Safari. Haven&#8217;t tested other browsers. It requires Prototype at the moment (included in the archive above) which some see as a downside because of its size. It doesn&#8217;t report speed of download. Upload speed is printed when using MegaUpload, so porting that to work with this code wouldn&#8217;t be difficult.</p>

<p><em>Update:</em> The script now has a <a href="http://tomas.epineer.se/tesupload/">permanent home</a> and a name: tesUpload.<!--e6eaa31efc2e7de14d3644fd3475625b--></p>
]]></content:encoded>
			<wfw:commentRSS>http://tomas.epineer.se/archives/3/feed/</wfw:commentRSS>
		</item>
	</channel>
</rss>
