The Axamblis Blog » 2009 » November
Developing Software is an Art.
Cocoa — Wednesday, November 11, 2009 4:27

F-Script: The Ultimate Debugging Console

Have you ever heard of F-Script? If you are a Cocoa developer I honestly hope you do. For those of you who haven’t, F-Script is supposed to be “A set of open source tools that complement Xcode and Interface Builder” that provide “Interactive introspection, manipulation and scripting of Cocoa objects”. So its a bunch of tools that allow you to interact with Objective-C and Cocoa during runtime through its own scripting mechanism, whose syntax differs significantly from the Objective-C language. So the line of source code…

1
MyClass * var = [[MyClass alloc] initWithName:@"John"];

is written like the following in F-Script:

1
var := MyClass alloc initWithName:'John'

If you download F-Script from www.fscript.org you end up with a bundle full of source code, executables and useful information. The most important are F-Script.app, FScript.framework and Extras/F-Script Anywhere.

Exploring Cocoa

The first file I mentioned — F-Script.app — is the toolchain in its simplest form: A script interpreter console. So what you can do is write your script lines to the console which will then be executed by the F-Script interpreter. For example: Writing the script line

1
NSApplication sharedApplication terminate:nil

will make the application quit. But more interestingly, it gives you access to everything that is currently loaded into the Objective-C runtime. So you may create a window and populate it with UI through the F-Script console. Everything you can do from code in Xcode, you can do in F-Script through the console.

Debug Your Application

The second file — FScript.framework — is the most important one for developers. As you might guess, it is a framework that bundles all the F-Script functionality. If you’re writing a Cocoa application, add FScript.framework to your project and link against it. Somewhere in your loading code, insert the line

1
[[NSApp mainMenu] addItem:[[[FScriptMenuItem alloc] init] autorelease]];

to add the F-Script menu to your main menu bar. What this gives you is a complete and immensly powerful scripting environment that is available to you at runtime. When you launch your app, go to the “F-Script” menu and choose “Show Console”. A new script interpreter will pop up ready to execute input from you through which you have access to all your objects: If your app has a controller object assigned as the app’s delegate, enter

1
controller := NSApplication sharedApplication delegate

to assign the object to the controller script variable. So if your controller features the method -makeNoise, you can go ahead and hack

1
controller makeNoise

into the script console and BOOM, your method gets called. What can you use this for? Obviously there’s no point in calling methods from the console that can also be executed through the press of a UI button. But if you’re developing a huge application that has some very complex functionality at its core, you’re very likely to end up with the situation that your core functionality is written and needs debugging, but lacking a user interface your app is not ready to take advantage of its core. Nevertheless you would like to debug the core you’ve written without having to go through the hassle of UI design yet. This is where F-Script comes in really handy. Launch the app, open the F-Script console and start debuggin your core! It’s all there right at your fingertips, ready to be thoroughly tested and evaluated, checked for bugs and all the other nasty app-killers.

That’s exactly what I did with Artifica today. Obviously writing a user interface for an application with the complexity of an image editor is no easy task and introduces a completely new source of bugs to your application. Therefore, I wrote the layer architecture from A to Z with the only testing UI available being a NSView that draws the final result of the layer rendering. As usually, after finishing the layering mechanism and launching the app for a try, everything stayed gray and empty. Bug. So I thought about the best way of debuggin the app. Writing some debugging code that created layers somewhere in the launch code of the app? Nah… that’s kind of lame and not very efficient. That was when I remembered F-Script. So I went to the website, grabbed my copy of it and added the framework and menu item to my app. And suddenly I was able to conduct the most thorough testing of my layers without having to create some testing UI for doing so. But not only does F-Script serve as a replacement for UI, it is also very useful for debugging. If you set one of your layer’s properties for example and nothing changes on the final result, you can use F-Script to inspect the layer object and look for where your updating mechanism broke down.

F-Script adds an invaluable means of debugging to your application. Things that were very uncomfortable to do beforehand, now are easy and fast. And if you have some frequently used object, for example your controller object, all you have to do is simply call

1
2
FSInterpreter * interpreter = [[fscriptMenuItem interpreterView] interpreter];
[interpreter setObject:[NSApp delegate] forIdentifier:@"controller"];

with fscriptMenuItem being the FScriptMenuItem you added to the main menu before. This line will assign your app’s delegate to the “controller” script variable which you may then use during debugging to directly access your controller object.

Code Injection

The third important part of the tools is the F-Script Anywhere application. What this application does is that it allows you to inject F-Script into running Cocoa applications. When you do that, the running application gets a “F-Script” menu item which gives you a means to inspect and experiment with that app through the console and object browser. This technique is very useful if you want to know how some of the private APIs work or just want to know how another application is structured.

F-Script saves the Day

Being very robust and extremely powerful, F-Script is the ultimate tool for debuggin, inspecting or hacking other applications. As a developer, the most valuable thing you can do with F-Script is to include the framework into your application and use the console and object browser for debugging. It saves you hours of debugging hassle since you don’t have to return to your source code and recompile everytime you want to check whether some operation returned a valid value. But most of all, you don’t have to write any specific debuggin code to your app except the creation of the menu item and maybe the declaration of the most important objects in the F-Script namespace for easy access.

If it weren’t for F-Script, I would have spent 5 hours today writing debugging code and creating some testing UI for Artifica which would have been another source for bugs which increases complexity of the debugging process again. F-Script gives you the possibility to completely split up the development of your object model and your view model, which not only saves you a lot of time and is more productive, but is also less frustrating since you never have to go figure whether your app’s functionality is broken due to a bug in the UI, the object model or even worse, somewhere in between.

— — —

Thanks for reading and enjoy coding with F-Script! It really is worth the 20 minutes of getting used to the scripting syntax!
Cheers

Artifica — Tuesday, November 10, 2009 16:01

Accessibility for Noobs* and Pros**

* short for “Newbies” — ** short for “Professionals”

Depending on what kind of application you write you end up having to deal with the more or less complex task of making the software attractive to a wide range of users. If you develop a Twitter client, there’s literally only one group of users: those who want to Twitter. Every user wants to be able to write a Tweet, read those of others and maybe view the Tweets where he was mentioned. There’s no feature that would overburdern the average user’s computer skills.

The Problem

Unfortunately, the genre of image editing software is probably the one featuring the widest range of users: There is the average user that knows what an aperture is and how a camera takes a picture, which wants to retouch his pictures exposure and color tones. Then there’s the user whose only concern is the size and weight of the camera when he’s buying one. He wants to have one button in his image editor which adjusts exposure and color tones automatically. And last but not least, there’s the professional ultra-skilled über-user which has a thorough understanding of everything from the architecture of the camera’s CCD sensor up to the background layer architecture and image data processing of his image editor. How do you make the app attractive to all these types of users?

Solving this problem is like designing an aircraft which a child can fly from Zürich to New York and a fighter pilot can do the wildest air acrobatics with, yet both immediately feel comfortable and in control when sitting in its cockpit. So how do you prevent the child from turning off the autopilot accidently but not have the pilot to go through 20 layers of security before granting him full control over the bird?

This is exactly the problem I’m working on at the moment. The layer architecture of Artifica (yes, the app has been named) as intend to engineer it is of a complexity never seen before. Drawing one layer incorporates the evaluation of 5 filters and about 10 intermediate drawing steps, user filters not included. The newbie might probably not even want to get in touch with layers in general. On the other hand, the professional user might not only want to use layers, but also access and adjust certain steps of the layer rendering process. Take filters for example. There are three points in the layer rendering process where a user might want to add a filter to the color channel: At the beginning on the color information of the layer, in the middle after the sublayers have been rendered onto the color information, and at the end when the layer is through the masking process. Adding a blur filter yields to different results at each of these points.

The possible Solution

Fortunately, almost all users have one thing in common: They like tidy and functional user interfaces. A professional user will probably not complain about having to click a button to bring up the powerful controls he might want to use on an image. He’s thankful if that control doesn’t pop up everytime he opens an image: He might only want to look at the image, crop it, or just hit the “auto-adjust exposer and lighting (noobs only)” button!

So there goes the partial solution: Making only a very small part of the functionality available through the interface that is presented to the user whenever an image is opened. So there might be a window for color controls which actually adds an image filter in the background and provides an opaque way of modifying it. No layer lists, no complicated tools, nothing. But the more advanced user mustn’t have to click more than one button, one menu item to bring up the layer list and advanced tools. Maybe the app should try to guess the user’s intentions. And by that, I don’t mean the Microsoft way of guessing what the user wants (because they’re in 99% of the cases completely wrong about it). If the user opens an image, the layering and everything is deactivated. As soon as the user chooses anything from “Add Layer…” in the menu down to the “Select Layer” tool, the layering should automatically be enabled.

Of course, as always when doing this kind of automated censorship, you should give your more advanced users the opportunity to get rid of it. So if a user knows, in two out of three images I open with Artifica I intend to do some layer work, he should be able to set a “Always Enable Layering” option globally for the app.

The clue here is…

…to make your app attractive to all user groups. A newbie should not be discouraged by unnecessary buttons or complicated lists when he opens an image. The advanced user should be pleased by the apps simplicity but must have access to the full functionality just one (or with some good guesswork of the app, zero) clicks away. The app should hide everything complicated from the first glance of a newbie at the app, but should not exclude him from the higher functionality. As soon as he starts to tamper around with the “Layers” menu, he also has to face the consequences of the layering mechanism being enabled and adding some complexity to the usage of the app.

These are my thoughts on complexity and accessibility of applications. Unfortunately, not all other application developers go through this kind of process, planning their UI. In Photoshop or Word, you’re pretty much confronted with a ton of functionality that you either don’t need or don’t understand as a beginner. There should be no fixed complexity, but a very dynamic system of reveiling functionality to your users depending on his needs. Start simple, with the option of exploring the app yourself and eventually ticking the “immediately start on complexity level 2″ preference if the user feels like he always needs to be presented with a certain basic functionality and usage complexity.

— — —

Thanks for reading, as always, comments are very welcome :)

Take care.

Artifica — Saturday, November 7, 2009 6:08

Let’s reinvent Image Editing and Design

Sit back for a minute and try to name an image editor that is user-friendly, simple yet powerful and productive. I’m having a hard time figuring out just one piece of software that matches this description. “What about Photshop?” you might ask. To be honest, Photoshop is a lightyear off of what I would call user-friendly and simple to use, and speaking of power and productivity: when I design something in Photoshop, e.g. website graphics and the like, I usually spend 10 to 20% of the time managing the different image files, keeping them in an editable state, pushing the files through the compressor and messing around with hundreds of backup layers and files.

Backup Layers? Why on earth…

…would someone need backup layers and files in Photoshop? The answer is simple: Errare humanum est — I make mistakes. Sometimes I need to intersect two selections very precisely, so I create two fill layers with each of them stored in the mask, and do my selection logic with them. So there goes the third layer which has the intersection of the two layers stored in it. Why not throwing the other layers away, why keeping backup layers? Well, usually I realize half an hour later that the mask I created is misplaced, has a bad shape, looks dull, etc.. And because Photoshop is one of the most destructive and unforgiving applications out there, there’s no way of efficiently going back half an hour to change something and then returning to the present with the changes applied immediately.

Destructibility and Unforgivingness — Vice or Virtue?

Why are there applications so user-friendly they let you undo every click you made, forgiving you about any mistake you could have possibly made, and other pieces of software that feel more like a big block of cheese you try to talk into helping you retouch your holiday snaphsots?

The answer to this question lies in the past. In the early days of computers, when Photoshop and Microsoft Office appeared for the first time, a computer running on 1 MB of system memory was considered the ultimate supercomputer. Unlike today, memory footprint and efficiency were the ultimate and exclusive concern of most software engineers back then. User-friendliness is a luxury that has popped up on the computer only a few years ago. Operating system suppliers like Apple and Microsoft have started to include more and more functionality into their systems which make the usage of applications across the platform more uniform to the user. Writing an application like TextEdit on today’s Mac OS is a matter of a few hours and perfectly illustrates the luxury and power built into today’s operating systems: Compared to TextEdit, the first Microsoft Word looks more like a toy and had by far less features, even if it did cost quite a bunch of money (which TextEdit doesn’t).

So, if you write a new program from scratch on Snow Leopard, you get all the nice features and gems of the operating system for free (spell checking, file handling, text input, undo management, networking, drag’n'drop, etc. … you could fill dozens of lines with features). If you want to load an image from disk, instead of writing all the image decompression and loading algorithms yourself, you just say “system, read that image!”. The system won’t even complain you didn’t say the magic word! There are parts in Photoshop and Office that probably date back way into the last century. Migrating a program which has millions over millions of lines of source code to new technologies is a pain and not realistic. So what do companies like Adobe and Microsoft do? They adopt some of the new features of the operating systems by writing them themselves. Have you never wondered why Photoshop and Office just don’t feel at home on Mac OS X and Windows XP, but more like a stranger having difficulties adopting to the local rules and culture?

I’m sure that Adobe and Microsoft are doing their very best to keep up with the growing demands and standards on modern computer platforms. Vice or virtue? Maybe it’s both. Sometimes you just have to choose the least painful way of doing something.

Are you trying to say it’s time to reinvent Photoshop?

Yes and no. There’s absolutely no point in trying to clone Photoshop because…

  1. it’s probably illegal due to patents and copyrights held by Adobe
  2. trying to run against Photoshop with your own PS-clone is just ridiculous.

So it is definitely not the time to duplicate Photoshop and add some user-friendliness-shickymicky to it to get it sell on the market. Photoshop is the best image editor out there in terms of functionality and power. So where’s the yes?

I think it’s time for a new approach on how we edit and design images. Some things have proven very powerful in the past, take layers for example: People got used to the idea behind layers and many other types of applications have adopted the scheme. This is something you have to keep and evolve in order to make for a good image editor. On the other hand, there’s the thing about destructive filters: In 2009 it shouldn’t be necessary to worry about the contents of a layer being messed up because a filter changes them irreversibly.

Indestructibility and Forgivingness — The Goal for a new Editor

These two words should be the ultimate goal for a new image editor.

Everything the user does should be undoable in an easy way. If the user feels safe in the editor, if he knows he can click anywhere in the app and try everything without having to worry about not being able to return to the original state, that’s when we suceeded creating an image editor for the new century. If the user can apply any filter to any of his layers without having to keep a backup of them, then we have succeeded.

“You’re really trying to reinvent the leading image editor with a robust undo system and an automatic backup-keeping so that filters can be undone from layers?” — Not at all. This was just a simple description of how things should work. The true power behind the filters is that they should be dynamically calculated. With today’s high performance graphics cards and CPUs, image filters can be calculated on-the-fly. The user can create a stack of 50 filters on his layer and see the result immediately. Don’t like the sepia tone of filter 29? Just change it, and filters 29 to 50 get recalculated – superfast.

This sounds nice but doesn’t reinvent the wheel of design and image editing. There’s more to it than just a few filters. We should radically change the way people input data like images, colors, pixels and the like into the application. Everything should be vector-based from the very beginning to the end. And with on-the-fly filters, you wouldn’t even have to rasterize your vector shape to blur it. All an application needs from the user is a clear indication of what he wants to do. So if he wants apply a blur to a vector, there’s no doubt the vector should be rasterized in the background and have the filter applied to it. It should not be about what the application can do, but what the user wants it to do.

If the user wants to create a reflection effect, he shouldn’t have to think about how to update the mirrored and faded reflection when the original changes. He should be able to create an instance layer which duplicates another, and apply a mirroring and fading filter to it. And since the filters are computed on-the-fly, he can change the original layer with the reflection updating in real time. This is how things should work.

And that’s just the beginning…

Those were only a few ideas and concepts one should try to follow and implement when creating the next big image editor. There are many, many more important things: how fast can you get your updated image exported again, how easy can you handle the user interface, how versatile are the tools the editor gives you at hand, etc..

Maybe creating such an application is a bit unrealistic, but maybe the time has come when finally someone should try to do it and establish new standards in image editing.

If you happen to have any ideas for such a new image editor, write a comment!

Thanks for reading the article.
Until my next revolutionary plan to world domination: Take care!