Showing posts with label Mac OS X. Show all posts
Showing posts with label Mac OS X. Show all posts

Saturday, November 6, 2010

Cocoa: Black Window Titlebar

Starting with Quicktime X and now with Facetime, Apple has introduced a new black ui titlebar. There's no NS component at the moment or any flag of NSWindow, so I've decided to throw away ten minutes to write my own black titlebar.
I've created a NSWindow class (BlackWindow.h/BlackWindow.m) that initializes a window without borders (styleMask NSBorderlessWindowMask) and I've created a NSView that draws the titlebar (BlackWindowTitleView.h/BlackWindowTitleView.m).
The titlebar redraws itself when some changes are applied to the window. With key value observing for title, document edited, ... and NSNotificationCenter for KeyNotifications the titlebar knows what to do.

Source code can be found on my GitHub under blog-code/MacBlackWindow.
git clone https://github.com/matteobertozzi/blog-code.git

Saturday, September 5, 2009

Grand Central Dispatch: First Look

In the last years I've always used a "parallel task" approach foreach loops that I've in the code, not always to speedup but even to clean-up the code. How to do it? Wrapping threads and Thread Pool like in this C# Parallel Forech Code.

Snow Leopard has introduced a new BSD-level infrastructure, with simple and efficient API to do this job. Here a little usage preview.

Block objects are a C-based language feature that you can use in your C, Objective-C, and C++ code. Blocks make it easy to define a self-contained unit of work. Blocks are something like Actions (delegate {}) in C#. Very useful to embed function in loops.

Blocks looks like a "private" function pointer, but you can access to the "parent" vars. (If you're a Python coder, you've exactly the same thing).


/* Blocks in Python...
* def main():
*    a = 10
*    def test(k):
*        print a, k
*    test(128)
*/
int main (int argc, const char *argv[]) {
  int a = 12;

  void (^test_block) (int) = ^(int k) {
    printf("A Block: PARENT(%d) ARG(%d)\n", a, k);
  };

  test_block(128);

  return(0);
}


The GCD queue API provides dispatch queues from which threads take tasks to be executed. Because the threads are managed by GCD, Mac OS X can optimize the number of threads based upon available memory, number of currently active CPU cores, and so on. This shifts a great deal of the burden of power and resource management to the operating system itself, freeing your application to focus on the actual work to be accomplished.


#include <dispatch/dispatch.h>
#include <stdlib.h>
#include <stdio.h>

#define ITEM_VMIN       (1)
#define ITEM_VMAX       (200)
#define NR_ITEMS        (100)

static void __fill_item (void *items, size_t n) {
  int *i_items = (int *)items;
  i_items[n] = (ITEM_VMIN + (int)(ITEM_VMAX * ((double)rand() / RAND_MAX)));
}

static void __work_on_item (void *items, size_t n) {
  int *i_items = (int *)items;
  i_items[n] *= 100;  /* Do some Computation on this Item */
}

int main (int argc, const char *argv[]) {
  dispatch_queue_t queue;
  int data[NR_ITEMS];

  /* Get Global Dispatch Queue */
  queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

  /* Initialize data Elements, and run computation on each element */
  dispatch_apply_f(NR_ITEMS, queue, data, __fill_item);
  dispatch_apply_f(NR_ITEMS, queue, data, __work_on_item);

  /* Brief review of the items */
  dispatch_apply(NR_ITEMS, queue, ^(size_t n) {
    printf("Results: Item %lu = %d\n", n, data[n]);
  });

  return(0);
}

Friday, May 1, 2009

iPhone: Touch, Drag, Hit!

Yesterday, Fredrik has asked me something like "Drag & Drop with Hit Test" on the iPhone. Here's a simple example.  There's a simple UIView class that handles the touch events and a protocol that says that if the "DragMe View" has hit or not the "HitMe View". Below you can see the result and the Source Code Link.

The source code is available here: Touch, Drag, Hit Source Code.

