Handle out-of-screen conditions. Improve drawing code.

This commit is contained in:
Lukhnos D. Liu 2012-03-29 12:16:06 -07:00
parent b492cb1f10
commit dd43b08d82
5 changed files with 78 additions and 69 deletions

View File

@ -52,6 +52,8 @@
- (BOOL)highlightNextCandidate; - (BOOL)highlightNextCandidate;
- (BOOL)highlightPreviousCandidate; - (BOOL)highlightPreviousCandidate;
- (void)setWindowTopLeftPoint:(NSPoint)topLeftPoint bottomOutOfScreenAdjustmentHeight:(CGFloat)height;
- (NSUInteger)candidateIndexAtKeyLabelIndex:(NSUInteger)index; - (NSUInteger)candidateIndexAtKeyLabelIndex:(NSUInteger)index;
@property (assign, weak, nonatomic) id<VTCandidateControllerDelegate> delegate; @property (assign, weak, nonatomic) id<VTCandidateControllerDelegate> delegate;

View File

@ -82,6 +82,52 @@
return NO; return NO;
} }
- (void)setWindowTopLeftPoint:(NSPoint)topLeftPoint bottomOutOfScreenAdjustmentHeight:(CGFloat)height
{
NSPoint adjustedPoint = topLeftPoint;
CGFloat adjustedHeight = height;
// first, locate the screen the point is in
NSRect screenFrame = [[NSScreen mainScreen] visibleFrame];
for (NSScreen *screen in [NSScreen screens]) {
NSRect frame = [screen visibleFrame];
if (topLeftPoint.x >= NSMinX(frame) && topLeftPoint.x <= NSMaxX(frame)) {
screenFrame = frame;
break;
}
}
// make sure we don't have any erratic value
if (adjustedHeight > screenFrame.size.height / 2.0) {
adjustedHeight = 0.0;
}
NSSize windowSize = [[self window] frame].size;
// bottom beneath the screen?
if (adjustedPoint.y - windowSize.height < NSMinY(screenFrame)) {
adjustedPoint.y = topLeftPoint.y + adjustedHeight + windowSize.height;
}
// top over the screen?
if (adjustedPoint.y >= NSMaxY(screenFrame)) {
adjustedPoint.y = NSMaxY(screenFrame) - 1.0;
}
// right
if (adjustedPoint.x + windowSize.width >= NSMaxX(screenFrame)) {
adjustedPoint.x = NSMaxX(screenFrame) - windowSize.width;
}
// left
if (adjustedPoint.x < NSMinX(screenFrame)) {
adjustedPoint.x = NSMinX(screenFrame);
}
[[self window] setFrameTopLeftPoint:adjustedPoint];
}
- (NSUInteger)candidateIndexAtKeyLabelIndex:(NSUInteger)index - (NSUInteger)candidateIndexAtKeyLabelIndex:(NSUInteger)index
{ {
return NSUIntegerMax; return NSUIntegerMax;
@ -108,9 +154,9 @@
return NSMakePoint(frameRect.origin.x, frameRect.origin.y + frameRect.size.height); return NSMakePoint(frameRect.origin.x, frameRect.origin.y + frameRect.size.height);
} }
- (void)setWindowTopLeftPoint:(NSPoint)windowTopLeftPoint - (void)setWindowTopLeftPoint:(NSPoint)topLeftPoint
{ {
[[self window] setFrameTopLeftPoint:windowTopLeftPoint]; [self setWindowTopLeftPoint:topLeftPoint bottomOutOfScreenAdjustmentHeight:0.0];
} }
- (NSUInteger)selectedCandidateIndex - (NSUInteger)selectedCandidateIndex

View File

@ -192,6 +192,13 @@
NSRect buttonRect = [_nextPageButton frame]; NSRect buttonRect = [_nextPageButton frame];
CGFloat spacing = 0.0; CGFloat spacing = 0.0;
if (newSize.height < 40.0) {
buttonRect.size.height = floor(newSize.height / 2);
}
else {
buttonRect.size.height = 20.0;
}
if (newSize.height >= 60.0) { if (newSize.height >= 60.0) {
spacing = ceil(newSize.height * 0.1); spacing = ceil(newSize.height * 0.1);
} }

View File

