Monday, July 26, 2010

Share Chrome web apps with DropBox, use them in Launchy

Lets see if we can kick this blog back to life a little bit.

I have a nasty habit of leaving tabs open for a very long time in my main browser window. I have 12GB of RAM in my main machine, and usually only boot once a month or so (whenever I finally give in and install the critical Windows updates etc), so this isn’t a problem as such. However, I thougth there must be a better way to handle this. Bookmarks are where URLs go to die for me – how can I stay up to date on the sites I use all the time? This is compounded by the fact that I spend much of my time on three different PCs – my main home machine (Windows 7), my personal laptop (Vista for now), and my workstation at work (Vista for now as well).

Most people familiar with the applications mentioned in the headline will probably see where I am going with this just by reading that line. For the rest, however, here is a short intro to each of them:

Google Chrome is my current browser-of-choice. It is fast, appears to be light-weight, has some nice extensions (Adblock and other lifesavers), is very fast (especially on the javascript side) and quite free. I am fairly browser agnostic, so I have them all, but Chrome is the one I keep using. It has a nice feature where you can create a “web app”. This basically makes a shortcut on the desktop to this web app, which then opens in a window by itself without the URL bar etc.

DropBox gives you one or more folders on your computer that will be synced between the machines you install it on. Cool for keeping ebooks, common configs, works-in-progress etc. up-to-date even when moving between machines. A 2GB account is free. You can also pay a modest sum for larger accounts.

Launchy is probably the most-used (measured in number of invocations) utility I have. I try to be mouseless to be more effective (and save my wrists), and Launchy takes me there. By pressing a quick keyboard shortcut (mine is alt-escape, the default is something different) I get a window where I type what I want to run. It is relatively smart about finding the right thing based on what you type. You can use it as a calculator etc. And I can start applications a LOT faster than mousing through the start menu. Get it. You’ll be glad you did.

Okey, so we got all three installed. See where this is heading? The basic idea is to define Chrome web apps for sites I use a lot (Stack Overflow and the ever increasing amazing sister sites, GMail, Google Reader / Feedly, LinkedIn, Facebook, GitHub, AgileZen, FogBugz, etc.), share them in a DropBox folder, and then have Launchy scan that folder and use what it finds there as shortcuts. So whenever I need to check my GMail account, I press Alt-Esc – G – M – Enter, and the window is there. Quickly and – dare I say it – with a minimum amount of pain.

There really isn’t much to it. There is only one small trick you have to do, and one very minor thing I didn’t figure out yet.

1. Go to the site you want to turn into a web app in Chrome.

2. Push the document-looking button top right and choose to create a web application (currently the top choice in my Chrome).

3. Choose to create the shortcut on the desktop.

4. Find the shortcut on the desktop. Open the properties window for it.

5. Open a Windows Explorer window (Windows-E). In the address bar, type %localappdata% and press enter.

6. Notice that the start of the value in the “Target” field in the properties window for the shortcut and the address bar in the Explorer window now are the same. Replace the part in the properties window that is the same as the address bar of the Explorer window with %localappdata%. This could turn out to be very important, as Chrome doesn’t install in the Program Files folder – rather, it installs in your local app data folder so that anyone can install it without being an admin. This is nice and all, but if you’re sync’ing with dropbox to computers where the local app data folder is different (different username, different OS), the shortcut won’t work.

7. Store the updated shortcut by clicking OK in the properties window.

8. Create a folder in your DropBox – I called mine Apps – and move the shortcut there.

9. Configure Launchy to scan this folder. To do this, press your Launchy shortcut, then Ctrl-, (control comma). Go to the Catalog tab, press the + button, and add the DropBox\Apps folder. In the “File Types” group, add “*.lnk” as a pattern. Rescan the catalog and press OK to escape the Launchy options window.

10. Repeat pt. 9 for each computer that you’re syncing via DropBox.

So what did we achieve with this? Whenever you start using a new web site regularly, create a shortcut as instructed here, and it will be available on each computer you work on. You will of course have to log in to the web app / site on each computer.