Saturday, March 28, 2009

iPhone: Download and Display Gravatar

Back to the real iPhone for a while... Gravatar, or globally recognized avatar, is an interesting free service. It can be integrated with AddressBook app or other apps that can have a picture related to email address. Here an Objective-C Example to retrive the Gravatar. It's really simple!

The Source Code is Available Here: iPhone Gravatar Example.

The Apple Worldwide Developers Conference (WWDC) takes place June 8-12, 2009 held at Moscone Center West in San Francisco. http://developer.apple.com/WWDC/.

Sunday, March 8, 2009

Cocoa: Sidebar with Badges, Take 2

Do you remember the Cocoa Sidebar? No, Take a Look at this post Cocoa Sidebar with Badges.

Joel asked me to revise the Sidebar, allowing to add/remove and do other operation at any time.

I've rewritten all the code of the Sidebar, and I've added a couple of new features, like the default action handler and obviously the ability to add, remove items and badges at any time.

All the past features, like Drag & Drop are still present, but there's something else to do to improve it. If You've suggestions, patches or something else post a comment or send me a mail!

The Source Code is Available Here: Cocoa Sidebar 2 Source Code.

Update 10 March 2008 - Source Updated with Fixes.

Saturday, February 28, 2009

Cocoa: Drag & Drop

Today a simple example of Drag & Drop with Cocoa and NSView. The screenshot below shows two groups. In the first one, you can drop the photos on your filesystem, taken from Desktop or Finder. In the second group, you can only drop the first group image.

You can find the source code here: Drag & Drop Test Source Code.

Saturday, December 6, 2008

WebKit: Dynamic Content

Today I've played a bit with WebKit. I Want do something like Cocoa VBox View and NSScrollView but with more flexibility. Below you can see the example result.
The interesting part of this example is How to manage WebKit content, and how to add something dynamically.

I use webView:decidePolicyForNavigationAction:request:frame:decisionListener: of WebPolicyDelegate Protocol to handle my custom requests, in this way...

- (void)webView:(WebView *)sender 
         decidePolicyForNavigationAction:(NSDictionary *)actionInformation
         request:(NSURLRequest *)request frame:(WebFrame *)frame
         decisionListener:(id)listener
{
  if ([[[request URL] path] isEqualToString:@"PATH to Handle"]) {
    [listener ignore];
    // Handle Request
  } else {
    [listener use];
  }
}

...Then with a little bit of JavaScript I'll set my dynamic content loaded from Database or somewhere else.

NSArray *args = [NSArray arrayWithObjects:@"Item1Content", 
@"Hi, I'm Test 1 Content", nil];
[[webKit windowScriptObject] callWebScriptMethod:@"fillElement" 
withArguments:args];

The fillElement method is a simple JS function like this document.getElementById(elem).innerHTML = data;

Here you can find the Source Code.

Friday, November 28, 2008

Objective-C: SQLite Wrapper

I've written a simple SQLite Wrapper with two Examples one for Mac and one for the iPhone. The Wrapper class has the same source code for both platforms.

Here you can find the Mac Example Source Code and the iPhone Example Source Code.


This is a simple usage example:

Sqlite *sqlite = [[Sqlite alloc] init];

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory
stringByAppendingPathComponent:@"SQLiteTest.db"];
if (![sqlite open:writableDBPath])
  return;

[sqlite executeNonQuery:@"CREATE TABLE test (key TEXT NOT NULL, value TEXT);"];
[sqlite executeNonQuery:@"DELETE FROM test;"];
[sqlite executeNonQuery:@"INSERT INTO test VALUES (?, ?);",
[Sqlite createUuid], @"PROVA"];
[sqlite executeNonQuery:@"INSERT INTO test VALUES (?, ?);",
[Sqlite createUuid], @"PROVA 2"];
[sqlite executeNonQuery:@"INSERT INTO test VALUES (?, ?);",
[Sqlite createUuid], @"PROVA 3"];

