Skip to content

Commit

Permalink
MMTabline: a new tabline for MacVim
Browse files Browse the repository at this point in the history
  • Loading branch information
sfsam committed Sep 15, 2024
1 parent a24ac02 commit 7283c1d
Show file tree
Hide file tree
Showing 131 changed files with 1,225 additions and 9,311 deletions.
2 changes: 1 addition & 1 deletion runtime/doc/gui_mac.txt
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ KEY VALUE ~
*MMSmoothResize* allow smooth resizing of MacVim window [bool]
*MMShareFindPboard* share search text to Find Pasteboard [bool]
*MMShowAddTabButton* enable "add tab" button on tabline [bool]
*MMTabMaxWidth* maximum width of a tab [int]
*MMShowTabScrollButtons* enable tab scroll buttons on tabline [bool]
*MMTabMinWidth* minimum width of a tab [int]
*MMTabOptimumWidth* default width of a tab [int]
*MMTextInsetBottom* text area offset in pixels [int]
Expand Down
2 changes: 1 addition & 1 deletion runtime/doc/tags
Original file line number Diff line number Diff line change
Expand Up @@ -5645,9 +5645,9 @@ MMRendererClipToRow gui_mac.txt /*MMRendererClipToRow*
MMScrollOneDirectionOnly gui_mac.txt /*MMScrollOneDirectionOnly*
MMShareFindPboard gui_mac.txt /*MMShareFindPboard*
MMShowAddTabButton gui_mac.txt /*MMShowAddTabButton*
MMShowTabScrollButtons gui_mac.txt /*MMShowTabScrollButtons*
MMShowWhatsNewOnStartup gui_mac.txt /*MMShowWhatsNewOnStartup*
MMSmoothResize gui_mac.txt /*MMSmoothResize*
MMTabMaxWidth gui_mac.txt /*MMTabMaxWidth*
MMTabMinWidth gui_mac.txt /*MMTabMinWidth*
MMTabOptimumWidth gui_mac.txt /*MMTabOptimumWidth*
MMTextInsetBottom gui_mac.txt /*MMTextInsetBottom*
Expand Down
22 changes: 3 additions & 19 deletions src/MacVim/MMAppController.m
Original file line number Diff line number Diff line change
Expand Up @@ -172,30 +172,14 @@ @implementation MMAppController
/// persisted user settings to have a clean environment.
+ (void)registerDefaults
{
int tabMinWidthKey;
int tabMaxWidthKey;
int tabOptimumWidthKey;
if (shouldUseYosemiteTabBarStyle()) {
tabMinWidthKey = 120;
tabMaxWidthKey = 0;
tabOptimumWidthKey = 0;
} else {
tabMinWidthKey = 64;
tabMaxWidthKey = 6*64;
tabOptimumWidthKey = 132;
}

NSUserDefaults *ud = NSUserDefaults.standardUserDefaults;

NSDictionary *macvimDefaults = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:NO], MMNoWindowKey,
[NSNumber numberWithInt:tabMinWidthKey],
MMTabMinWidthKey,
[NSNumber numberWithInt:tabMaxWidthKey],
MMTabMaxWidthKey,
[NSNumber numberWithInt:tabOptimumWidthKey],
MMTabOptimumWidthKey,
[NSNumber numberWithInt:120], MMTabMinWidthKey,
[NSNumber numberWithInt:200], MMTabOptimumWidthKey,
[NSNumber numberWithBool:YES], MMShowAddTabButtonKey,
[NSNumber numberWithBool:YES], MMShowTabScrollButtonsKey,
[NSNumber numberWithInt:2], MMTextInsetLeftKey,
[NSNumber numberWithInt:1], MMTextInsetRightKey,
[NSNumber numberWithInt:1], MMTextInsetTopKey,
Expand Down
1 change: 0 additions & 1 deletion src/MacVim/MMFullScreenWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
NSWindow *target;
MMVimView *view;
NSPoint oldPosition;
NSString *oldTabBarStyle;
int options;
int state;

Expand Down
9 changes: 0 additions & 9 deletions src/MacVim/MMFullScreenWindow.m
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
#import "MMVimView.h"
#import "MMWindowController.h"
#import "Miscellaneous.h"
#import <PSMTabBarControl/PSMTabBarControl.h>

// These have to be the same as in option.h
#define FUOPT_MAXVERT 0x001
Expand Down Expand Up @@ -169,12 +168,6 @@ - (void)enterFullScreen
// make target's window controller believe that it's now controlling us
[[target windowController] setWindow:self];

oldTabBarStyle = [[view tabBarControl] styleName];

NSString *style =
shouldUseYosemiteTabBarStyle() ? (shouldUseMojaveTabBarStyle() ? @"Mojave" : @"Yosemite") : @"Unified";
[[view tabBarControl] setStyleNamed:style];

// add text view
oldPosition = [view frame].origin;

Expand Down Expand Up @@ -268,8 +261,6 @@ - (void)leaveFullScreen
[self retain]; // NSWindowController releases us once
[[self windowController] setWindow:target];

[[view tabBarControl] setStyleNamed:oldTabBarStyle];

// fix delegate
id delegate = [self delegate];
[self setDelegate:nil];
Expand Down
11 changes: 11 additions & 0 deletions src/MacVim/MMTabline/MMHoverButton.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#import <Cocoa/Cocoa.h>

// A button that fades in a circular background when hovered.

@interface MMHoverButton : NSButton

@property (nonatomic, retain) NSColor *fgColor;

+ (NSImage *)imageNamed:(NSString *)name;

@end
140 changes: 140 additions & 0 deletions src/MacVim/MMTabline/MMHoverButton.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#import "MMHoverButton.h"

@implementation MMHoverButton
{
NSTrackingArea *_trackingArea;
NSBox *_circle;
}

+ (NSImage *)imageNamed:(NSString *)name
{
CGFloat size = [name isEqualToString:@"CloseTabButton"] ? 15 : 17;
return [NSImage imageWithSize:NSMakeSize(size, size) flipped:NO drawingHandler:^BOOL(NSRect dstRect) {
NSBezierPath *p = [NSBezierPath new];
if ([name isEqualToString:@"AddTabButton"]) {
[p moveToPoint:NSMakePoint( 8.5, 4.5)];
[p lineToPoint:NSMakePoint( 8.5, 12.5)];
[p moveToPoint:NSMakePoint( 4.5, 8.5)];
[p lineToPoint:NSMakePoint(12.5, 8.5)];
[p setLineWidth:1.2];
[p stroke];
}
else if ([name isEqualToString:@"CloseTabButton"]) {
[p moveToPoint:NSMakePoint( 4.5, 4.5)];
[p lineToPoint:NSMakePoint(10.5, 10.5)];
[p moveToPoint:NSMakePoint( 4.5, 10.5)];
[p lineToPoint:NSMakePoint(10.5, 4.5)];
[p setLineWidth:1.2];
[p stroke];
}
else if ([name isEqualToString:@"ScrollLeftButton"]) {
[p moveToPoint:NSMakePoint( 5.0, 8.5)];
[p lineToPoint:NSMakePoint(10.0, 4.5)];
[p lineToPoint:NSMakePoint(10.0, 12.5)];
[p fill];
}
else if ([name isEqualToString:@"ScrollRightButton"]) {
[p moveToPoint:NSMakePoint(12.0, 8.5)];
[p lineToPoint:NSMakePoint( 7.0, 4.5)];
[p lineToPoint:NSMakePoint( 7.0, 12.5)];
[p fill];
}
return YES;
}];
}

- (instancetype)initWithFrame:(NSRect)frameRect
{
self = [super initWithFrame:frameRect];
if (self) {
self.buttonType = NSButtonTypeMomentaryChange;
self.bordered = NO;
self.imagePosition = NSImageOnly;

// This view will fade in/out when hovered.
_circle = [NSBox new];
_circle.boxType = NSBoxCustom;
_circle.borderWidth = 0;
_circle.alphaValue = 0.16;
_circle.fillColor = NSColor.clearColor;
_circle.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
_circle.frame = self.bounds;
[self addSubview:_circle positioned:NSWindowBelow relativeTo:nil];
}
return self;
}

- (void)setFgColor:(NSColor *)color
{
_fgColor = color;
self.image = super.image;
}

- (void)setImage:(NSImage *)image
{
_circle.cornerRadius = image.size.width / 2.0;
NSColor *fillColor = self.fgColor ?: NSColor.controlTextColor;
super.image = [NSImage imageWithSize:image.size flipped:NO drawingHandler:^BOOL(NSRect dstRect) {
[image drawInRect:dstRect];
[fillColor set];
NSRectFillUsingOperation(dstRect, NSCompositingOperationSourceAtop);
return YES;
}];
self.alternateImage = [NSImage imageWithSize:image.size flipped:NO drawingHandler:^BOOL(NSRect dstRect) {
[[fillColor colorWithAlphaComponent:0.2] set];
[[NSBezierPath bezierPathWithOvalInRect:dstRect] fill];
[super.image drawInRect:dstRect];
return YES;
}];
}

- (void)setEnabled:(BOOL)enabled
{
[super setEnabled:enabled];
[self evaluateHover];
}

- (void)updateTrackingAreas
{
[self removeTrackingArea:_trackingArea];
_trackingArea = [[NSTrackingArea alloc] initWithRect:self.bounds options:(NSTrackingMouseEnteredAndExited | NSTrackingActiveInKeyWindow) owner:self userInfo:nil];
[self addTrackingArea:_trackingArea];
[self evaluateHover];
[super updateTrackingAreas];
}

- (void)backgroundCircleShouldHighlight:(BOOL)shouldHighlight
{
NSColor *fillColor = NSColor.clearColor;
if (shouldHighlight) {
fillColor = self.fgColor ?: NSColor.controlTextColor;
}
[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:0.1];
_circle.animator.fillColor = fillColor;
[NSAnimationContext endGrouping];
}

- (void)evaluateHover
{
NSPoint mouseLocation = [self.window mouseLocationOutsideOfEventStream];
mouseLocation = [self convertPoint:mouseLocation fromView:nil];
if (NSPointInRect(mouseLocation, self.bounds)) {
if (self.enabled) [self backgroundCircleShouldHighlight:YES];
else [self backgroundCircleShouldHighlight:NO];
} else {
[self backgroundCircleShouldHighlight:NO];
}
}

- (void)mouseEntered:(NSEvent *)event
{
if (self.enabled) [self backgroundCircleShouldHighlight:YES];
}

- (void)mouseExited:(NSEvent *)event
{
[self backgroundCircleShouldHighlight:NO];
}

@end
23 changes: 23 additions & 0 deletions src/MacVim/MMTabline/MMTab.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#import <Cocoa/Cocoa.h>

// A tab with a close button and title.

#define MMTabShadowBlurRadius (2)

typedef enum : NSUInteger {
MMTabStateSelected,
MMTabStateUnselected,
MMTabStateUnselectedHover,
} MMTabState;

@class MMTabline;

@interface MMTab : NSView

@property (nonatomic, copy) NSString *title;
@property (nonatomic, getter=isCloseButtonHidden) BOOL closeButtonHidden;
@property (nonatomic) MMTabState state;

- (instancetype)initWithFrame:(NSRect)frameRect tabline:(MMTabline *)tabline;

@end
Loading

0 comments on commit 7283c1d

Please sign in to comment.