The one small thing I mentioned that I didn’t figure out yet is how to get the icons for the web apps across – but Chrome takes care of that after the first run (i.e. second time you open that web app on a computer, Launchy will also display the correct favicon), so it wasn’t worth angsting over.

I hope this is useful to someone besides myself. :)

Saturday, March 07, 2009

Scaling images while keeping aspect ratio and max size

In an application I am writing, I recently came across the need to accept uploaded pictures and scale them to a set size for inclusion in a table. Simple stuff, just a “let’s make all pictures the same size for easier layout” kind of deal. Say the “target” size was 800x600, and given a size originalSize, the function needs to figure out a new size for the image that meets the following demands:

1. The entire image must fit inside the target size.

2. The image must keep its’ aspect ratio.

3. The size of the new image must never be larger in either direction than the original (no upscaling)

4. The image must be as large as possible without breaking the three other rules.

After a few days of wrapping my head around this (and doing other stuff), I realized it was all the aspect ratio – which way we used to calculate the width/height that should be returned, depends entirely on which of the aspect ratios are larger; That of the original image, or that of the target size.

I of course started with the unit tests – a MbUnit RowTest with 20 rows of different combinations of picture sizes, new sizes, and expected result sizes. I had done all the calculations on paper in advance and was pretty sure they were correct.

After a little bit of experimentation, I ended up with this method:

  1: public static Size GetRenderSize(Size originalSize, Size targetSize)
  2: {
  3:     float targetRatio = targetSize.Width / (float)targetSize.Height;
  4:     float imageRatio = originalSize.Width / (float)originalSize.Height;
  5: 
  6:     if (imageRatio < targetRatio) // Target ratio is wider than the source ratio, scale by height
  7:     {
  8:         var smallerY = Math.Min(originalSize.Height, targetSize.Height);
  9:         return new Size((int)Math.Round(smallerY * imageRatio,0), smallerY);
 10:     }
 11:     // Target ratio taller than source ratio or the same - scale by width
 12:     var smallerX = Math.Min(originalSize.Width, targetSize.Width);
 13:     return new Size(smallerX, (int)Math.Round(smallerX / imageRatio,0));
 14: }


A lot simpler than I thought, and seems to give correct results on each and every calculation. :)

Wednesday, February 25, 2009

Silverlight vs. FireFox

After struggling with getting some Silverlight (2.0) apps working in FireFox (v3), I thought I’d post the solutions here so that I can find them easily in the future.

The first problem was getting the application to load in the first place. In one of the parameters to the <object> that will represent your application, you pass in a ‘data’ parameter, like this:

data="data:application/x-silverlight-2,"

See that pesky little comma after the “2”? Well, without it, your app probably won’t show up in FireFox, at least mine wouldn’t. It works fine in IE and Chrome, but no way the ‘fox would love it.

The second issue seems to be that if you give your app a percentage height, and the outer elements don’t have a set height themselves, you could end up with an application with a height of 0 pixels – which means there is nothing to show. Fortunately other people have already figures this out, such as this here guy, who I thank for saving me some gray hairs. :)

That’s it!

Sunday, January 11, 2009

Making a dropdownlist in ASP.Net MVC from an enum

Some times your business objects use a simple enum to indicate something, for instance a status. For one of my projects I have a TaskStatus defined like this:

public enum TaskStatus
{
    NotStarted,
    InProgress,
    Waiting,
    Finished,
    Cancelled
}

Nothing exciting here. Now I want to turn this into a SelectList that can be used with the Html.DropDownList helper. Turns out this is embarrassingly easy using LINQ and anonymous methods:

  1: var statuses = from TaskStatus s in Enum.GetValues(typeof(TaskStatus))
  2:                select new { ID = s, Name = s.ToString() };
  3: ViewData["taskStatus"] = new SelectList(statuses, "ID", "Name", task.Status);


