thingsinjars

  • 16 Sep 2023

    My Books

    Not Geek, Ideas

  • 14 Dec 2009

    What's your Google Suggest number?

    • What's your Google Suggest number?

    The next step in ego-googling: how many letters of your name do you need to type into the google search box before you are the top suggestion? The lower the better, obviously. Including spaces, My name is the top suggestion after 10 characters so I have a Google Suggest Number of 10. My darling wife (who has recently changed her name) has a Google Suggest number of ∞ as she can type in her whole name and Google doesn't suggest her.

    Turns out somebody proposed this first over 5 years ago. Oh well. Nothing's new on the internet.

    Geek

  • 10 Dec 2009

    Side Tab

    • thumb of my Opera layout

    After reading Aza Raskin's post about Firefox moving its tabs down the side of the window, I decided to give it a go in Opera. It turns out to be very useful when you have a widescreen monitor. I usually end up with several dozen tabs open at once and it's much easier to be able to put them down the side in an area which is, for most websites at least, dead space. On the rare occasions I do find myself on a website which requires more than the 1470px horizontal space this gives me, I can just tap f4 and get my full 1650px back. As the window sidepanel also groups by window and lists all tabs open across all windows, I can keep them ordered thematically, too.

    This arrangement definitely doesn't work, however, when you have a small screen. When I tried this on my netbook, I had to choose between losing half of my screen to the tab list or only being able to read the beginning of each page title, even if I only had one tab open.

    A quick aside, when I first read about moving tabs down the side, my initial thought was "It's a shame Opera doesn't have add-ons, I'd like to give this a go" and very nearly fired up Firefox before I realised that Opera already has this functionality and has had since (approximately) version 5 (almost 10 years ago). Just sayin'.

    Geek, Opinion, Design

  • 7 Dec 2009

    Some simple tips

    The views and opinions expressed within are not those of National Museums Scotland. This site is in no way affiliated with National Museums Scotland or the website www.nms.ac.uk

    First of all, the disclaimer: I am not a designer. If I were to make claim to being anything creative it's an illustrator but there's a huge difference between the two (I've always said that an illustrator makes the thing to go on the t-shirt, the designer says where on the t-shirt it goes). Despite the recent trend for everyone to call themselves web designers, I'm still going to go by web developer. I make things.

    Bearing that in mind, there are still quite a few web design and UX tips and techniques I've picked up along the way which can be applied to most sites and not interfere with the mysterious ways of designers.

    Recently, I've been reworking templates for National Museums Scotland for faster load times and better SEO and I'll illustrate what I'm talking about with a couple of examples from there. The brief on these templates is that the content can't really change and there are some chunks that the CMS generates which can't be changed. Note: the NMS templates are completely finished yet and those that are haven't been rolled out across the whole site but sticking with that whole release early, release often way of doing things, these little incremental improvements can be applied without affecting too much else.

    For reference, here are before and after screen grabs of two of the templates.

    • Our Museums Before
    • Our Museums After
    • Museum gateway before
    • Museum gateway after

    Some people will find these tips blatantly obvious but the fact that pages still get made without considering these means they do need reiterating.

    Link the Logo

    The web's been around for a few years now and there are a few conventions users have gotten used to. One of them is that the logo is a link that takes you back to the home page. It doesn't harm anything to have a link there so even if 99% of visitors don't use it, why annoy the 1% who do?

    Don't link to the search

    From the moment the visitor decides they want to search your site for something, the most important thing is to get the results in front of them as quickly as possible. It therefore makes for a better experience if you bring the results one step closer to them. Rather than requiring the user to click on a link to get to the search form to do their search to get the results, put the search box on every page. They fill it in and go to the results page. If the user wants to take advantage of any advanced search features you may have, they can modify their search from the results page.

    Search box positioned within header

    Note: the new template still contains a link to the search page due to some legacy requirements. I don't actually recommend this.

    Line up

    • thumbnail of layout not aligned
    • thumbnail of layout aligned

    I'm sure there's more to design than this but there are a couple of well tested rules I recommend any non-designer to learn:

    1. If it doesn't line up, make it line up.
    2. If it's already lined up, make it not.

    That and a subscription to iStock and you're done...

    Note: This was a joke, real designers please don't stab me with your crayons.

    Make the hit area as big as possible

    • Thumbnail of gateway panel comparison
    • Thumbnail of gateway panel hit area comparison

    From the gateway page for Our Museums, there are two ways the user could go. They were either looking for opening times (in which case, they're done), or they want to find out more information about the individual museums on their own pages. To that end, it makes sense to make the next step as easy as possible and bascially turn the content this page into six huge buttons. To keep everything semantic, JavaScript has been used here to extract the destinations from each of the links and apply them to the whole panel area (it'll default to linked text and image with JavaScript disabled). As you can see, doing this changes the hit area for each museum from a line of text to a veritable barn door.

    White text on a white background is not good

    • white text laid over white background
    • white text laid over black background

    Actually, I'm not sure whether it's the fact that the link wasn't as readable as it could have been or the fact that to go home requires poking her in the eye that upset me most. Either way, if you do need to use an image that has a light bit underneath some light text and you can't shuffle it along like here, a quick wipe with the burn tool in Photoshop works wonders.

    Underline links

    I'm not going to get into the debate over whether or not designers hate underlines but for a high-traffic, public sector with an extremely varied demographic, I'd recommend using them. As Paul Boag mentions, what you do with your design and your solutions for various usability issues depends on the audience. A graphic designer's portfolio might very well eschew underlines when denoting links, a government site probably shouldn't. Especially when you remember that you should never rely on colour alone to convey information, including whether not a piece of text is a link.

    Titles are titles of something

    • titles far away from paragraph text
    • titles near paragraph text

    If you have a title, it generally refers to the thing below it, not the thing above it. Make sure you keep titles and the things they are titles of together.

    Avoid disparate navigation

    • navigation split over two areas
    • navigation combined into one area

    Again, another of the rules of web that has evolved over the last several years: Sections go along the top, navigation down the side. To keep consistent with the rest of the site the horizontal museum links were brought down and integrated with the rest of the navigation. This maybe isn't the most illustrative example but, basically, don't have a top nav, left nav, right nav and several others when you could have just one.

    Only a fraction

    There we are, a few handy little tips for your next build project. This hasn't gone into any issues of column width, line-height - or leading (pronounced /ˈlɛdɪŋ/) as designers call it, hover states or any of the myriad other things it could, just a few of the more important and easy-to-do ones.

    Geek, Design, CSS, Javascript

  • 1 Nov 2009

    Building an Objective-C growlView

    Wherein our intrepid hero learns some Objective-C and figures out the easy bits are actually quite hard.

    This is a little guide on how to write a growl plugin to automatically send notifications as tweets. If you just want the finished thing: GrowlBird.zip [Zip - 228KB]

    A couple of days ago, I decided to give myself a little software development task to write a Twitter Growl view. Growl is a centralised notification system for Mac OS X that lots of other applications can use so that there's one consistent way of showing notifications.

    Background

    The idea behind this little experiment wasn't to have tweets appear as growl notifications, there are already plenty of apps that do this, the idea was to have growl notifications sent to Twitter. Some friends have started organising a crowdsourced Friday afternoon playlist via Spotify and I thought it'd be handy if Spotify tweeted each song as it started. The easiest way I could think of doing this was to tap into the fact that Spotify sends a Growl notification on track start and get the Growl display plugin to tweet it as well [1].

    Build

    I downloaded the Growl Display Plugin Sample 1.2 [Zip - 186 KB] from the developer downloads page and the MGTwitterEngine library. I then downloaded Xcode so I could do the development. I have to point out here that this was my first foray into Objective-C programming and, indeed, my first attempt at anything vaguely C-related since I wrote a command-line calculator about 12 years ago. If I do it wrong, please forgive me.

    The first thing to do was open the sample project in Xcode, figure out what files do what, etc. There is very little documentation on how Growl views or display styles work so I pretty much just spend an hour reading all the source from top to bottom. Here's a quick summary:

    Sample_Prefix.pch
    Pre-compiled header. Stuff that's included before every pre-compiled file
    Growl/
    Folder containing standard Growl stuff. Don't need to touch.
    GrowlSampleDisplay.h
    Header file, didn't need to change anything
    GrowlSampleDisplay.m
    Class for setting up things. Again, didn't touch [2].
    GrowlSamplePrefs.h
    Defining default preference values and naming functions to handle them. More on this later.
    GrowlSamplePrefs.m
    The actual functions mentioned in the previous header file
    GrowlSampleWindowController.h
    Not doing anything visual, really so I didn't need to mess around with this
    GrowlSampleWindowController.m
    As above
    GrowlSampleWindowView.h
    Declaring objects needed for execution
    GrowlSampleWindowView.m
    Instantiating the objects then actually using them later on.

    Again, I'm not used to doing this stuff so if I'm using the wrong terminology, just pretend I'm not.

    I then dragged the MGTwitterEngine library into the project drawer, saved and built. At this point it successfully did nothing different which is what I was hoping it would do. Well, it popped up the 'This is a Preview of the Sample Display' message using the MusicVideo style which is what it does when you don't screw with it.

    Testing growlView

    It's not actually that easy to test growlView plugins. You can't simply add and remove them. To install, you double-click on it. You should be able to see it listed in the Display tab of the preference pane. To re-install, you need to delete ~/Library/Preferences/com.Growl.GrowlHelperApp, ~/Library/Application Support/Growl/Plugins/Sample.growlView and restart growl (click on the paw in the menu bar). It's a bit of a hassle.

    The next thing was to include the MGTwitterEngine. In GrowlSampleWindowController.h, #import "MGTwitterEngine.h" and create a new object. I just followed the instructions in the README but be sure to follow all of them. If you get errors about LibXML not being installed or YAJL not working, don't worry, you just need to make sure you set USE_LIBXML to 0 in all the places you're supposed to. GrowlSampleWindowController.h now contains this:

    
    #import "GrowlDisplayWindowController.h"
    #import "MGTwitterEngine.h"
    
    @class GrowlBirdWindowView;
    
    @interface GrowlBirdWindowController : GrowlDisplayWindowController {
    	CGFloat						frameHeight;
    	NSInteger					priority;
    	NSPoint						frameOrigin;
    	MGTwitterEngine *twitterEngine;
    }
    @end

    In GrowlSampleWindowController.m, I then instantiated the new object:

    
      @implementation GrowlBirdWindowController
      - (id) init {
      	  :
      	  :
          twitterEngine = [[MGTwitterEngine alloc] initWithDelegate:self];
    	    [twitterEngine setUsername:@"growlbirdtest" password:@"testgrowlbird"];
    	  }
    	  :

    And then modified the setNotification function to also send an update:

    
    - (void) setNotification: (GrowlApplicationNotification *) theNotification {
        :
    	[view setTitle:title];
    	[view setText:text];
      NSLog(@"sendUpdate: connectionIdentifier = %@", [twitterEngine sendUpdate:[NSString stringWithFormat:@"%@, %@", title, text]]); // The new line
      :
      }

    That was enough to get growl to send messages to appear on http://twitter.com/growlbirdtest but it doesn't make it that useful for anybody else, to be honest. The next thing to figure out was the preferences.

    Preferences

    Without documentation, this took a bit longer that I expected. To start off changing the english version before worrying about localization, find the GrowlBirdPrefs.xib in resources/en.lproj/ and open it. Interface Builder will launch then you can double-click on 'Window' and see the layout of the preference pane. Search in the Library for 'text' and drag a text field into the window then spend about half and hour clicking round the interface. Open up the various inspectors (right-click on an object), look through the different tabs, click between the newly added text field and the sliders and drop-downs that are already there just to see what's different. Once I was a bit familiar, I opened the connections tab so that I could bind the value of the text field to the value 'twitterUsername' in my code. I checked 'value', Bind to 'File's Owner' and entered 'twitterUsername' in Model Key Path. I then repeated this for twitterPassword using a Secure Text Field from the Library. The option nextKeyView is used to say which item is tabbed to next when you're navigating with the keyboard so to keep things tidy, I dragged lines from nextKeyView from each of them to the right places in the layout.

    Back in the code, I added new default preferences in GrowlSamplePrefs.h:

    
      #define Sample_USERNAME_PREF		@"Username"
      #define Sample_DEFAULT_USERNAME		@"growlbirdtest"
    
      #define Sample_PASSWORD_PREF		@"Password"
      #define Sample_DEFAULT_PASSWORD		@"testgrowlbird"
      :
      :
      @interface GrowlBirdPrefs : NSPreferencePane {
      	IBOutlet NSSlider *slider_opacity;
      	IBOutlet NSString *twitterUsername;
      	IBOutlet NSString *twitterPassword;
      }

    and named some handlers for them:

    
      - (NSString *) twitterUsername;
      - (void) setTwitterUsername:(NSString *)value;
      - (NSString *) twitterPassword;
      - (void) setTwitterPassword:(NSString *)value;

    Be careful here, I got confused and didn't have the same spelling here for twitterUsername and twitterPassword as I had put in the interface builder as I hadn't realised the two were directly connected. They are. Obviously. The next thing to do is to write the code for these handlers:

    
      - (NSString *) twitterUsername {
      	NSString *value = nil;
      	READ_GROWL_PREF_VALUE(Sample_USERNAME_PREF, SamplePrefDomain, NSString *, &value);
      	return value;
      }
      - (void) setTwitterUsername:(NSString *)value {
      	WRITE_GROWL_PREF_VALUE(Sample_USERNAME_PREF, value, SamplePrefDomain);
      	UPDATE_GROWL_PREFS();
      }
      - (NSString *) twitterPassword {
      	NSString *value = nil;
      	READ_GROWL_PREF_VALUE(Sample_PASSWORD_PREF, SamplePrefDomain, NSString *, &value);
      	return value;
      }
      - (void) setTwitterPassword:(NSString *)value {
      	WRITE_GROWL_PREF_VALUE(Sample_PASSWORD_PREF, value, SamplePrefDomain);
      	UPDATE_GROWL_PREFS();
      }
    

    Build and reinstall and this will now show the same preference pane as before but with two new text fields which allow you to enter your username and password. In fact, build at several stages along the way. Every time you make a change, in fact. If something breaks, check the error log to see if it's something predictable that should have broken at that point or if you've done something wrong. Also, keep the OS X log app Console open in the background. It will spew out error messages if you do something wrong. It's also good to have your code write out console messages to keep a track on what your code is doing like so:

    
      - (NSString *) twitterPassword {
      	NSString *value = nil;
      	READ_GROWL_PREF_VALUE(Bird_PASSWORD_PREF, SamplePrefDomain, NSString *, &value);
      	NSLog(@"twitterPassword = %@", value);
      	return value;
      }
    

    You'll notice we're still sending messages to the growlbirdtest account because, even though we are reading and saving the username and password, we're not doing anything with them. That's easily remedied by editing GrowlSampleWindowView.m again and replacing the hard-coded login details with a couple of lines to read from the preferences or fall back on the default:

    
      twitterEngine = [[MGTwitterEngine alloc] initWithDelegate:self];
    	NSString *twitter_username = Bird_DEFAULT_USERNAME;
    	NSString *twitter_password = Bird_DEFAULT_PASSWORD;
    	READ_GROWL_PREF_VALUE(Bird_USERNAME_PREF, SamplePrefDomain, NSString *, &twitter_username);
    	READ_GROWL_PREF_VALUE(Bird_PASSWORD_PREF, SamplePrefDomain, NSString *, &twitter_password);
    	[twitterEngine setUsername:twitter_username password:twitter_password];
    	NSLog(@"Twitter Login: username = %@", twitter_username);
    

    And, hooray! It works and posts to the account for which you entered details. Sort of. Some apps double-post. I haven't figured out why yet.

    Renaming

    After all that, the final bit (which I thought would be the easiest) was to rename the growlView from 'Sample' to 'Bird'. I have read that in the latest version of Xcode (which presumably comes with Snow Leopard), there's a global 'Rename' which will do all the relevant stuff for you. If you don't have that, you'll need to read 'On the Renaming of Xcode Projects' and do everything there. If you're still finding your growlView is called Sample, manually open every Info.plist you can find, 'Get Info' on everything, scour through the settings for the different build environments (Debug and Release)... It took longer to rename the project than to actually build it.

    A trivial aside, I have also added two fields to the preferences for tweet prefix and tweet postfix in exactly the same way the username and password were added. I leave the details to the interested reader.

    You should now have a completed, installable growlView/Growl View/Growl Display/growlStyle/whatever it's actually called. You can export the current Git project to have a look around or you can just download the finished GrowlBird.zip [Zip - 228KB] if you like. Note, the Git project isn't guaranteed buildable at any moment in time, I might break it. The localisations still need done and the layout of the prefPane isn't the greatest, either.

    [1] Since writing this, I have discovered that someone else already made a growlView to do this, it just didn't show up on any of my Google searching.

    [2] It turns out that I did have to modify these in the end due to a silly bug. Like I said, this is my first attempt at this kind of thing.

    Geek, Development

  • newer posts
  • older posts

Categories

Toys, Guides, Opinion, Geek, Non-geek, Development, Design, CSS, JS, Open-source Ideas, Cartoons, Photos

Shop

Colourful clothes for colourful kids

I'm currently reading

Projects

  • Awsm Street – Kid's clothing
  • Stickture
  • Explanating
  • Open Source Snacks
  • My life in sans-serif
  • My life in monospace
Simon Madine (thingsinjars)

@thingsinjars.com

Hi, I’m Simon Madine and I make music, write books and code.

I’m the Engineering Lead for komment.

© 2025 Simon Madine