Skip to content
This repository has been archived by the owner on Sep 18, 2021. It is now read-only.

TwUI ease of use updates #115

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 9 additions & 8 deletions README.md
@@ -1,15 +1,16 @@
# TwUI 0.2.0
# TwUI 0.5.0r1

TwUI is a hardware accelerated UI framework for Mac, inspired by UIKit. It enables:
TwUI is a hardware accelerated UI framework for Mac, inspired by, and somewhat code-compatible with UIKit. It enables:

* GPU accelerated rendering backed by CoreAnimation
* Simple model/view/controller development familiar to iOS developers
* Similar API, and near-perfect drag and drop iOS support.

It differs from UIKit in a few ways:

* Simplified table view cells
* Block-based layout and drawRect
* A consistent coordinate system (bottom left origin)
* A consistent coordinate system (bottom left origin, like Core Graphics)
* Sub-pixel text rendering

# Setup
Expand All @@ -22,11 +23,11 @@ Your TUIView-based view hierarchy is hosted inside an TUINSView, which is the br

# Example Project

An included example project shows off the basic construction of a pure TwUI-based app. A TUINSView is added as the content view of the window, and some TUIView-based views are hosted in that. It includes a table view, and a tab bar (which is a good example of how you might build your own custom controls).
An included example project shows off the basic construction of a pure TwUI-based app. A TUINSView is added as the content view of the window, and some TUIView-based views are hosted in that. It includes a table view, and a basic tab bar (which is a good example of how you might build your own custom controls).

# Status

TwUI should be considered an alpha project. It is current shipping in Twitter for Mac, in use 24/7 by many, many users and has proven itself very stable. The code still has a few Twitter-for-Mac-isms that should be refactored and cleaned up.
TwUI should be considered an alpha project. It is current shipping in Twitter for Mac, Github for Mac, in use 24/7 by many, many users and has proven itself very stable. The code still has a few Twitter-for-Mac-isms that should be refactored and cleaned up.

