Day 4, learning Objective C
I completed my custom control yesterday - it's a simple knob style control. I feel I understand the basics of Core graphics and implementing a UIControl from scratch (including getting touch input, sending a an 'event' when someone interacts wwith the control, etc). To reskin an existing UI Control, you would just subclass it and override any methods you want to change. This may include some of the input methods if you want to control how people interact with it. If you want to change the look/feel then you can override the drawRect method. Core Graphics is very similar to other UI frameworks I've used, such as LibNUI, Swing and Juice, so no troubles there.
Today I started working on an RSS reader to learn some more of the specifics about working with the UITableView component, which is probably the most used component of all.
Some more good resources I came across this morning:
Day 2 learning objective C
(for those that don't know I am taking a week to learn apple's Objective C. Bleep! BOX (my other iphone app) is written in C++ using LibNUI, so I haven't had to touch any Objective C so far)
Today I investigated Objective C++. Basically, if you rename your .M files to .MM then you can mix C++ code in with your Objective C code. Seems to work just fine. It's pretty common to interface with C/C++ libraries from Objective C (several example apps do). If I am ever forced to write iPhone apps that need to use standard GUI widgets then I would probably use regular Objective C for the interface and C++ for all the logic and data. Aside from being easier to work with (for me anyway), I think this will provide better separation between UI code and 'back end' code.. A lot of the Iphone examples I've seen so far have controllers for specific pages holding onto 'model' data. This can lead to architectural problems because there are a lot of cases where you want the two to be seperate and independent. I see the same issue with a lot of Flash code too, since the recommended way of doing things is always to subclass one of the Display classes. I usually find that using singletons for app-wide data is a better choice than attaching your data to a UI specific class.
I am also looking through the rest of the example apps, trying to learn more. A couple that caught my attention are the Wi-Tap app which shows how to do basic TCP connectivity (once again this references C++ code to get the job done), and also the LaunchMe app. Apparently it's possible to set up a custom URL type to launch an iphone app.. IE, have myappname://www.someurl.com/ open up your app. This would be cool for Bleep! BOX to allow people to browse a bunch of user submitted songs in safari and have the ability to click on one to open it up in the app. Seems very easy to implement.
AccelerometerGraph is the first example I've looked at so far that gives a good 'low level' look at how to make a UI component that draws itself. It also manually creates UI items which gives a better look at how things work internally. Digging in deeper..
More learnings:
- @selector is basically a delegate. Use it to call methods in response to actions
- In terms of reskinning existing objects, you can use Categories to override or add methods on objects without actually subclassing them. Though I'm a little unclear on how this works. Once I've made a category, does this apply to all instances of that object or can I choose whether I instantiate the the regular 'uncategorized' version of the object or the 'category' version?
- UIView - addSubView is how you add 'child' views.
- Good Info: http://www.iphoneexamples.com/, http://cocoadevcentral.com/d/learn_objectivec/
- This is interesting. A code only approach to iPhone ui - convert XIB to code: http://kosmaczewski.net/2009/03/17/nib2objc/
I'm starting to write my own Control from scratch. This is how I got started with LibNUI and should be a good way to get started with UIKit.
Thoughts on Objective C
This is my first day trying to learn Objective C. Here's my thoughts so far - some of these may be wrong since I am still a newb.
Learning a new language is always a bit frustrating at first, so bear with me.
What is it
- Objective C seems like it started with C, took a few OO concepts from C++ and added manual reference counting memory allocation out of the box. Somewhere along the way, syntax got beaten to death with a hammer, resulting in a strange, unique syntax. This gets a big frowny face from me - almost every modern language shares a similar syntax (Java, C++, C#, Actionscript, Javascript, heck even PHP once you get past the dollar signs) - being different here only makes it hard to learn and there's no reason it couldn't have a more C++ or Java like syntax.
What's weird
- Why come up with an entirely new syntax and language? Objective C is rumored to be less efficient than C++ and doesn't seem to offer any benefits. Programmers still have to deal with pointers (in the sense that bad reference counting can still crash your applications). Poor use of reference counting can easily lead to memory leaks. There doesn't seem to be anything particularly slick or time saving about the language itself.
- When declaring an interface, why are methods and variables outside of the brackets? Also, it's not necessary to declare methods as part of the interface? Seems like this kind of defeats the purpose of having an interface.
- Way of declaring and calling methods (esp methods with parameters) is strange and not very readable..
What's nice
- Interface builder is kind of nice.. Ability to click and drag to connect outlets is slick. However, I find myself wondering if I couldn't do things faster just by creating the interface "by hand" with code. Even simple stuff requires a lot of setup..
- @property, @synthesize
So far every application I try to write from scratch crashes and burns. Oh well, there's always tomorrow.
iPhone app
Just wanted to drop a post to say that my iphone app is coming along pretty well. I've put in a ton of time on it the last few weeks and it's starting to come together. I should be close to finishing it in another week or two.
The first few days with libnui were a little frustrating since I didn't quite understand how the layout widgets were sizing themselves (specifically the grid based widgets). I've been used to juce's more explicit (typically fixed size) layouts. Now that I've been working with them a while, I find them to be a more welcome addition and there are some nice things you can do with them that do save time. I am still a bit confused about how some of the CSS stuff works (mainly I think I need some more examples and documentation about how the different widgets can be styled..), though it's perfectly acceptable to eschew css and set up your widgets styles via code (which is what I've been doing). I'll avoid getting into too deep of a comparison between juce and libnui here because I want to do a full post on it later.
Now that i know my way around the framework I am pretty productive and the good news is that writing your own components is a pretty simple affair (just as easy as it is in juce).
Currently I have all the major synthesis modules written. I have most of the major 'pages' in the app written (only one or two left to go). I've had to scale back my planned # of voices due to CPU constraints. I'm still shooting for 10 voices, though i need to get each voice down to about 6.5% cpu in order to keep the GUI snappy and avoid audio breakups. Right now I think they are at 8% and I've already done a fair bit of optimization. Each voice is basically a 2-Osc synth + filter and several envelopes, so you can do some cool stuff with them. I always find it hard not to throw in the kitchen sink when it comes to making synthesizers. I like to have a lot of options. I also have some pretty cool 'live performance' oriented features (which make use of multitouch) that I think people are going to dig. I will post some screenshots soon. We will have a more finalized gui design soon. I also did some work on a logo.
One good benefit of the whole thing, is that I basically re-wrote my audio framework from scratch (this same framework is what I'm using in Genome). In doing so, I identified a bunch of optimizations and design improvements that I should be able to carry over to Genome. Re-writing things almost always yields a better product. Many parts of genome have been re-written several times by now. There is a big tendency for programmers not to want to touch old code and to just 'leave it as is' even if it's flawed. I prefer to start from scratch every once in a while just to clean out the skeletons.
Good article on designing iphone UI’s
http://www.the-soulmen.com/blog/2009/02/09/on-prototyping-iphone-ui/
The article talks about the challenges of designing a UI for such a small screen, and how you have to design elements to be bigger for a touch interface than you do for a mouse clicking interface - something I immediately noticed myself when I began designing my iphone app. Worth a read.
Song View VI
Nearing the light at the end of the tunnel for the song view
- Many fixes and additions concerning mouse / keyboard selection and control. This is one of my favorite areas to work on (though it can be time consuming) since sometimes small changes to the feel can have a big impact on usability
- added keyboard shortcut for adding markers. other fixes concerning markers (missing undo's, added doubleclick to split a marker, etc..).
Still to do in this phase:
- Tempo markers, tempo box
- 6 or so small fixes and additions
Next Phase: Improve control surface functionality
Weekend Update
This has been a fairly unproductive programming weekend so far. Had some errands to run yesterday and Warhammer II: Dawn of War is eating into some time as well. I've wrapped up most of the work with Undo's - there's still a few fixes and additions to do (when is there not?) but I will work on those a bit later. I'm currently planning how I want to tackle the Song View. I have a long list of enhancements and low level changes I want to make and am currently debating whether I just want to re-write everything or try to keep some of what I have. One major change is to have it use the EventPattern class I wrote for the Piano roll. Having them share the same basic mechanisms should reduce complexity and make debugging easier. On the up side, I only have two more major areas to work on (including SongView) then 3-4 smaller ones, then I can start thinking about allowing some people to beta test..
I found a nice little addin for VS 2005 called Project Line Counter (VS 2008 has something like this built in). Looks like Genome is up to 39,000 lines of code so far and probably about 200 classes (give or take). Juce on the other hand, has about 250,000 lines of code. So you can see how much work it's saving me
There are very few classes in Juce that I'm not using in some way.
Cool devices that support OSC
- Jazzmutant Lemur
- iPhone / iTouch apps: TouchOSC, mrmr, others..
- Monome
- Touchlib
- reactivision
Cool stuff
Create Digital Music has some really cool stuff here. I'm really interested in playful, easy to use interfaces like this.
Piano Roll (work in progress)
Here's a shot of the Piano Roll module I'm working on. FYI, all art is 'programmer art'. I'm going to have a GUI designer clean things up once I'm done getting everything working.
