Category > Uncategorized

Class Methods and Typedef Enums

Ricki » 21 June 2010 » In Uncategorized » 1 Comment

This is a nifty little “pattern” for collecting reusable elements, color, labels, settings etc. that is standard through out your program. I do use Interface Builder, but I prefer reuse approach of code.

When a projects design has been agreed upon and the basic things are laid out: font, size, color theme etc. I usually build myself an ISInterfaceElements class. This class contains a few Class Methods called getColor:(ColorType) type and getLabel:(LabelType) type. Our Proof-of-Concept Class will contain 3 different colors: BackgroundColor, ForegroundColor and TextColor. It will also contain 3 types of labels, a HeadlineLabel, TextLabel and a DetailLabel. These six components will get you pretty far in describing the text and color of an iPhone App.

How to do it “manually”.

If I were to build a UILabel, using nothing but code, and make it adhere to the design mentioned above it would probably go a bit like this:

1
2
3
4
5
6
7
8
9
10
    UILabel *label = [[UILabel alloc] init];
    [label setFrame:CGRectMake(0.0f, 0.0f, 320.0f, 20.0f)];
    [label setFont:[UIFont fontWithName:@"Helvetica" size:14]];
    [label setTextAlignment:UITextAlignmentCenter];
   
    UIColor *textColor = [UIColor colorWithRed:0.2f green:0.5f blue:0.3f alpha:1.0f];
    [label setTextColor:textColor];
   
    [label setShadowColor:[UIColor darkGrayColor]];
    [label setShadowOffset:CGSizeMake(0.0f, 1.0f)];

If you do stuff like this manually and scattered around your program you will at some point encounter the “Let’s change the font and color of the app!” witch will leave you with a couple of hours of “Sherlock Holmes copy-paste”, as I like to call it.
Instead we will try to gather common functionality in a single class so that any change made here will propagate outwards to all the parts of the code.
We will use the approach that Apple often uses in their frameworks, e.g. when initializing a UIButton you could do it like this:

1
      UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];

The way to go about this is to write a Class that has Class Methods for getting a UILabel and UIColor back, and instead of giving them ID’s like 0034, 1234 etc. we write a typedef enum with nice, easy-to-remember names like UIButtonTypeCustom above. This will make sure code completion and compiler checking will work with you instead of against you.

The Class:

As I wrote at the beginning our class will have 3 label and 3 colors, so we start out by writing typedef enums for these elements and we define a (UILabel*) getLabel:(LabelType) type and (UIColor*)getColor:(ColorType) type method.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//
//  ISInterfaceElements.h
//  BlogPostCode
//
//  Created by RickiG on 6/21/10.
//  Copyright 2010 www.rickigregersen.com. Use as you please:).
//

#import <Foundation/Foundation.h>

typedef enum {
   
    BackgroundColor = 0,    //This will give the BackgroundColor the ID 0 and ForeGroundColor the ID 1 etc.
    ForegroundColor,        //it is not needed, if left out it will default to 0,1,2...
    TextColor,
   
} ColorType;

typedef enum {
   
    HeadlineLabel = 3,      //This will give the HeadlineLabel the ID 3, the TextLabel 4 etc.
    TextLabel,              //use this only if the enums can not have the same value, in our case
    DetailLabel,            //they are not needed, but shown to illustrate that enums just corresponds to integers
   
} LabelType;

@interface ISInterfaceElements : NSObject {
   
}

+ (UIColor*) getColor:(ColorType) type;
+ (UILabel*) getLabel:(LabelType) type;

@end

Now we implement these two methods. The logic of determining which kind of Color of Label is returned is done with a switch case (as the enums are integers):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
//
//  ISInterfaceElements.m
//  BlogPostCode
//
//  Created by RickiG on 6/21/10.
//  Copyright 2010 www.rickigregersen.com. Use as you please:).
//

#import "ISInterfaceElements.h"

#define APP_FONT @"HelveticaNeue"               //Defined once so that it is simple to change the font of the app
#define APP_FONT_BOLD @"HelveticaNeue-Bold"

@implementation ISInterfaceElements

+ (UIColor*) getColor:(ColorType) type {
   
    int value; //We deal with the Color in terms of Hex, this is what a designer will often return.
   
    switch (type) {
           
        case BackgroundColor:
            value = 0x2d3c3f;
            break;         
        case ForegroundColor:
            value = 0x627376;
            break;
        case TextColor:
            value = 0xDDDDDD;
            break;
        default:
            value = 0x000000;
            break;
    }
   
    int r, g, b;
    b = value & 0x0000FF;
    g = ((value & 0x00FF00) >> 8);
    r = ((value & 0xFF0000) >> 16);
   
    return [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:1.0f];
}

