2016-10-26 21:14:02 +00:00
|
|
|
#import "GBImageView.h"
|
|
|
|
|
|
|
|
@implementation GBImageViewGridConfiguration
|
|
|
|
- (instancetype)initWithColor:(NSColor *)color size:(NSUInteger)size
|
|
|
|
{
|
|
|
|
self = [super init];
|
|
|
|
self.color = color;
|
|
|
|
self.size = size;
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
@end
|
|
|
|
|
2022-02-19 20:13:07 +00:00
|
|
|
@interface GBGridView : NSView
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation GBGridView
|
|
|
|
|
2016-10-26 21:14:02 +00:00
|
|
|
- (void)drawRect:(NSRect)dirtyRect
|
|
|
|
{
|
2022-02-19 20:13:07 +00:00
|
|
|
GBImageView *parent = (GBImageView *)self.superview;
|
|
|
|
|
|
|
|
CGFloat y_ratio = parent.frame.size.height / parent.image.size.height;
|
|
|
|
CGFloat x_ratio = parent.frame.size.width / parent.image.size.width;
|
|
|
|
for (GBImageViewGridConfiguration *conf in parent.verticalGrids) {
|
2016-10-26 21:14:02 +00:00
|
|
|
[conf.color set];
|
|
|
|
for (CGFloat y = conf.size * y_ratio; y < self.frame.size.height; y += conf.size * y_ratio) {
|
|
|
|
NSBezierPath *line = [NSBezierPath bezierPath];
|
2019-06-07 20:38:34 +00:00
|
|
|
[line moveToPoint:NSMakePoint(0, y - 0.5)];
|
|
|
|
[line lineToPoint:NSMakePoint(self.frame.size.width, y - 0.5)];
|
2016-10-26 21:14:02 +00:00
|
|
|
[line setLineWidth:1.0];
|
|
|
|
[line stroke];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-19 20:13:07 +00:00
|
|
|
for (GBImageViewGridConfiguration *conf in parent.horizontalGrids) {
|
2016-10-26 21:14:02 +00:00
|
|
|
[conf.color set];
|
|
|
|
for (CGFloat x = conf.size * x_ratio; x < self.frame.size.width; x += conf.size * x_ratio) {
|
|
|
|
NSBezierPath *line = [NSBezierPath bezierPath];
|
|
|
|
[line moveToPoint:NSMakePoint(x + 0.5, 0)];
|
|
|
|
[line lineToPoint:NSMakePoint(x + 0.5, self.frame.size.height)];
|
|
|
|
[line setLineWidth:1.0];
|
|
|
|
[line stroke];
|
|
|
|
}
|
|
|
|
}
|
2019-06-07 20:38:34 +00:00
|
|
|
|
2022-02-19 20:13:07 +00:00
|
|
|
if (parent.displayScrollRect) {
|
2019-06-07 20:38:34 +00:00
|
|
|
NSBezierPath *path = [NSBezierPath bezierPathWithRect:CGRectInfinite];
|
|
|
|
for (unsigned x = 0; x < 2; x++) {
|
|
|
|
for (unsigned y = 0; y < 2; y++) {
|
2022-02-19 20:13:07 +00:00
|
|
|
NSRect rect = parent.scrollRect;
|
2019-06-07 20:38:34 +00:00
|
|
|
rect.origin.x *= x_ratio;
|
|
|
|
rect.origin.y *= y_ratio;
|
|
|
|
rect.size.width *= x_ratio;
|
|
|
|
rect.size.height *= y_ratio;
|
|
|
|
rect.origin.y = self.frame.size.height - rect.origin.y - rect.size.height;
|
|
|
|
|
|
|
|
rect.origin.x -= self.frame.size.width * x;
|
|
|
|
rect.origin.y += self.frame.size.height * y;
|
2022-02-19 20:13:07 +00:00
|
|
|
|
2019-06-07 20:38:34 +00:00
|
|
|
|
|
|
|
NSBezierPath *subpath = [NSBezierPath bezierPathWithRect:rect];
|
|
|
|
[path appendBezierPath:subpath];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
[path setWindingRule:NSEvenOddWindingRule];
|
|
|
|
[path setLineWidth:4.0];
|
|
|
|
[path setLineJoinStyle:NSRoundLineJoinStyle];
|
|
|
|
[[NSColor colorWithWhite:0.2 alpha:0.5] set];
|
|
|
|
[path fill];
|
|
|
|
[path addClip];
|
|
|
|
[[NSColor colorWithWhite:0.0 alpha:0.6] set];
|
|
|
|
[path stroke];
|
|
|
|
}
|
2016-10-26 21:14:02 +00:00
|
|
|
}
|
2022-02-19 20:13:07 +00:00
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation GBImageView
|
|
|
|
{
|
|
|
|
NSTrackingArea *_trackingArea;
|
|
|
|
GBGridView *_gridView;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (instancetype)initWithCoder:(NSCoder *)coder
|
|
|
|
{
|
|
|
|
self = [super initWithCoder:coder];
|
|
|
|
self.wantsLayer = true;
|
|
|
|
_gridView = [[GBGridView alloc] initWithFrame:self.bounds];
|
|
|
|
_gridView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
|
|
|
|
[self addSubview:_gridView];
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setImage:(NSImage *)image
|
|
|
|
{
|
|
|
|
[super setImage:image];
|
|
|
|
for (CALayer *layer in self.layer.sublayers) {
|
|
|
|
layer.magnificationFilter = kCAFilterNearest;
|
|
|
|
}
|
|
|
|
}
|
2016-10-26 21:14:02 +00:00
|
|
|
|
|
|
|
- (void)setHorizontalGrids:(NSArray *)horizontalGrids
|
|
|
|
{
|
|
|
|
self->_horizontalGrids = horizontalGrids;
|
2022-02-19 20:13:07 +00:00
|
|
|
[_gridView setNeedsDisplay:true];
|
2016-10-26 21:14:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setVerticalGrids:(NSArray *)verticalGrids
|
|
|
|
{
|
|
|
|
self->_verticalGrids = verticalGrids;
|
2022-02-19 20:13:07 +00:00
|
|
|
[_gridView setNeedsDisplay:true];
|
2016-10-26 21:14:02 +00:00
|
|
|
}
|
|
|
|
|
2019-06-07 20:38:34 +00:00
|
|
|
- (void)setDisplayScrollRect:(bool)displayScrollRect
|
|
|
|
{
|
|
|
|
self->_displayScrollRect = displayScrollRect;
|
2022-02-19 20:13:07 +00:00
|
|
|
[_gridView setNeedsDisplay:true];
|
2019-06-07 20:38:34 +00:00
|
|
|
}
|
|
|
|
|
2016-10-26 21:14:02 +00:00
|
|
|
- (void)updateTrackingAreas
|
|
|
|
{
|
2022-02-19 20:13:07 +00:00
|
|
|
if (_trackingArea != nil) {
|
|
|
|
[self removeTrackingArea:_trackingArea];
|
2016-10-26 21:14:02 +00:00
|
|
|
}
|
|
|
|
|
2022-02-19 20:13:07 +00:00
|
|
|
_trackingArea = [ [NSTrackingArea alloc] initWithRect:[self bounds]
|
2016-10-26 21:14:02 +00:00
|
|
|
options:NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways | NSTrackingMouseMoved
|
|
|
|
owner:self
|
|
|
|
userInfo:nil];
|
2022-02-19 20:13:07 +00:00
|
|
|
[self addTrackingArea:_trackingArea];
|
2016-10-26 21:14:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)mouseExited:(NSEvent *)theEvent
|
|
|
|
{
|
|
|
|
if ([self.delegate respondsToSelector:@selector(mouseDidLeaveImageView:)]) {
|
|
|
|
[self.delegate mouseDidLeaveImageView:self];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)mouseMoved:(NSEvent *)theEvent
|
|
|
|
{
|
|
|
|
if ([self.delegate respondsToSelector:@selector(imageView:mouseMovedToX:Y:)]) {
|
|
|
|
NSPoint location = [self convertPoint:theEvent.locationInWindow fromView:nil];
|
|
|
|
location.x /= self.bounds.size.width;
|
|
|
|
location.y /= self.bounds.size.height;
|
|
|
|
location.y = 1 - location.y;
|
|
|
|
location.x *= self.image.size.width;
|
|
|
|
location.y *= self.image.size.height;
|
|
|
|
[self.delegate imageView:self mouseMovedToX:(NSUInteger)location.x Y:(NSUInteger)location.y];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|