NSArray *results = [sqlite executeQuery:@"SELECT * FROM test;"];
for (NSDictionary *dictionary in results) {
  NSLog(@"Row");
  for (NSString *key in [dictionary keyEnumerator])
    NSLog(@" - %@ %@", key, [dictionary objectForKey:key]);
}

[results release];
[sqlite release];

Sunday, November 16, 2008

Cocoa: VBox View and NSScrollView

Following the post of yesterday, today I've implemented a simple VBoxView (Vertical Box Layout) that allow you to lines up NSViews vertically.
Here you can find the example Source Code.

Saturday, November 15, 2008

Cocoa: Drawing Images, Texts and Shadows

Today I'm playing a bit with Quartz and Cocoa Drawing system (that is based on Quartz).

I've made a simple example that you can see below where I've used custom NSView that draws an Image and a Bezier Path with some text inside, and around the Bezier Path there's a Shadow.
...And this is the drawRect method source code of the custom NSView.

- (void)drawRect:(NSRect)frameRect {
  [NSGraphicsContext saveGraphicsState];

  [[NSColor colorWithCalibratedRed:0.64 green:0.66 blue:0.71 alpha:1.0] set];
  NSRectFill(frameRect);

  /* Draw Shadow */
  NSShadow *shadow = [[NSShadow alloc] init];
  [shadow setShadowColor:[[NSColor blackColor] colorWithAlphaComponent:0.5]];
  [shadow setShadowOffset:NSMakeSize(4.0, -4.0)];
  [shadow setShadowBlurRadius:3.0];
  [shadow set];

  /* Draw Control */
  NSRect myRect = NSMakeRect(80, 50, frameRect.size.width - 120, 60);
  NSBezierPath *path = [NSBezierPath bezierPath];
  [path setLineJoinStyle:NSRoundLineJoinStyle];
  [path appendBezierPathWithRoundedRect:myRect xRadius:8.0 yRadius:8.0];    

  [path moveToPoint:NSMakePoint(80, 75)];
  [path lineToPoint:NSMakePoint(65, 85)];
  [path lineToPoint:NSMakePoint(80, 95)];

  NSColor *startingColor = [NSColor colorWithCalibratedRed:0.90
  green:0.92 blue:0.85 alpha:1.0];
  NSColor *endingColor = [NSColor colorWithCalibratedRed:0.81
                               green:0.83 blue:0.76 alpha:1.0];
  NSGradient *gradient = [[[NSGradient alloc] initWithStartingColor:startingColor
                              endingColor:endingColor] autorelease];
  [path fill];
  [gradient drawInBezierPath:path angle:90];

  [NSGraphicsContext restoreGraphicsState];

  [shadow release];

  NSImage *image = [NSImage imageNamed:NSImageNameUser];
  [image drawInRect:NSMakeRect(15, 50, 50, 50) fromRect:NSZeroRect
                operation:NSCompositeSourceOver fraction:1.0];

  NSString *string = [NSString stringWithString:@"Text\nMore Text"];
  [string drawInRect:NSMakeRect(90, 60, frameRect.size.width - 140, 45)
               withAttributes:nil];
}

Sunday, November 9, 2008

Cocoa: Filterbar Control

This morning I've created this FilterBar (take a look at the picture below). You can add custom NSView and you can manage you groups with delegates.
so here is the link of Cocoa Filterbar Demo. And here you can find the Cocoa Filterbar Souce.

Saturday, November 8, 2008

Cocoa: Horizontal Box

It's a couple of days that I'm searching for something like QHBoxLayout (Qt Horizonal Box Layout) in Cocoa. There's NSMatrix that do something like this... but it uses NSCell and it sets the same size for all the cells, so this is not what I want. My solution is a simple NSView subclass...

And This is a simple "Main" to test the HBox.
- (NSTextField *)createTextField:(NSString *)text {
  NSTextField *field = [[NSTextField alloc] init];
  [field setStringValue:text];
  return [field retain];
}

