Commit ae660fdf authored by Kateryna Kostiuk's avatar Kateryna Kostiuk

UI/UX: refactor messages view

Change-Id: I2292ddf0d958aadc8171a86f12450ec56af0f6fc
Reviewed-by: Andreas Traczyk's avatarAndreas Traczyk <andreas.traczyk@savoirfairelinux.com>
parent 55b6a31a
......@@ -265,6 +265,7 @@ SET(ringclient_XIBS
ContactRequest
AccBannedContacts
PasswordChange
MessageCells
)
# Icons
......@@ -274,6 +275,7 @@ SET_SOURCE_FILES_PROPERTIES(${myApp_ICON} PROPERTIES
MACOSX_PACKAGE_LOCATION Resources)
SET(ring_ICONS
${CMAKE_CURRENT_SOURCE_DIR}/data/dark/ic_attachment.png
${CMAKE_CURRENT_SOURCE_DIR}/data/default_avatar_overlay.png
${CMAKE_CURRENT_SOURCE_DIR}/data/symbol_name.png
${CMAKE_CURRENT_SOURCE_DIR}/data/background-light.png
......
......@@ -69,7 +69,6 @@
convModel_->sendMessage(convUid_, std::string([text UTF8String]));
self.message = @"";
[messageField setStringValue:@""];
[messagesViewVC newMessageSent];
}
}
......
......@@ -96,7 +96,7 @@
if (cachedConv_ != nil)
return cachedConv_;
auto& convQueue = convModel_->allFilteredConversations();
auto convQueue = convModel_->allFilteredConversations();
auto it = getConversationFromUid(convUid_, *convModel_);
......@@ -202,7 +202,6 @@
self.message = @"";
if (isPending)
[delegate currentConversationTrusted];
[messagesViewVC newMessageSent];
}
}
......
......@@ -30,7 +30,6 @@
@interface MessagesVC : NSViewController
-(void)setConversationUid:(const std::string)convUid model:(lrc::api::ConversationModel*)model;
-(void)newMessageSent;
@property (retain, nonatomic) id <MessagesVCDelegate> delegate;
......
This diff is collapsed.
......@@ -30,10 +30,19 @@
@property (nonatomic, strong) IBOutlet NSButton* declineButton;
@property (nonatomic, strong) IBOutlet NSProgressIndicator* progressIndicator;
@property (nonatomic, strong) IBOutlet NSTextField* statusLabel;
@property (nonatomic, strong) IBOutlet NSBox* timeBox;
@property (nonatomic, strong) IBOutlet NSTextField* timeLabel;
@property (nonatomic, strong) IBOutlet NSTextField* transferedFileName;
@property (nonatomic, strong) IBOutlet NSImageView* transferedImage;
@property (nonatomic, strong) IBOutlet NSProgressIndicator* sendingMessageIndicator;
@property (nonatomic, strong) IBOutlet NSTextField* messageFailed;
@property (nonatomic, strong) IBOutlet NSView* messageStatus;
- (uint64_t) interaction;
- (void) setupForInteraction:(uint64_t)inter;
- (void) updateWidthConstraint:(CGFloat) newWidth;
- (void) updateMessageConstraint:(CGFloat) width andHeight: (CGFloat) height timeIsVisible: (bool) visible;
- (void) updateImageConstraint: (CGFloat) width andHeight: (CGFloat) height;
- (void) invalidateImageConstraints;
@end
......@@ -25,7 +25,10 @@
uint64_t interaction;
}
@synthesize msgView;
NSString* const MESSAGE_MARGIN = @"10";
NSString* const TIME_BOX_HEIGHT = @"34";
@synthesize msgView, msgBackground, timeBox, transferedImage;
@synthesize photoView;
@synthesize acceptButton;
@synthesize declineButton;
......@@ -50,34 +53,74 @@
[self setupDirection];
[self.msgView setBackgroundColor:[NSColor clearColor]];
[self.msgView setString:@""];
[self.msgView setAutoresizingMask:NSViewWidthSizable];
[self.msgView setAutoresizingMask:NSViewHeightSizable];
[self.msgBackground setAutoresizingMask:NSViewWidthSizable];
[self.msgBackground setAutoresizingMask:NSViewHeightSizable];
[self.msgView setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.msgBackground setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.msgView setEnabledTextCheckingTypes:NSTextCheckingTypeLink];
[self.msgView setAutomaticLinkDetectionEnabled:YES];
[self.msgView setEditable:NO];
if ([self.identifier containsString:@"Message"]) {
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-5-[msgView]"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(msgView)]];
}
}
- (void) updateWidthConstraint:(CGFloat) newWidth
- (void) updateMessageConstraint:(CGFloat) width andHeight: (CGFloat) height timeIsVisible: (bool) visible
{
[self.msgView removeConstraints:[self.msgView constraints]];
NSLayoutConstraint* constraint = [NSLayoutConstraint
constraintWithItem:self.msgView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem: nil
attribute:NSLayoutAttributeWidth
multiplier:1.0f
constant:newWidth];
[NSLayoutConstraint deactivateConstraints:[self.msgView constraints]];
[NSLayoutConstraint deactivateConstraints:[self.timeBox constraints]];
NSString* formatWidth = [NSString stringWithFormat:@"H:|-%@-[msgView(==%@)]-%@-|",
MESSAGE_MARGIN,[NSString stringWithFormat:@"%f", width],
MESSAGE_MARGIN];
NSString* formatHeight = [NSString stringWithFormat:@"V:[msgView(==%@)]",
[NSString stringWithFormat:@"%f", height]];
NSArray* constraintsMessageHorizontal = [NSLayoutConstraint
constraintsWithVisualFormat:formatWidth
options:NSLayoutFormatAlignAllCenterY
metrics:nil views:NSDictionaryOfVariableBindings(msgView)];
NSArray* constraintsMessageVertical = [NSLayoutConstraint
constraintsWithVisualFormat:formatHeight
options:0
metrics:nil views:NSDictionaryOfVariableBindings(msgView)];
NSLayoutConstraint* centerMessageConstraint =[NSLayoutConstraint constraintWithItem:msgView
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:msgView.superview
attribute:NSLayoutAttributeCenterY
multiplier:1.f constant:0.f];
NSString* formatTime = [NSString stringWithFormat:@"V:[timeBox(%@)]", TIME_BOX_HEIGHT];
[self.timeBox setHidden:NO];
if (!visible) {
formatTime = [NSString stringWithFormat:@"V:[timeBox(1)]"];
[self.timeBox setHidden:YES];
}
NSArray* constraintsVerticalTimeBox = [NSLayoutConstraint
constraintsWithVisualFormat:formatTime
options:0
metrics:nil views:NSDictionaryOfVariableBindings(timeBox)];
NSArray* constraints = [[[constraintsMessageHorizontal arrayByAddingObjectsFromArray:constraintsMessageVertical]
arrayByAddingObject:centerMessageConstraint] arrayByAddingObjectsFromArray:constraintsVerticalTimeBox];
[NSLayoutConstraint activateConstraints:constraints];
}
- (void) updateImageConstraint: (CGFloat) width andHeight: (CGFloat) height {
[NSLayoutConstraint deactivateConstraints:[self.transferedImage constraints]];
[self.msgBackground setHidden:YES];
NSString* formatHeight = [NSString stringWithFormat:@"V:[transferedImage(==%@)]",[NSString stringWithFormat:@"%f", height]];
NSString* formatWidth = [NSString stringWithFormat:
@"H:[transferedImage(==%@)]",[NSString stringWithFormat:@"%f", width]];
NSArray* constraintsHorizontal = [NSLayoutConstraint
constraintsWithVisualFormat:formatWidth
options:0
metrics:nil views:NSDictionaryOfVariableBindings(transferedImage)];
NSArray* constraintsVertical = [NSLayoutConstraint
constraintsWithVisualFormat:formatHeight
options:0
metrics:nil views:NSDictionaryOfVariableBindings(transferedImage)];
NSArray* constraints =[constraintsHorizontal arrayByAddingObjectsFromArray:constraintsVertical] ;
[NSLayoutConstraint activateConstraints:constraintsHorizontal];
}
[self.msgView addConstraint:constraint];
- (void) invalidateImageConstraints {
[NSLayoutConstraint deactivateConstraints:[self.transferedImage constraints]];
}
- (uint64_t)interaction
......
......@@ -24,11 +24,23 @@ typedef NS_ENUM(NSInteger, PointerDirection) {
RIGHT,
BLOCK,
};
typedef NS_ENUM(NSInteger, BubbleType) {
SINGLE = 0,
FIRST = 1,
MIDDLE = 2,
LAST = 3,
};
@interface MessageBubbleView: NSView
/*
* Background color of the bubble
*/
@property NSColor* bgColor;
@property Boolean needPointer;
@property BubbleType type;
@property enum PointerDirection pointerDirection;
/*
* Radius value for rounded corner. Default is 12
*/
@property CGFloat cornerRadius;
@end
......@@ -28,46 +28,83 @@
[super drawRect:dirtyRect];
CGContextRef context = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
CGContextSetRGBFillColor(context, 1, 1, 1, 1);
CGFloat radius = 6;
CGFloat minx = CGRectGetMinX(dirtyRect), midx = CGRectGetMidX(dirtyRect), maxx = CGRectGetMaxX(dirtyRect);
CGFloat miny = CGRectGetMinY(dirtyRect), midy = CGRectGetMidY(dirtyRect), maxy = CGRectGetMaxY(dirtyRect);
CGFloat defaultRadius = 16;
CGFloat radius = (self.cornerRadius) ? self.cornerRadius : defaultRadius;
CGFloat minx = CGRectGetMinX(dirtyRect);
CGFloat midx = CGRectGetMidX(dirtyRect);
CGFloat maxx = CGRectGetMaxX(dirtyRect);
CGFloat miny = CGRectGetMinY(dirtyRect);
CGFloat midy = CGRectGetMidY(dirtyRect);
CGFloat maxy = CGRectGetMaxY(dirtyRect);
CGMutablePathRef outlinePath = CGPathCreateMutable();
if (self.pointerDirection == LEFT)
{
minx += 6;
CGPathMoveToPoint(outlinePath, nil, midx, miny);
CGPathAddArcToPoint(outlinePath, nil, maxx, miny, maxx, midy, radius);
CGPathAddArcToPoint(outlinePath, nil, maxx, maxy, midx, maxy, radius);
CGPathAddArcToPoint(outlinePath, nil, minx, maxy, minx, midy, radius);
if(self.needPointer) {
CGPathAddLineToPoint(outlinePath, nil, minx, maxy - 20);
CGPathAddLineToPoint(outlinePath, nil, minx - 6, maxy - 15);
CGPathAddLineToPoint(outlinePath, nil, minx, maxy - 10);
switch (self.type) {
case SINGLE:
CGPathMoveToPoint(outlinePath, nil, midx, miny);
CGPathAddArcToPoint(outlinePath, nil, maxx, miny, maxx, midy, radius);
CGPathAddArcToPoint(outlinePath, nil, maxx, maxy, midx, maxy, radius);
CGPathAddArcToPoint(outlinePath, nil, minx, maxy, minx, midy, radius);
CGPathAddArcToPoint(outlinePath, nil, minx, miny, midx, miny, radius);
break;
case FIRST:
CGPathMoveToPoint(outlinePath, nil, midx, miny);
CGPathAddArcToPoint(outlinePath, nil, maxx, miny, maxx, midy, radius);
CGPathAddArcToPoint(outlinePath, nil, maxx, maxy, midx, maxy, radius);
CGPathAddArcToPoint(outlinePath, nil, minx, maxy, minx, midy, radius);
CGPathAddArcToPoint(outlinePath, nil, minx, miny, midx, miny, 0);
break;
case MIDDLE:
CGPathMoveToPoint(outlinePath, nil, midx, miny);
CGPathAddArcToPoint(outlinePath, nil, maxx, miny, maxx, midy, radius);
CGPathAddArcToPoint(outlinePath, nil, maxx, maxy, midx, maxy, radius);
CGPathAddArcToPoint(outlinePath, nil, minx, maxy, minx, midy, 0);
CGPathAddArcToPoint(outlinePath, nil, minx, miny, midx, miny, 0);
break;
case LAST:
CGPathMoveToPoint(outlinePath, nil, midx, miny);
CGPathAddArcToPoint(outlinePath, nil, maxx, miny, maxx, midy, radius);
CGPathAddArcToPoint(outlinePath, nil, maxx, maxy, midx, maxy, radius);
CGPathAddArcToPoint(outlinePath, nil, minx, maxy, minx, midy, 0);
CGPathAddArcToPoint(outlinePath, nil, minx, miny, midx, miny, radius);
break;
}
CGPathAddArcToPoint(outlinePath, nil, minx, miny, midx, miny, radius);
CGPathCloseSubpath(outlinePath);
}
else
{
maxx-=6;
CGPathMoveToPoint(outlinePath, nil, midx, miny);
CGPathAddArcToPoint(outlinePath, nil, minx, miny, minx, midy, radius);
CGPathAddArcToPoint(outlinePath, nil, minx, maxy, midx, maxy, radius);
CGPathAddArcToPoint(outlinePath, nil, maxx, maxy, maxx, midy, radius);
if(self.needPointer) {
CGPathAddLineToPoint(outlinePath, nil, maxx, maxy - 20);
CGPathAddLineToPoint(outlinePath, nil, maxx + 6, maxy - 15);
CGPathAddLineToPoint(outlinePath, nil, maxx, maxy - 10);
} else {
switch (self.type) {
case SINGLE:
CGPathMoveToPoint(outlinePath, nil, midx, miny);
CGPathAddArcToPoint(outlinePath, nil, maxx, miny, maxx, midy, radius);
CGPathAddArcToPoint(outlinePath, nil, maxx, maxy, midx, maxy, radius);
CGPathAddArcToPoint(outlinePath, nil, minx, maxy, minx, midy, radius);
CGPathAddArcToPoint(outlinePath, nil, minx, miny, midx, miny, radius);
break;
case FIRST:
CGPathMoveToPoint(outlinePath, nil, midx, miny);
CGPathAddArcToPoint(outlinePath, nil, maxx, miny, maxx, midy, 0);
CGPathAddArcToPoint(outlinePath, nil, maxx, maxy, midx, maxy, radius);
CGPathAddArcToPoint(outlinePath, nil, minx, maxy, minx, midy, radius);
CGPathAddArcToPoint(outlinePath, nil, minx, miny, midx, miny, radius);
break;
case MIDDLE:
CGPathMoveToPoint(outlinePath, nil, midx, miny);
CGPathAddArcToPoint(outlinePath, nil, maxx, miny, maxx, midy, 0);
CGPathAddArcToPoint(outlinePath, nil, maxx, maxy, midx, maxy, 0);
CGPathAddArcToPoint(outlinePath, nil, minx, maxy, minx, midy, radius);
CGPathAddArcToPoint(outlinePath, nil, minx, miny, midx, miny, radius);
break;
case LAST:
CGPathMoveToPoint(outlinePath, nil, midx, miny);
CGPathAddArcToPoint(outlinePath, nil, maxx, miny, maxx, midy, radius);
CGPathAddArcToPoint(outlinePath, nil, maxx, maxy, midx, maxy, 0);
CGPathAddArcToPoint(outlinePath, nil, minx, maxy, minx, midy, radius);
CGPathAddArcToPoint(outlinePath, nil, minx, miny, midx, miny, radius);
break;
}
CGPathAddArcToPoint(outlinePath, nil, maxx, miny, midx, miny, radius);
CGPathCloseSubpath(outlinePath);
}
CGPathCloseSubpath(outlinePath);
CGContextAddPath(context, outlinePath);
CGContextFillPath(context);
CGContextAddPath(context, outlinePath);
CGContextClip(context);
if(self.bgColor) {
......@@ -76,4 +113,5 @@
NSRectFill(dirtyRect);
}
}
@end
......@@ -29,4 +29,8 @@
+ (NSImage *)imageResize:(NSImage*)anImage
newSize:(NSSize)newSize;
- (NSImage *) roundCorners:(CGFloat)radius;
- (NSImage *) imageResizeInsideMax:(CGFloat) dimension;
@end
......@@ -40,4 +40,38 @@
return nil;
}
- (NSImage *) roundCorners:(CGFloat)radius {
NSImage *existingImage = self;
NSSize existingSize = [existingImage size];
NSSize newSize = NSMakeSize(existingSize.width, existingSize.height);
NSImage *composedImage = [[NSImage alloc] initWithSize:newSize];
[composedImage lockFocus];
[[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
NSRect imageFrame = NSRectFromCGRect(CGRectMake(0, 0, existingSize.width, existingSize.height));
NSBezierPath *clipPath = [NSBezierPath bezierPathWithRoundedRect:imageFrame xRadius:radius yRadius:radius];
[clipPath setWindingRule:NSEvenOddWindingRule];
[clipPath addClip];
[existingImage drawAtPoint:NSZeroPoint fromRect:NSMakeRect(0, 0, newSize.width, newSize.height) operation:NSCompositeSourceOver fraction:1];
[composedImage unlockFocus];
return composedImage;
}
- (NSImage*) imageResizeInsideMax:(CGFloat) dimension {
if (self.size.width < dimension && self.size.height < dimension) {
return self;
}
CGFloat widthScaleFactor = dimension / self.size.width;
CGFloat heightScaleFactor = dimension / self.size.height;
CGFloat scale = MIN(widthScaleFactor, heightScaleFactor);
NSSize size = NSZeroSize;
size.width = self.size.width * scale;
size.height = self.size.height * scale;
return [NSImage imageResize:self newSize:size];
}
@end
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment