Skip to content

Commit

Permalink
Compute intrinsic size
Browse files Browse the repository at this point in the history
  • Loading branch information
tanin47 committed May 17, 2020
1 parent 9e756d7 commit 4933ee8
Show file tree
Hide file tree
Showing 12 changed files with 370 additions and 281 deletions.
6 changes: 6 additions & 0 deletions mac-app/Tip.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
F3A35D2D23D6301200982791 /* malformed_json_provider.rb in Resources */ = {isa = PBXBuildFile; fileRef = F3A35D2C23D6301200982791 /* malformed_json_provider.rb */; };
F3A35D3023D6344000982791 /* TipNoticeView.m in Sources */ = {isa = PBXBuildFile; fileRef = F3A35D2F23D6344000982791 /* TipNoticeView.m */; };
F3A35D3223D636ED00982791 /* empty_provider.rb in Resources */ = {isa = PBXBuildFile; fileRef = F3A35D3123D636EC00982791 /* empty_provider.rb */; };
F3C248222470A6D3003EA099 /* WrappedTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = F3C248212470A6D3003EA099 /* WrappedTextView.m */; };
F3E5B64B23BA846A002BEDD6 /* FontAwesome-Solid.otf in Resources */ = {isa = PBXBuildFile; fileRef = F3E5B64A23BA846A002BEDD6 /* FontAwesome-Solid.otf */; };
F3EA2538246A528000B21837 /* auto_execute_url_provider.rb in Resources */ = {isa = PBXBuildFile; fileRef = F3EA2537246A528000B21837 /* auto_execute_url_provider.rb */; };
FA0E180D23E6AD86006B4DD6 /* TipUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA0E180C23E6AD86006B4DD6 /* TipUITests.swift */; };
Expand Down Expand Up @@ -78,6 +79,8 @@
F3A35D2E23D6344000982791 /* TipNoticeView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TipNoticeView.h; sourceTree = "<group>"; };
F3A35D2F23D6344000982791 /* TipNoticeView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TipNoticeView.m; sourceTree = "<group>"; };
F3A35D3123D636EC00982791 /* empty_provider.rb */ = {isa = PBXFileReference; lastKnownFileType = text.script.ruby; path = empty_provider.rb; sourceTree = "<group>"; };
F3C248202470A6D3003EA099 /* WrappedTextView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WrappedTextView.h; sourceTree = "<group>"; };
F3C248212470A6D3003EA099 /* WrappedTextView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WrappedTextView.m; sourceTree = "<group>"; };
F3E5B64A23BA846A002BEDD6 /* FontAwesome-Solid.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "FontAwesome-Solid.otf"; sourceTree = "<group>"; };
F3EA2537246A528000B21837 /* auto_execute_url_provider.rb */ = {isa = PBXFileReference; lastKnownFileType = text.script.ruby; path = auto_execute_url_provider.rb; sourceTree = "<group>"; };
FA0E180723E6A7D3006B4DD6 /* TipUITests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "TipUITests-Bridging-Header.h"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -150,6 +153,8 @@
F3A35D2F23D6344000982791 /* TipNoticeView.m */,
F357936223E66CD600031E09 /* AppDelegate.h */,
F357936323E66CD600031E09 /* AppDelegate.m */,
F3C248202470A6D3003EA099 /* WrappedTextView.h */,
F3C248212470A6D3003EA099 /* WrappedTextView.m */,
);
path = Tip;
sourceTree = "<group>";
Expand Down Expand Up @@ -299,6 +304,7 @@
F300998123B8159D0000B9E3 /* main.m in Sources */,
F30CBFF123B9A154008D6B47 /* TipTableView.m in Sources */,
F3A35D3023D6344000982791 /* TipNoticeView.m in Sources */,
F3C248222470A6D3003EA099 /* WrappedTextView.m in Sources */,
F30099A623B816AF0000B9E3 /* Receiver.m in Sources */,
F37DB94723D548E7002D799E /* ForTest.m in Sources */,
);
Expand Down
2 changes: 1 addition & 1 deletion mac-app/Tip/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.3.0-rc1</string>
<string>1.3.0-rc2</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
Expand Down
3 changes: 0 additions & 3 deletions mac-app/Tip/TipItemTextField.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ NS_ASSUME_NONNULL_BEGIN

@interface TipItemTextField : NSTextField

@property (nonatomic, retain) NSLayoutConstraint* widthConstraint;
@property (nonatomic, retain) NSLayoutConstraint* heightConstraint;

@end

