Gameboards and GUIs

Written by Cathy on June 4, 2009 Leave a Comment

I wrote a post for the Sofa blog called Gameboards and GUIs. It’s inspired by something I read in the game design book, Rules of Play, by Katie Salen and Eric Zimmerman and I want to take a moment here to recommend the book to anyone who’s interested in interface and interaction design. It’s a great book with unique insight into the challenge of engaging people in meaningful and enjoyable experiences. Add it to your reading rainbow!

Read Gameboards and GUIs.

Posted in Personal, Research

KTUIKit 0.9.1

Written by Cathy on May 26, 2009 4 Comments

I want to thank all of the brave Mac devs out there who’ve taken the time to try out KTUIKit. The comments and bug reports are extremely helful and appreciated. Thank you.

Things have been moving along with KTUIKit and I’m finally ready for a new Pre-alpha milestone release (0.9.1).

You can download a copy of the release here, or checkout the source from the GoogleCode project.

The .zip file contains:

  • A build of the framework
  • A build of the plugin
  • The KTUIKit Xcode project
  • An example application Xcode project that uses the framework and plugin
  • I’ve posted the release notes on the project’s home page. There are major API changes in this update so I’ve made the previous revision of the project available for download for those who went beyond ‘brave’ into the realm of ‘crazy’ and have used it in a project you actually care about spacer

    I’ve also updated the KTUIKit page here on the blog with new instructions on how to install the plugin and use the framework in a project. The example project on the page has also been updated to use the latest version of the plugin and framework.

    A little bit of news: I started working at Sofa a few months back and we’re using KTUIKit in a new product. I’m developing KTUIKit for Sofa in a separate branch of the subversion project and will slowly move those changes over to the trunk as the designs are finalized and the code stabilized. There are two things that made it into this version of the trunk that some people might find interesting: KTLayerController, a new controller for layers (like a view controller is to views) and KTTabViewController, whose only job is to switch between a list of view controllers. Both are still *in the works*, but I’ve been using them and I think they have promise. I have very loose descriptions of the classes and more in the release notes.

    Again, thanks to everyone and I’ll see you at WWDC!

    Posted in Uncategorized

    KTUIKit 0.9.0

    Written by Cathy on November 12, 2008 13 Comments

    I’m pleased to (finally!) introduce KTUIKit, an open source framework and Interface Builder plug-in project. The goal of the project is to address some of the issues that I’ve brought up in previous posts on this blog:

  • Incorporating NSViewController into Cocoa’s controller system
  • Replacing NSView’s Autoresizing mechanism for the layout of views and controls
  • Styling of views (not controls, i wish…)
  • KTUIKit currently includes the XS-Controllers, KTView, subclasses of many of the standard Cocoa controls, KTLayoutManager and KTStyleManager. The Interface Builder plug-in provides a GUI for the layout manager and style manager.

    This is still very much a work-in-progress. Don’t try to use it in your own project yet! There are bugs – especially in the Interface Builder ‘Style’ inspector, which is basically still unusable for anyone other than the person that programmed it… Nevertheless, I thought I’d go ahead and put the project out there – incomplete, with bugs and all.

    If you want to check it out in action, you can download an example project. The project shows how to use the layout and style managers in the view controller classes as well as in Interface Builder. If you want to open the nib files, you’ll have to do a little bit of work to get Interface Builder to load the plug-in:

  • Build the KTUIKit Xcode project that came with the example project
  • Copy the framework, which is located in a directory called “Uninstalled Products” in the Xcode project’s build directory, into your ~Library/Frameworks directory
  • Launch Interface Builder and go to its Preferences window
  • Go to the “Plug-ins” tab and hit the Add (+) button
  • Navigate IB to the copy of the framework in your ~Library/Frameworks directory
  • Hit ‘Open’
  • KATI will show up in your list of plug-ins and its library objects will show up in your library.
  • The Example Project

    spacer

    This example is very similar to the view controller example projects I’ve posted in the past. It’s basically a window composed of several nib files, pieced together by several view controllers. The difference is that it uses KTUIKit’s views and their layout and style managers.

    The main thing to notice is how durable the layout is. Make the window as small as you can and as big as you can – drag the split view dividers all the way to zero and back. Nothing breaks. Everything is where it should be. There are also examples in the code of using the layout manager’s relative layout configurations – like “filling” and “floating”. There is no extra layout calculation code in the view controllers and KTView is never subclassed in the example project.

    I’ve created a page dedicated to KTUIKit. It contains information about how to get it from Google Code and about using the framework in an Xcode project.

    If you have comments or feedback or if you’re interested in contributing to its development please feel free to email me. Here’s to a quick move to 1.0!

    Posted in KTUIKit

    Simple NSViewController Sample Projects

    Written by Cathy on July 24, 2008 5 Comments

    Hello!!

    Thanks for all of the feedback on the XS-Controllers design that Jonathan and I posted. We’re going to be making some changes to the design based on feedback, bug reports and the experience we’ve had using it ourselves over the past few months.

    First, I want to take a few steps back and offer a couple of example projects that use NSViewController – straight out of the box – in a non-document based application. I hope these will be more useful for people who are just starting out with view controllers. The projects do the following:

  • Create a view controller with a nib file
  • Add several view controllers’ views to the window’s view hierarchy
  • Switching between two view controllers and their views
  • Patch a single view controller into the Responder Chain
  • There’s also a good sample project available on Apple’s site. I recommend checking it out.

    Simple View Controller Xcode Projects

    Simple View Controller – Adding Views to the View Hierarchy

    spacer Download SimpleViewControllerPart1.zip

    A window controller creates two view controllers and
    adds their views to the window’s view hierarchy. The window controller keeps references to the view controllers as instance variables. They are not added to the responder chain.

    Simple View Controller 2 – Switching View Controllers

    spacer Download SimpleViewControllerPart2.zip

    This project extends the previous project so that the DetailViewController manages the switching between two other view controllers and adding their views to its “contentView”. This gives you tab-like behavior with the addition of view controller switching instead of just view switching.

    The DetailViewController is patched into the responder chain when it is created, after its view is added to the window, so that it can handle the View menu actions for switching the views.

    Note on the Responder Chain:

    If you take a look at the sample code, you’ll notice that I added the DetailViewController to the responder chain after the window controller. This follows Jonathan’s and my design for the XSViewControllers. Many people have asked why we didn’t add the XSViewControllers into the responder chain after their associated views instead. There a couple of reasons for this:

  • A view controller can’t control when its view is added and removed from the view hierarchy, so in a design like ours, there is no reliable way to patch the chain in this way without subclassing and extending NSView to be aware of its view controllers. This is a more intrusive design, in my opinion.
  • There is a significant behavior difference between the two approaches. Action messages take a specific route through the responder chain. In order for a view controller to be able to validate a menu item, its view or one of its subviews will need to be the first responder. This means that you have to subclass the view, override ‘acceptsFirstResponder’ to return “YES” – AND that your user has to click in the view before going to the menu in order for the menu items to be usable.

    Placing the view controllers in the same part of the chain as the other controller classes ensures that the action message can travel to them, regardless of which view is the first responder. The controllers can then decide which items to validate based on their own internal logic.

  • To see the difference in behavior of the two approaches, change the sample code from the SimpleViewController2 project in the file MainWindowController.m, in the windowDidLoad: method:

    	// patch the detail view into the responder chain
    	NSResponder * aNextResponder = [self nextResponder];
    	[self setNextResponder:mDetailViewController];
    	[mDetailViewController setNextResponder:aNextResponder];
    

    to

    	// patch the detail view into the responder chain
    	NSResponder * aNextResponder = [aDetailView nextResponder];
    	[aDetailView setNextResponder:mDetailViewController];
    	[mDetailViewController setNextResponder:aNextResponder];
    

    After you make that change, build and run the project. Click within the detail view area to make it the window’s First Responder. Go to the ‘View’ menu and the items will be validated. Now click into the table view area and then return to the ‘View’ menu. The menu items won’t be validated. You will have to click in the detail view area again to validate the menu items. This isn’t the desired behavior for these menu items.

    Anyway…

    NSViewController and IB

    NSViewController is designed to be used with a nib file. As you can with NSWindowController, you will initialize a view controller with the name of its associated nib file.

    mTableViewController = [[TableViewController alloc] initWithNibName:@"TableView" bundle:nil];
    

    The view controller will automatically load the nib when it is asked to return its view for the first time. In order for all of this to go smoothly, there are two things to be sure to do in your nib file:

    1. Set the File’s Owner’s “Class” to be the NSViewController subclass that will be managing its view

    1. Drag the view controller’s header file into the IB project or use the “Read Class Files…” command in the File menu and select the header file.
    2. Select the “File’s Owner” object and go to “Identity” tab in the inspector palette. Start typing the class name of the view controller. It should autocomplete for you.
    spacer

    2. Connect the File’s Owner’s (your view controller) “view” outlet to the nib’s top level view.

    1. Ctrl-drag from “File’s Owner” to the view.
    2. Select the “view” outlet when the small context menu pops up.
    spacer

    That’s it!

    Resources

    NSViewController Class Reference

    Apple’s View Controller Sample Code (shows example of switching view controllers)

    NSResponder Class Reference

    The Responder Chain for Action Messages (from the docs on the Event Architecture)

    Posted in Sample Code | Tagged NSViewController, SampleCode

    WWDC 2008!

    Written by Cathy on June 7, 2008 2 Comments

    I thought I could get the next post out before WWDC, but it seems doubtful at this point. Sorry for the long pauses lately, I’ve had lots of work to do for my real job and it seems that it will be this way for the next month or so.

    Anyway, if anyone wants to hang out in San Francisco next week, send me an email or a tweet spacer

    See you there!!!

    Posted in Uncategorized

    NSViewController, the New C in MVC – Pt. 3 of 3

    Written by Cathy on May 26, 2008 20 Comments

    The last two installments in this series focused on the challenge of integrating NSViewController into the controller layer of the current Cocoa MVC application architecture. This is an important step to take, especially when developing a Cocoa application with a single window interface design. In a single window design, users will access most of the application’s features through one window rather than opening and closing several smaller windows as they are needed. Since this one window will never close during a session, the multiple view controllers in the window will fill the role previously held by multiple window controllers in creating a dynamic Cocoa application.

    The application’s view controllers will perform tasks like loading/unloading the content of nib files and their controllers as needed and validating/invalidating menu items as features are added or removed from the window. Plugging NSViewController into the existing controller architecture is a simple way to provide it with the support it needs to fulfill these standard duties for your application.

    However important these window controller-type tasks are, keep in mind that they are not the principle duty of a view controller. Unlike NSWindowController, NSViewController has a close relationship to the view layer of the Cocoa MVC design. Each view controller manages a view in a view hierarchy. A system of view controllers, like the system Jonathan Dann and I described in the previous installment, manages the entire view hierarchy of a window. One of the most mission-critical jobs of a system of view controllers is to build and maintain the structure and layout of a complex view hierarchy in a dynamic environment.

    spacer

    Above: Adobe Photoshop Lightroom is an example of a feature rich application with a single window interface design.

    Quick Quiz: what is a view hierarchy?

    Quick answer from the docs (emphasis is mine):

    In addition to being responsible for drawing and handling user events, a view instance can act as a container, enclosing other view instances. Those views are linked together creating a view hierarchy. Unlike a class hierarchy, which defines the lineage of a class, the view hierarchy defines the layout of views relative to other views.

    V + C, the dynamic layout duo

    There is a key difference between developing a Cocoa application that spreads its interface over several windows and one that uses a single window interface. In a single window design, the view hierarchy of the application’s main window is much more complex and, most importantly, dynamic than Cocoa windows normally are. In fact, the view hierarchy is a prominent character in this type of development. Managing its structure and layout throughout the application’s runtime is a significant design problem that should be addressed in a systematic way by the software’s MVC architecture – in both the controller and view layers.

    NSViewController addresses this issue by providing support for building and managing the structure of a view hierarchy through its “view” instance variable. Once you organize your view controllers into a coherent system, you have a convenient mechanism for accessing and adjusting the hierarchy from its significant branches. But the problem is only half solved since changes in the view hierarchy are reflected by changes in the layout, and unfortunately, the issue of layout in a dynamic view environment remains to be addressed by Cocoa.

    Building and maintaining a complex layout, like the one pictured above, requires cooperation from both the views and the controllers of a window. The controllers are the dictators of the layout. They tell the views contained in their domain of the hierarchy where to go and how to behave. Unless the circumstances are very special, it’s up to the view hierarchy itself to do the calculations necessary to maintain the integrity of that layout as the forces within it change over time. If either member of the layout duo fails to perform their duty, the interface will simply break.

    The problem with V

    In Cocoa, NSView fails to perform its duty in this kind of system because it isn’t equipped with the right tools. NSView has something called an “autoresizing mask”, which is meant to define the layout behavior of a view when its superview’s layout changes. However, Autoresizing was never designed to function in a view hierarchy with a dynamic structure. It is simply not the right tool for this job. This is evidenced by one simple thing: Autoresizing requires that a view is already laid out within its superview before you are supposed to set the desired resizing behavior.

    This is well and good when you’re creating your entire layout in Interface Builder, where all the views are present and accounted for, but it’s simply not a practical limitation to make in a system of views and view controllers where elements of the layout will be added and removed during the application’s runtime.

    It means that a view controller must have knowledge of it’s view’s superview and its frame before it can technically set a layout, but view controllers don’t necessarily have that information. For instance, when a view controller is initialized, it will create a view that will eventually be added to the view hierarchy. At that moment, however, it doesn’t know anything about the view/controller hierarchy that it and its view are about to become a part of. Technically, there’s no way for the controller to guarantee that the layout it dictates to its view (or more specifically, the view’s subviews) won’t be damaged by the layout of the view above it in the hierarchy. Since NSViewController can’t always meet the requirements set forth by Autoresizing, the layout is exposed to the glitches and bugs that I’ve described in previous posts by default, and there’s nothing to be done about it except to take extra special care to explicitly size and position new views when adding them into the hierarchy and to set limits on how much the user is allowed to resize elements like split views and the window itself. This is just extra grunt-work code that isn’t *really* necessary. It’s a byproduct of the bugs in Autoresizing.

    The bigger problem, one that does sometimes affect the design of the controllers, is that when a view controller makes a change to the existing view hierarchy, by either adding or removing views or manually adjusting the size or position of a view, it needs to take the view’s siblings into consideration. The quote I pasted earlier, defining a view hierarchy, states that:

    the view hierarchy defines the layout of views relative to other views.

    What the docs really mean is that the layout of views is defined relative to their superviews. The sibling views aren’t considered by the view hierarchy at all during autoresizing. So, any sibling that needs to move or resize as a result of the change needs to have its layout recalculated and its autoresizing mask re-set by the view controller that propagated the change – even if the affected views aren’t in the controller’s domain of the view hierarchy. In this situation, the dynamic layout behavior of the view hierarchy becomes the responsibility of the view controller to maintain. This slippage of responsibility results in case-by-case workaround code that’s not only a pain in the ass to maintain, but that sometimes requires dependencies to views contained by other view controllers to be hard coded into the view controller. All this does is make your view controllers less reusable by no fault of their own. Again, none of this is necessary, it’s a byproduct of the limitations of Autoresizing.

    Absolute vs. Relative

    At the heart of the problem with Autoresizing, specifically in a dynamic system of views and view controllers, is the fact that there’s just nothing dynamic about it. The mechanism is based on absolute positions and sizes, which makes it an inappropriate layout tool for this kind of interface development. There are very few absolutes in a single window interface design. Absolutes might include the height of a toolbar or the width of a control, but the state of the view hierarchy as a whole, at any given time during the app’s runtime, is variable.

    A dynamic view hierarchy and its controller counterparts would be better served by a layout tool that can accommodate relative sizes and positions. In a relative system, a view controller could just tell a newly created view to, for example, *fill* the width and height of its superview or *float* upwards in its superview – without having to specify any specific size or position (which might not be known anyway) – and the view hierarchy would work out the details once the view is in there.

    Remember, view controllers have A LOT of responsibility in a Cocoa applicaiton. They handle action events, load nib files, validate menu items, and sync up views to their data. Why add managing the autoresizing behavior of the view hierarchy to their already long list of chores?

    Still more to come…

    So, yeah, I warned about the rant spacer Now I’ll try to offer a solution.

    I’ve prepared an example project that illustrates how to use Jonathan’s and my controller subclasses, XSWindowController and XSViewController to build and manage a dynamic view hierarchy. The project introduces an NSView subclass, KTView, into the mix. Naturally, KTView uses an alternative to the Autoresizing mechanism that’s specifically designed to work within a changing view hierarchy. It’s not a perfect solution (only Apple can do that), but it does get rid of the extra code from the view controllers that’s only there as a byproduct of Autoresizing.

    The goal of the project is to bring together the concepts and opinions that have been covered in these three posts through examples of NSViewController in action.

    I’ve decided that I don’t want to release KTView without an Interface Builder plugin, so I’ll publish the project with a tutorial as soon as that’s finished.

    Until then, I found the original Smalltalk MVC Design paper, How to use Model-View-Controller. It’s interesting to read how Cocoa’s MVC design deviated from the original idea, especially when it comes to views and controllers. Enjoy!

    Posted in Architecture, Layout, Research | Tagged Architecture, Layout, NSView, NSViewController, Research

    Manual Input Sessions

    Written by Cathy on April 23, 2008 Leave a Comment

    In Computer Administrative Debris, I briefly discussed the idea of “directness” in interaction design. I described a “direct” interaction model as one where the visual representation of the content and the interface to the content are the same. A direct interaction model also implies some sort of physical interaction with content. Today, we most frequently use the mouse as an extension of our bodies to “point” at objects on the screen and to “drag” or “drop” them. With gesture and touch-based technologies entering the mainstream, these interactions will become more and more concerned with the movement and/or form of the user’s actual body.

    A beautiful and extreme example of directness in an interface design can be found in the the software developed by Golan Levin and Zachary Lieberman for their 2004 audio/visual performances, Manual Input Sessions.

    The Manual Input Sessions is a series of audiovisual vignettes which probe the expressive possibilities of hand gestures and finger movements.

    Using a custom hardware/software setup, they developed interfaces for creating and composing audio in real-time that incorporate physical objects and the body into the interaction models. Users of this software literally mold the audio with their hands over time.

    Also, when you watch the videos, notice how each interface has environmental characteristics that aid the user in creating and composing the audio. This is a clever way to add extra meaning to the input data. It also infuses the interfaces with a sense of play and exploration, so they become much more instrument-like and less tool-like.

    [these videos need sound]

    Posted in Art, Input, Research

    NSViewController, the New C in MVC – Pt. 2 of 3

    Written by Cathy on April 17, 2008 26 Comments

    In the last post on NSViewController, I described the need for a view controller class that is part of a sound controller architecture, especially when developing an application with a single window interface. In this post, Jonathan Dann and I will share the design we came up with for integrating NSViewController into the existing Cocoa MVC application architecture using NSWindowController as the glue.

    Before, we do that…

    Meet Jonathan.

    I’m currently training with the National Health Service in the UK, working towards becoming a state-registered Medical Physicist. I was i

    gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.