@ -27,6 +27,10 @@
#import "VTHorizontalCandidateView.h" #import "VTHorizontalCandidateView.h"
// use these instead of MIN/MAX macro to keep compilers happy with pedantic warnings on
NS_INLINE CGFloat min(CGFloat a, CGFloat b) { return a < b ? a : b; }
NS_INLINE CGFloat max(CGFloat a, CGFloat b) { return a > b ? a : b; }
@implementation VTHorizontalCandidateView @implementation VTHorizontalCandidateView
@synthesize highlightedIndex = _highlightedIndex; @synthesize highlightedIndex = _highlightedIndex;
@ -46,7 +50,7 @@
- (void)setKeyLabels:(NSArray *)labels displayedCandidates:(NSArray *)candidates - (void)setKeyLabels:(NSArray *)labels displayedCandidates:(NSArray *)candidates
{ {
NSUInteger count = MIN([labels count], [candidates count]); NSUInteger count = min([labels count], [candidates count]);
id tmp; id tmp;
tmp = _keyLabels; tmp = _keyLabels;
@ -66,7 +70,7 @@
// TODO: Handle CJK text drawing // TODO: Handle CJK text drawing
NSRect candidateRect = [[_displayedCandidates objectAtIndex:index] boundingRectWithSize:baseSize options:NSStringDrawingUsesLineFragmentOrigin attributes:_candidateAttrDict]; NSRect candidateRect = [[_displayedCandidates objectAtIndex:index] boundingRectWithSize:baseSize options:NSStringDrawingUsesLineFragmentOrigin attributes:_candidateAttrDict];
CGFloat width = MAX(labelRect.size.width, candidateRect.size.width) + _cellPadding; CGFloat width = max(labelRect.size.width, candidateRect.size.width) + _cellPadding;
[newWidths addObject:[NSNumber numberWithDouble:width]]; [newWidths addObject:[NSNumber numberWithDouble:width]];
} }
@ -107,50 +111,12 @@
CGFloat labelFontSize = [labelFont pointSize]; CGFloat labelFontSize = [labelFont pointSize];
CGFloat candidateFontSize = MAX([candidateFont pointSize], [candidateFontCJK pointSize]); CGFloat candidateFontSize = max([candidateFont pointSize], [candidateFontCJK pointSize]);
CGFloat biggestSize = MAX(labelFontSize, candidateFontSize); CGFloat biggestSize = max(labelFontSize, candidateFontSize);
_keyLabelHeight = labelFontSize; _keyLabelHeight = ceil(labelFontSize * 1.20);
_candidateTextHeight = candidateFontSize; _candidateTextHeight = ceil(candidateFontSize * 1.20);
_cellPadding = ceil(biggestSize / 2.0);
if (labelFontSize <= 16.0) {
_keyLabelHeight += 4.0;
}
else if (labelFontSize <= 24.0) {
_keyLabelHeight += 8.0;
}
else if (labelFontSize <= 64.0) {
_keyLabelHeight += 16.0;
}
else {
_keyLabelHeight += 24.0;
}
if (candidateFontSize <= 16.0) {
_candidateTextHeight += 4.0;
}
else if (candidateFontSize <= 24.0) {
_candidateTextHeight += 8.0;
}
else if (candidateFontSize <= 64.0) {
_candidateTextHeight += 16.0;
}
else {
_candidateTextHeight += 24.0;
}
if (biggestSize <= 16.0) {
_cellPadding = 8.0;
}
else if (biggestSize <= 24.0) {
_cellPadding = 16.0;
}
else if (biggestSize <= 64.0) {
_cellPadding = 24.0;
}
else {
_cellPadding = 32.0;
}
} }

View File