- (NSButton *)createButton:(NSString *)caption {
  NSButton *button = [[NSButton alloc] init];
  [button setBezelStyle:NSRecessedBezelStyle];
  [button setButtonType:NSPushOnPushOffButton];
  [[button cell] setHighlightsBy:(NSCellIsBordered | NSCellIsInsetButton)];
  [button setShowsBorderOnlyWhileMouseInside:YES];
  [button setButtonType:NSOnOffButton];
  [button setTitle:caption];

  return [button retain];
}

- (void)awakeFromNib {
  [box addItem:[self createTextField:@"Label 1"]];
  [box addItem:[self createButton:@"Button 1"]];
  [box removeItemAtIndex:0];
  [box addItem:[self createTextField:@"Label 2"]];
  [box addItem:[self createButton:@"Say"]];
}

Download Here the Test Cocoa HBox Source.

Sunday, November 2, 2008

Quick Look: Look before you launch

Quick Look is a technology introduced in Mac OS X version 10.5 that enables client applications, such as Spotlight and the Finder, to display thumbnail images and full-size previews of documents.
Here you can Find the source code example: TestQuickLook.zip

Sunday, October 26, 2008

Cocoa: System StatusBar Item (Aka TrayBar)

Today's example is "How to add your own Item inside System Status Bar". It's really easy but the Apple OS X Human Interface Guidelines discourage it, at the end of the post you can find the Apple HIG notes.


Something about Names... Apple HIG call this MenuBar part "MenuBar Extra" (See Apple HIG Part III - The Menu Bar and Its Menus) using Cocoa you can get it from NSStatusBar systemStatusBar.

Saturday, October 25, 2008

Cocoa: Image Pattern as NSView Background

I Really like Apple Mail Note Editor, and today I've tried to do something like notes of Mail.app

Mail uses html and css loaded into a WebView (WebKit) to render the background of the window. I've used a simple NSView, I've Inherited from it and I've added a couple of feature to render an image as background pattern. Below you can see the result and here you can Download the Source.

Saturday, October 11, 2008

Cocoa: Notification Badge

I Really like iPhone notifications... a little badge appears on the application's icon and displays something. For example in Apple Mail it displays the number of the unread mails.

Now the Code! a simple method that take an argument that is the number to show on the badge. (IMPORTANT: Take a look at the code, there're appIcon.tiff and starIcon.tiff that you should have in your Project's Resources).
-(void)showNotifyCountOnApplicationIcon: (int) currentCountOfUnread
{
  NSImage *originalIcon = [NSImage imageNamed:@"appIcon.tiff"];
  NSString *countdown = [NSString stringWithFormat:@"%i", currentCountOfUnread];
  NSImage *iconImageBuffer = [originalIcon copy];
  NSSize iconSize = [originalIcon size];

  // Create attributes for drawing the count.
  NSDictionary * attributes = [[NSDictionary alloc]
  initWithObjectsAndKeys:[NSFont fontWithName:@"Helvetica-Bold" size:32],
  NSFontAttributeName, [NSColor whiteColor],
  NSForegroundColorAttributeName, nil];
  NSSize numSize = [countdown sizeWithAttributes:attributes];

  // Create a red circle in the icon large enough to hold the count.
  [iconImageBuffer lockFocus];
  [originalIcon drawAtPoint:NSMakePoint(0, 0)
          fromRect:NSMakeRect(0, 0, iconSize.width, iconSize.height)
          operation:NSCompositeSourceOver
          fraction:1.0f];

  float max = (numSize.width > numSize.height) ? numSize.width : numSize.height;
  max += 28;
  NSRect circleRect = NSMakeRect(iconSize.width - max,
  iconSize.height - max, max, max);

  // Draw the star image and scale it so the unread count will fit inside.
  NSImage * starImage = [NSImage imageNamed:@"starIcon.tiff"];
  [starImage setScalesWhenResized:YES];
  [starImage setSize:circleRect.size];
  [starImage compositeToPoint:circleRect.origin operation:NSCompositeSourceOver];

  // Draw the count in the red circle
  NSPoint point = NSMakePoint(NSMidX(circleRect) - numSize.width / 2.0f + 2.0f,
  NSMidY(circleRect) - numSize.height / 2.0f + 2.0f);
  [countdown drawAtPoint:point withAttributes:attributes];

  // Now set the new app icon and clean up.
  [iconImageBuffer unlockFocus];
  [NSApp setApplicationIconImage:iconImageBuffer];
  [iconImageBuffer release];
  [attributes release];
}