Now I can just use it in my view using the helper method:



  1: <td><b>Status:</b></td><td><%=Html.DropDownList("taskStatus")%></td></tr> 


Easy peasy. :)

Monday, December 01, 2008

You can’t do that in WPF?

One of the things that virtually everyone talks about whenever they start learning WPF is how amazing the experience is – there are virtually no limits to the amazing stuff you can do. Or put in a different way; The hard becomes easy, the impossible becomes possible.

However, one thing I have not found a way to do (and which is apparently not currently possible, according to the answer I got on StackOverflow.com), is how to handle databinding in the case where you want to bind to an interface, and not the actual object.

In my case, I have a list of business objects that represent the ItemsSource for a ListBox. Each of these objects contains two other objects. These objects can be one of several different types, the only thing they have in common is that they implement a specific interface. The problem here is that the ItemTemplate I use cannot refer to the Interface properties – the binding engine will only see the object as the type it really is, not the interface.

While this isn’t a HUGE thing, it is a weakness that would be very nice to be able to work around in an upcoming update of WPF.

Thursday, November 06, 2008

WPF ComboBox binding to LINQ to SQL

This is mostly for my own use – I am senile enough to run into this problem again in the future.

Like all controls in WPF, the ComboBox is full of configurability and extensibility. This can get quite hairy quite quickly – and if you set the wrong parameters when you databind to a LINQ to SQL data source, really funky stuff can happen.

So here is something that worked for me:

<ComboBox Grid.Column="1" Grid.Row="1" VerticalAlignment="Center" IsEditable="False"   
          Margin="10,2" 
          ItemsSource="{Binding Path=Produkt.Modeller}"  
          DisplayMemberPath="Modell"  
          SelectedValuePath="Modell"  
          SelectedItem="{Binding Path=ProduktModell}"  
          />
ItemsSource is relatively easy – just point at the collection of options.


DisplayMemberPath is also relatively easy – it just tells WPF what to display in the ComboBox.



But SelectedValuePath and SelectedItem took some experimentation to get right – the above works for me, but with some variation came some pretty strange bugs. Models being renamed and stuff.



So now I know.

Sunday, October 19, 2008

Book impression – Programming WPF

So, I was a complete newbie when it came to WPF, but because of Sloth and other applications, I was curious about what this was, as I must admit that UI programming in Windows has been a serious annoyance. Perhaps that’s the way it has to be when you come from a background of Amiga programming, with som web stuff thrown in for good measure.

I think I can safely say that I now have a pretty good grasp of how I can use WPF for creating better experiences for the users of my software. There are a lot of things I can do now that I couldn’t before, and the whole layout model makes a lot more sense. Declarative programming is definately the way to go when it comes to GUI programming, IMHO.

So, what about the book? Well, like many programming books, it’s hard to just read it without a keyboard and a compiler nearby. You want to try out the stuff as you go along, and the book rightly encourages you to do so. The logical progression of things felt a little off at times, and in places it felt more like a reference book than an end-to-end learning experience. Particularly when it came to look at data binding, I must admit I struggled a bit; Their explanations were very good, but I left those chapters feeling like the authors should have given more attention to databinding towards CLR objects; After all, WPF representing the presentation layer, I would expect most non-trivial applications to have some model data to show; It won’t all be created as part of the XAML.

Other than small gripes like this, I feel like I have a pretty good idea of the things you can do with WPF. Of course it doesn’t touch on features of .Net 3.5 Sp1 such as the possibilities of creating grid views (the book came out long before Sp1), so while this is not the fault of the authors, if you want to learn about the new features of Sp1, you have to look elsewhere.

So, is this brick worth reading through? If you’re stuck with WinForms and want a better way to do things, go for it! There is a lot you can do with WPF that would be very hard with the old ways, and I for one believe that WPF represents the future of UI programming. I will surely use it for my coming client applications, and I will keep this book nearby as a handy reference.

My copy of the book is “Programming WPF, Second Edition”. It is published by O’Reilly, and authored by Chris Sells and Ian Griffiths.