@ -29,6 +29,10 @@
#import "VTVerticalKeyLabelStripView.h" #import "VTVerticalKeyLabelStripView.h"
#import "VTVerticalCandidateTableView.h" #import "VTVerticalCandidateTableView.h"
// use these instead of MIN/MAX macro to keep compilers happy with pedantic warnings on
NS_INLINE CGFloat min(CGFloat a, CGFloat b) { return a < b ? a : b; }
NS_INLINE CGFloat max(CGFloat a, CGFloat b) { return a > b ? a : b; }
static const CGFloat kCandidateTextPadding = 24.0; static const CGFloat kCandidateTextPadding = 24.0;
static const CGFloat kCandidateTextLeftMargin = 8.0; static const CGFloat kCandidateTextLeftMargin = 8.0;
@ -108,7 +112,7 @@ static const CGFloat kCandidateTextLeftMargin = 8.0;
- (void)reloadData - (void)reloadData
{ {
_maxCandidateAttrStringWidth = ceil(MAX([_candidateFont pointSize], [_CJKCandidateFont pointSize])) * 2.0 + kCandidateTextPadding; _maxCandidateAttrStringWidth = ceil(max([_candidateFont pointSize], [_CJKCandidateFont pointSize])) * 2.0 + kCandidateTextPadding;
[_tableView reloadData]; [_tableView reloadData];
[self layoutCandidateView]; [self layoutCandidateView];
@ -168,7 +172,7 @@ static const CGFloat kCandidateTextLeftMargin = 8.0;
if (selectedRow != -1 && itemCount > 0 && itemCount > labelCount) { if (selectedRow != -1 && itemCount > 0 && itemCount > labelCount) {
if (newIndex > selectedRow && (newIndex - selectedRow) > 1) { if (newIndex > selectedRow && (newIndex - selectedRow) > 1) {
lastVisibleRow = MIN(newIndex + labelCount - 1, itemCount - 1); lastVisibleRow = min(newIndex + labelCount - 1, itemCount - 1);
} }
// no need to handle the backward case: (newIndex < selectedRow && selectedRow - newIndex > 1) // no need to handle the backward case: (newIndex < selectedRow && selectedRow - newIndex > 1)
@ -274,7 +278,7 @@ static const CGFloat kCandidateTextLeftMargin = 8.0;
return NO; return NO;
} }
newIndex = MIN(newIndex + labelCount, itemCount - 1); newIndex = min(newIndex + labelCount, itemCount - 1);
} }
else { else {
if (newIndex == 0) { if (newIndex == 0) {
@ -329,9 +333,9 @@ static const CGFloat kCandidateTextLeftMargin = 8.0;
return; return;
} }
CGFloat candidateFontSize = ceil(MAX([_candidateFont pointSize], [_CJKCandidateFont pointSize])); CGFloat candidateFontSize = ceil(max([_candidateFont pointSize], [_CJKCandidateFont pointSize]));
CGFloat keyLabelFontSize = ceil([_keyLabelFont pointSize]); CGFloat keyLabelFontSize = ceil([_keyLabelFont pointSize]);
CGFloat fontSize = MAX(candidateFontSize, keyLabelFontSize); CGFloat fontSize = max(candidateFontSize, keyLabelFontSize);
NSControlSize controlSize = (fontSize > 36.0) ? NSRegularControlSize : NSSmallControlSize; NSControlSize controlSize = (fontSize > 36.0) ? NSRegularControlSize : NSSmallControlSize;
@ -362,24 +366,9 @@ static const CGFloat kCandidateTextLeftMargin = 8.0;
_keyLabelStripView.keyLabels = [_keyLabels subarrayWithRange:NSMakeRange(0, keyLabelCount)]; _keyLabelStripView.keyLabels = [_keyLabels subarrayWithRange:NSMakeRange(0, keyLabelCount)];
_keyLabelStripView.labelOffsetY = (keyLabelFontSize >= candidateFontSize) ? 0.0 : floor((candidateFontSize - keyLabelFontSize) / 2.0); _keyLabelStripView.labelOffsetY = (keyLabelFontSize >= candidateFontSize) ? 0.0 : floor((candidateFontSize - keyLabelFontSize) / 2.0);
CGFloat rowHeight = fontSize; CGFloat rowHeight = ceil(fontSize * 1.20);
if (fontSize <= 16.0) {
rowHeight += 4.0;
}
else if (fontSize <= 24.0) {
rowHeight += 8.0;
}
else if (fontSize <= 64.0) {
rowHeight += 16.0;
}
else {
rowHeight += 24.0;
}
[_tableView setRowHeight:rowHeight]; [_tableView setRowHeight:rowHeight];
CGFloat rowSpacing = [_tableView intercellSpacing].height; CGFloat rowSpacing = [_tableView intercellSpacing].height;
CGFloat stripWidth = ceil(keyLabelFontSize * 1.20); CGFloat stripWidth = ceil(keyLabelFontSize * 1.20);
CGFloat tableViewStartWidth = ceil(_maxCandidateAttrStringWidth + scrollerWidth);; CGFloat tableViewStartWidth = ceil(_maxCandidateAttrStringWidth + scrollerWidth);;
@ -387,7 +376,6 @@ static const CGFloat kCandidateTextLeftMargin = 8.0;
CGFloat windowHeight = keyLabelCount * (rowHeight + rowSpacing); CGFloat windowHeight = keyLabelCount * (rowHeight + rowSpacing);
NSRect frameRect = [[self window] frame]; NSRect frameRect = [[self window] frame];
frameRect = [[self window] frame];
NSPoint topLeftPoint = NSMakePoint(frameRect.origin.x, frameRect.origin.y + frameRect.size.height); NSPoint topLeftPoint = NSMakePoint(frameRect.origin.x, frameRect.origin.y + frameRect.size.height);
frameRect.size = NSMakeSize(windowWidth, windowHeight); frameRect.size = NSMakeSize(windowWidth, windowHeight);