NS_ASSUME_NONNULL_END
37 changes: 12 additions & 25 deletions mac-app/Tip/TipItemTextField.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,21 @@
//

#import "TipItemTextField.h"
#import "VeritcallyAlignNSTextFieldCell.h"

@implementation TipItemTextField

- (void) setStringValue:(NSString *)stringValue {
[super setStringValue:stringValue];

CGSize textSize = [self getTextSize:stringValue];

CGFloat width = textSize.width;
CGFloat height = MAX(16, textSize.height);

self.frame = NSMakeRect(self.frame.origin.x, self.frame.origin.y, width, height);

[self removeConstraint:_widthConstraint];
[self removeConstraint:_heightConstraint];
_widthConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:width];
_heightConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:height];
[self addConstraint:_widthConstraint];
[self addConstraint:_heightConstraint];
self.needsLayout = true;
}

- (CGSize) getTextSize:(NSString *) text {
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:self.font, NSFontAttributeName, nil];
NSMutableAttributedString *as = [[NSMutableAttributedString alloc] initWithString:text attributes:attributes];
CGSize size = [as size];
size.width += 4;
return size;
- (instancetype)init {
if (self = [super init]) {
self.cell = [VeritcallyAlignNSTextFieldCell new];
self.editable = NO;
self.selectable = YES;
self.bezeled = NO;
self.drawsBackground = NO;
self.font = [NSFont fontWithName:@"RobotoMono-Regular" size:12];
self.lineBreakMode = NSLineBreakByTruncatingTail;
}
return self;
}

@end
11 changes: 5 additions & 6 deletions mac-app/Tip/TipNoticeView.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//

#import <Cocoa/Cocoa.h>
#import "TipItem.h"

NS_ASSUME_NONNULL_BEGIN