With Mac OS X Leopard was introduced NSDockTile class that lets you customize the visual representation for your application’s miniaturized windows and application icon as they appear in the dock. So with this class you can easily add Notification Badge in this way.
NSDockTile *dockTile = [NSApp dockTile];

// setup our image view for the dock tile
NSRect frame = NSMakeRect(0, 0, dockTile.size.width, dockTile.size.height);
NSImageView *dockImageView = [[NSImageView alloc] initWithFrame: frame];
[dockImageView setImage: [NSImage imageNamed:@"appIcon.tiff"]];

// by default, add it to the NSDockTile
[dockTile setContentView: dockImageView];
[dockTile display];

// Show Notification Badge '45'
[dockTile setShowsApplicationBadge:YES];
[dockTile setBadgeLabel:@"45"];

Monday, August 11, 2008

Qt4 Mac Dock Icon Click

When you click the "close button" of an application's window, on Mac OS X the window will be hidden but the application continue running. When you click on the Dock Icon, the application's window will be showed. This is the default behaviour for Mac Apps but Qt Apps doesn't the same. So, how we could implement this behaviour?
#ifndef _APPLICATION_H_
#define _APPLICATION_H_

// Qt4 Headers
include <QApplication>
include <QWidget>

// Carbon Headers
#ifdef Q_WS_MAC
#include <Carbon/Carbon.h>
#endif

class Application : public QApplication {
Q_OBJECT

public:
Application (int& argc, char **argv);

QWidget *mainWindow (void) const;

private:
QWidget *m_mainWindow;

#ifdef Q_WS_MAC
AEEventHandlerUPP m_appleEventProcessorUPP;
#endif
};

#endif // !_APPLICATION_H_

Here, we've implemented an Application class that Inherits from QApplication. This class contains a reference to the App's Main Window.
#ifdef Q_WS_MAC
static OSStatus appleEventProcessor(const AppleEvent *ae,
AppleEvent *event,
long handlerRefCon)
{
Application *app = (Application *) handlerRefCon;

OSType aeID = typeWildCard;
OSType aeClass = typeWildCard;

AEGetAttributePtr(ae, keyEventClassAttr, typeType, 0,
&aeClass, sizeof(aeClass), 0);
AEGetAttributePtr(ae, keyEventIDAttr, typeType, 0,
&aeID, sizeof(aeID), 0);

if (aeClass == kCoreEventClass) {
if (aeID == kAEReopenApplication) {
app->mainWindow()->show();
}
return noErr;
}

return eventNotHandledErr;
}
#endif

Application::Application (int& argc, char **argv)
: QApplication(argc, argv)
{
// Don't Quit the App on Window Close
setQuitOnLastWindowClosed(false);

// Initialize Main Window
m_mainWindow = new QLabel("Test Main Window");

#ifdef Q_WS_MAC
// Install Reopen Application Event (Dock Clicked)
m_appleEventProcessorUPP = AEEventHandlerUPP(appleEventProcessor);
AEInstallEventHandler(kCoreEventClass, kAEReopenApplication,
m_appleEventProcessorUPP, (long) this, true);
#endif
}

QWidget *Application::mainWindow (void) const {
return(m_mainWindow);
}

Thats all folks! Run the app, Click on close button and then click on the dock icon to see the result.