This project follows the [SemVer](http://semver.org/) standard. The API may change in backwards-incompatible ways before the 1.0 release.

Expand All @@ -36,9 +37,9 @@ The goal of TwUI is to build a high-quality UI framework designed specifically f

There are many places where TwUI could be improved:

* Accessibility. It would be great to bridge the AppKit accessibility APIs to something simpler, again, inspired by UIKit.
* Accessibility. It would be great to bridge the AppKit accessibility APIs to something simpler, again, inspired by UIKit. The current accessibility APIs are not completely feature filled either.

* Text editing. TUITextEditor is a simple text editor (built on TUITextRenderer). It provides basic editing support and handles a number of standard keybindings. Fleshing this out to be indistinguishable from NSTextView (read: spellchecking, autocorrect) would be useful. If the logic around this were self-contained it would even be great as a standalone project, useful for anyone looking to build a custom text editor for the Mac.
* Text editing. TUITextEditor is a simple text editor built on TUITextRenderer. It provides basic editing support and handles a number of standard keybindings. Fleshing this out to be indistinguishable from NSTextView would be useful.

* Reverse-hosting. Right now TUIViews may be hosted inside of an existing NSView hierarchy. It would be useful if the reverse were possible, adding NSViews inside of TUIViews. Doing so in a robust way so event routing, the responder chain, and CAAnimations all just work is a challenge.

Expand All @@ -54,7 +55,7 @@ TwUI has a mailing list, subscribe by sending an email to <twui@librelist.com>.

# Copyright and License

Copyright 2011 Twitter, Inc.
Copyright 2011-2012 Twitter, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this work except in compliance with the License.
Expand Down
112 changes: 76 additions & 36 deletions lib/UIKit/TUINSWindow.h
Expand Up @@ -17,29 +17,43 @@
#import <Cocoa/Cocoa.h>
#import "TUINSView.h"

// BASED ON THE INAppStoreWindow by indragiek, and
// the TUINSWindow that was used for Twitter for Mac.
// A combo pack that sets everything up for you!
// The implementation code shows how it's done.

// A general set of window additions to support
// any NSWindow housing a TUINSView to be able
// to use TUIViews instead of NSViews in them.
// It is recommended to use TUIWindows instead
// of generic NSWindows because of the in-built
// performance gains and flexibility, however.
@interface NSWindow (TUIWindowAdditions)

// Return the array of TUINSViews in the heirarchy.
- (NSArray *)TUINSViews;
- (void)setEverythingNeedsDisplay;

- (BOOL)tui_containsObjectInResponderChain:(NSResponder *)r;

/*
If you know you need to make something first responder in the future (say, after an animation completes),
but not if something is made first responder in the meantime, use this:
1. request a token with futureMakeFirstResponderRequestToken
2. when the animation completes, try to make first responder with
makeFirstResponder:withFutureRequestToken:
3. it will succeed if nothing else made something else first responder before you did

Currently used by TUITableView for when you're arrowing around really fast, and switch sections before
the selected cell comes onscreen.

Note this has only been tested with a NSWindow subclass that overrides -makeFirstResponder directly,
not with a vanilla NSWindow since I started moving these methods into a category.
*/
// Set -setNeedsDisplay on all TUIView subviews.
- (void)setEverythingNeedsDisplay;

- (BOOL)tui_makeFirstResponder:(NSResponder *)aResponder; // increments future token
// Check if a responder exists in the chain. Note
// that this also applies to TUIResponder, as the
// TUIResponder is an NSResponder subclass.
- (BOOL)TUI_containsObjectInResponderChain:(NSResponder *)r;

// If you know you need to make something first
// responder in the future (say, after an animation
// completes), but not if something is made first
// responder in the meantime, use this:
//
// 1. Request a token with futureMakeFirstResponderRequestToken.
// 2. When the animation completes, try to make first responder with:
// makeFirstResponder:withFutureRequestToken:
// 3. It will succeed if nothing else made something
// else first responder before you did.

// Increments future token and makes responder.
- (BOOL)TUI_makeFirstResponder:(NSResponder *)aResponder;

- (NSInteger)futureMakeFirstResponderRequestToken;
- (BOOL)makeFirstResponder:(NSResponder *)aResponder withFutureRequestToken:(NSInteger)token;
Expand All @@ -48,28 +62,54 @@

@end

/*
If you're not Twitter for Mac, you probably don't want to use TUINSWindow.
Just use a plain NSWindow, this class will likely be removed from TUIKit
once a bit of cleanup happens on Twitter for Mac. See the category above
for stuff that you can use on any NSWindow instance.
*/
// Draws a default style Mac OS X title bar.
@interface TUITitlebarView : NSView
@end

@interface TUINSWindow : NSWindow <NSWindowDelegate>
{
TUINSView *nsView;
NSMutableArray *altUINSViews; // kill
}
// A performance-optimized pre-built TUINSView
// heirarchial container window, which is still
// Cocoa compatible. Set the rootView to your
// TUIView of choice, and everything else is automatic.
@interface TUIWindow : NSWindow

- (id)initWithContentRect:(CGRect)rect;
// The height of the title bar. By default, this is set
// to the standard title bar height, 22px.
@property (nonatomic) CGFloat titleBarHeight;

- (void)drawBackground:(CGRect)rect;
// The title bar view itself. Add subviews to this view
// that you want to show in the title bar (e.g. buttons,
// a toolbar, etc.). This view can also be set if you
// want to use a different styled title bar aside from
// the default one (textured, etc.).
@property (nonatomic, retain) NSView *titleBarView;

- (CGFloat)toolbarHeight;
// Set whether the fullscreen or traffic light buttons are horizontally centered.
@property (nonatomic) BOOL centerFullScreenButton;
@property (nonatomic) BOOL centerTrafficLightButtons;

@property (nonatomic, readonly) TUINSView *nsView;
@property (nonatomic, readonly) NSMutableArray *altUINSViews; // add to this to participate in setEverythingNeedsDisplay
// Set whether you want the title bar to hide in fullscreen mode.
@property (nonatomic) BOOL hideTitleBarInFullScreen;

@end
// Set whether the baseline TUIWindow draws between itself and the main window contents is shown.
@property (nonatomic) BOOL showsBaselineSeparator;

// Adjust the left and right padding of the trafficlight and fullscreen buttons.
@property (nonatomic) CGFloat trafficLightButtonsLeftMargin;
@property (nonatomic) CGFloat fullScreenButtonRightMargin;

extern NSRect ABClampProposedRectToScreen(NSRect proposedRect);
// Get the container TUINSView or the set the root view TUIView.
@property (nonatomic, readonly) TUINSView *containerView;
@property (nonatomic, retain) TUIView *rootView;

// An overridable block to customize the TUIWindow's titlebar drawing.
typedef void (^TUIWindowTitleBarDrawingBlock)(BOOL drawsAsMainWindow,
CGRect drawingRect,
CGPathRef clippingPath);
@property (nonatomic, copy) TUIWindowTitleBarDrawingBlock titleBarDrawingBlock;

// Simpler initialization methods than those for the NSWindow.
- (id)initWithContentRect:(NSRect)contentRect;
- (id)initWithContentRect:(NSRect)contentRect screen:(NSScreen *)screen;
- (id)initBorderlessWithContentRect:(NSRect)contentRect;

@end