Expand All @@ -18,17 +19,15 @@ typedef NS_ENUM(NSInteger, TipNoticeViewAction) {

@interface TipNoticeView : NSView

- (instancetype)initWithFrame:(NSRect)frame;
- (void) updateWithMessage:(NSString*) message icon:(UniChar)icon action:(TipNoticeViewAction)action;

@property NSTextField* textField;
@property NSTextView* textField;
@property NSTextField* iconField;

@property TipNoticeViewAction action;

- (void) updateWithItems:(nonnull NSArray<TipItem *> *)items andError:(NSException *) error;

@property (nonatomic, retain) NSLayoutConstraint* heightConstraint;
@property (nonatomic, retain) NSLayoutConstraint* widthConstraint;

@property CGSize preferredSize;

@end

Expand Down
93 changes: 64 additions & 29 deletions mac-app/Tip/TipNoticeView.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,60 +8,95 @@

#import "TipNoticeView.h"
#import "VeritcallyAlignNSTextFieldCell.h"
#import "WrappedTextView.h"

@implementation TipNoticeView

- (instancetype)initWithFrame:(NSRect)frame{
if (self = [super initWithFrame:frame]) {
_iconField = [[NSTextField alloc] initWithFrame:frame];
_iconField.cell.font = [NSFont fontWithName:@"Font Awesome 5 Free" size:14];
- (instancetype)init{
if (self = [super init]) {
self.translatesAutoresizingMaskIntoConstraints = NO;

_iconField = [[NSTextField alloc] init];
_iconField.identifier = @"iconField";
_iconField.translatesAutoresizingMaskIntoConstraints = NO;
_iconField.cell.font = [NSFont fontWithName:@"Font Awesome 5 Free" size:16];
_iconField.editable = NO;
_iconField.selectable = NO;
_iconField.bezeled = NO;
_iconField.drawsBackground = NO;
_iconField.alignment = NSTextAlignmentCenter;
[self addSubview:_iconField];

_textField = [[NSTextField alloc] init];
_textField.cell = [VeritcallyAlignNSTextFieldCell new];
_textField.cell.font = [NSFont fontWithName:@"RobotoMono-Regular" size:13];

_textField = [[WrappedTextView alloc] init];
_textField.identifier = @"textField";
_textField.translatesAutoresizingMaskIntoConstraints = NO;
_textField.font = [NSFont fontWithName:@"RobotoMono-Regular" size:13];
_textField.editable = NO;
_textField.selectable = NO;
_textField.bezeled = NO;
_textField.drawsBackground = NO;
_textField.alignment = NSTextAlignmentLeft;
[self addSubview:_textField];

NSDictionary *viewDict = NSDictionaryOfVariableBindings(_iconField, _textField);
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-3-[_iconField]-1-[_textField]-2-|" options:0 metrics:nil views:viewDict]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-5-[_iconField]-(>=0)-|" options:0 metrics:nil views:viewDict]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-2-[_textField]-5-|" options:0 metrics:nil views:viewDict]];

[_iconField setContentCompressionResistancePriority:NSLayoutPriorityRequired forOrientation:NSLayoutConstraintOrientationVertical];
[_iconField setContentCompressionResistancePriority:NSLayoutPriorityRequired forOrientation:NSLayoutConstraintOrientationHorizontal];

[_textField setContentCompressionResistancePriority:NSLayoutPriorityRequired forOrientation:NSLayoutConstraintOrientationVertical];
[_textField setContentCompressionResistancePriority:NSLayoutPriorityRequired forOrientation:NSLayoutConstraintOrientationHorizontal];
}

return self;
}

- (void) updateWithItems:(NSArray *)items andError:(NSException *)error {
if (error) {
NSString *message = nil;
TipNoticeViewAction action = TipNoticeViewActionNone;

if ([error.name isEqualToString:@"MalformedJsonException"]) {
message = @"Malformed JSON returned from provider. Click to see logs in Console. You'll need to set the filter Process=Tip.";
action = TipNoticeViewActionOpenConsole;
} else if ([error.name isEqualToString:@"ProviderNotExistException"]) {
message = [NSString stringWithFormat:@"%@ doesn't exist. Please make a provider script. Click to see instruction.", [error.userInfo objectForKey:@"provider"]];
action = TipNoticeViewActionOpenProviderInstruction;
} else if ([error.name isEqualToString:@"ProviderNotExecutableException"]) {
message = [NSString stringWithFormat:@"Provider isn't executable. Please chmod 755 %@", [error.userInfo objectForKey:@"provider"]];
} else {
message = @"Error occurred. Click to see logs in Console. You'll need to set the filter Process=Tip.";
action = TipNoticeViewActionOpenConsole;
}

[self updateWithMessage:message
icon:0xf06a
action:action];
} else if (items.count == 0) {
[self updateWithMessage:@"No tips. You can add tips through your provider script. Click to see the instruction."
icon:0xf59a
action:TipNoticeViewActionOpenProviderInstruction];
} else {
[self updateWithMessage:@"No error."
icon:0xf06a
action:TipNoticeViewActionOpenConsole];
}
}

- (void) updateWithMessage:(NSString*)message
icon:(UniChar)icon
action:(TipNoticeViewAction)action {
self.action = action;

_textField.stringValue = message;

_textField.string = message;
_iconField.stringValue = [NSString stringWithFormat:@"%C", icon];

NSSize size = [_textField.cell cellSizeForBounds:NSMakeRect(0, 0, self.frame.size.width - 40, FLT_MAX)];
_textField.frame = NSMakeRect(
self.frame.origin.x + 30,
self.frame.origin.y + 8,
size.width,
size.height);
_iconField.frame = NSMakeRect(self.frame.origin.x + 5, size.height + 10 - 30, 25, 25);
self.frame = NSMakeRect(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, size.height + 15);

[self removeConstraint:_widthConstraint];
[self removeConstraint:_heightConstraint];

_widthConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:self.frame.size.width];
_heightConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:self.frame.size.height];
[self addConstraint:_widthConstraint];
[self addConstraint:_heightConstraint];
self.needsLayout = YES;

_preferredSize = CGSizeMake(3 + _iconField.intrinsicContentSize.width + 1 + _textField.intrinsicContentSize.width + 2, 2 + _textField.intrinsicContentSize.height + 5);
}

- (NSSize)intrinsicContentSize {
return _preferredSize;
}

- (void)resetCursorRects {
Expand Down
9 changes: 5 additions & 4 deletions mac-app/Tip/TipTableController.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,16 @@ NS_ASSUME_NONNULL_BEGIN

@interface TipTableController : NSViewController<NSTableViewDataSource, NSTableViewDelegate>

@property (nonatomic) NSArray<TipItem*>* items;
@property (nonatomic) NSException* error;
@property TipNoticeView* noticeView;
@property TipTableView* table;
@property NSTableColumn* iconColumn;
@property NSTableColumn* textColumn;

@property (nonatomic) NSException* error;
@property (nonatomic) NSArray<TipItem*>* items;

- (void) performAction:(NSUInteger)row;

- (void)setItems:(nonnull NSArray<TipItem *> *)items;

@end

NS_ASSUME_NONNULL_END
Loading

0 comments on commit 4933ee8

Please sign in to comment.