+ (UILabel*) getLabel:(LabelType) type {
   
    UILabel *label = [[[UILabel alloc] init] autorelease];
    [label setBackgroundColor:[UIColor clearColor]];   
   
    switch (type) {
        case HeadlineLabel:
            [label setFont:[UIFont fontWithName:APP_FONT_BOLD size:14]];
            [label setTextColor:[self getColor:TextColor]];
            label.shadowColor = [UIColor darkGrayColor];
            label.shadowOffset = CGSizeMake(0.0, 1.0);         
            break;
        case TextLabel:
            [label setFont:[UIFont fontWithName:APP_FONT size:12]];
            [label setTextColor:[UIColor whiteColor]];
            label.shadowColor = [UIColor blackColor];
            label.shadowOffset = CGSizeMake(0.0, 1.0);
            break;
        case DetailLabel:
            [label setFont:[UIFont fontWithName:APP_FONT size:10]];
            [label setTextColor:[UIColor darkGrayColor]];
            [label setTextAlignment:UITextAlignmentRight];
            break
        default:
            break;
    }
   
    return label;
}

@end

Using the ISInterfaceElements Class:

Now that the class is set up it is really simple to obtain a UILabel or UIColor in a way that 1) does not clutter up your code with repeating setup-code 2) makes your design consistent, fonts and colors are easily changed in one location 3) follows the approach you know from Apples frameworks.

Make sure to import the ISInterfaceElements.h header then do the highlighted part below:

1
2
3
4
5
6
7
8
9
10
11
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    // Override point for customization after application launch
   
    UILabel *headline = [ISInterfaceElements getLabel:HeadlineLabel];
    [headline setText:@"Hello, World"];
    [window addSubview:headline];
    [window makeKeyAndVisible];
   
    return YES;
}

Continue reading...

DTXplorer drum kit goes Processing

Ricki » 09 September 2009 » In Java, Processing, Uncategorized » 6 Comments

This my DTXplorer drumkit getting feed into MidiPipe onto Osculator and finally ends up in Processing. Now thats beat detection!
YouTube Preview Image
YouTube Preview Image

I have taken some time to get my Yamaha DTXplorer electronic drums to communicate nicely with my Mac, finally it worked out and I can now “harvest” the sweet, sweet MIDI coming from the drums. Im no Moby, so believe me when I say these last one and a half days of frustrations was not to immortalize the sound of my drumming. It was, of course to get the data into Processing. A friend of mine is a DJ and he wanted us to experiment with playing “live” drums along with the turntables. Furthermore, to make some sort of visualization that would be 100% true to the beat. This is very hard I found out, there are a lot of good sound libraries with beat detection out there, but they are never plug n’ play. You need to tweak your code for every single song and even that is no guarantee for a consistent output. I came up with a pretty straight forward solution, if we were to use the electronic drums anyway we could just as well use the MIDI for the beat detection and then have the turntables control the colors.

I found out that I needed a few different applications and a MIDI cable before I got the signal all the way through. First off is the ESI MidiMate cable, I actually had the old model, but I think it was broken and could not handle if the MIDI in was not connected to a ground plane. It was 295 Danish Kroner ( ≈$55 ). Then I needed MidiPipe. This a free application developed by Nico Wald and it is brilliant! Should I ever make any money with this setup I will run to a browser and donate some money to Nico.
The idea with MidiPipe is that it “hijacks” every single MIDI port it can detect on the system, you then drag the one you need to the pipe(ESI MIDIMATE Port 1 turn up in MidiPipe the second I connected it to the drumkit) you can then drag other stuff into the pipe. I dragged in “AList” from the “Modifier” and that gave me just what it says, a list of all midi signals passing through MidiPipe.

MidiPipe is a life-saver

MidiPipe is a life-saver

This was a cool way of testing out the drums. Lastly I dragged a “MIDI out” into the Pipe, more about that in a second. Then I went out and finally bought that license for OSCulator. Osculator have been running my Wiimote, iPhone, Arduino and Make controller for the last year and I have been to lazy/cheap to just buy the license. Well Osculator is a $15 minimum, but Camille asks people nicely to pay $39, which I did, of course, having used his software for about a year now. What Osculator can do is just to much to explain here… I needed it to translate my MIDI into OSC (because OSC is the new MIDI :) ) and then relay the rewritten data to a port on localhost using UDP. This was done so I could have some control over the data, also I now get something along the lines of “snare – on – 0.6″ (thats the pad sending the message, that it was “on”/hit and the strength it was hit with) into Processing instead of some MIDI byte I have to bitwise shift around to get any data from it, it just makes debugging easier and sending something through Osculator opens a world of other possibilities.

It is just crazy how many features there can be in such a simple application

It is just crazy how many features there can be in such a simple application

A note here, when I started Osculator, MidiPipe noticed Osculator was listening on port 8000 and stuffed that piece of information into the “MIDI out” I mentioned earlier, now I could just select it there. So now my MIDI came in through MidiPipe, was listed for me to see and then relayed on to Osculator. In Osculator I caught each MIDI event and by selecting the signal and going Osculator – Edit – Demux, I could split the signal into its components and rebroadcast them as OSC messages on the network. For handling OSC Protocol stuff in Processing Andreas Schlegel did a really great library, you can get it here along with some other goodies Andreas made.

I now had 8 different OSC messages, one for each drum pad, cymbal and foot pedal (Im going to do the high hat pedal later on) that I can read out in Processing. I did a small sketch as you see in the video and just started the “play along” feature on my DTXplorer kit, with some “Hard Rock” :) selected and and the computers microphone recording.

And as always if there is some code or help You need just leave a mail or comment.

A version not completely compressed by the geniuses over at youtube

Continue reading...

Tags: , , , , , , , ,