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)highlightPreviousCandidate;
- (void)setWindowTopLeftPoint:(NSPoint)topLeftPoint bottomOutOfScreenAdjustmentHeight:(CGFloat)height;
- (NSUInteger)candidateIndexAtKeyLabelIndex:(NSUInteger)index;
@property (assign, weak, nonatomic) id<VTCandidateControllerDelegate> delegate;

View File

@ -82,6 +82,52 @@
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
{
return NSUIntegerMax;
@ -108,9 +154,9 @@
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

View File

@ -192,6 +192,13 @@
NSRect buttonRect = [_nextPageButton frame];
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) {
spacing = ceil(newSize.height * 0.1);
}

View File

@ -27,6 +27,10 @@
#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
@synthesize highlightedIndex = _highlightedIndex;
@ -46,7 +50,7 @@
- (void)setKeyLabels:(NSArray *)labels displayedCandidates:(NSArray *)candidates
{
NSUInteger count = MIN([labels count], [candidates count]);
NSUInteger count = min([labels count], [candidates count]);
id tmp;
tmp = _keyLabels;
@ -66,7 +70,7 @@
// TODO: Handle CJK text drawing
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]];
}
@ -107,50 +111,12 @@
CGFloat labelFontSize = [labelFont pointSize];
CGFloat candidateFontSize = MAX([candidateFont pointSize], [candidateFontCJK pointSize]);
CGFloat biggestSize = MAX(labelFontSize, candidateFontSize);
CGFloat candidateFontSize = max([candidateFont pointSize], [candidateFontCJK pointSize]);
CGFloat biggestSize = max(labelFontSize, candidateFontSize);
_keyLabelHeight = labelFontSize;
_candidateTextHeight = candidateFontSize;
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;
}
_keyLabelHeight = ceil(labelFontSize * 1.20);
_candidateTextHeight = ceil(candidateFontSize * 1.20);
_cellPadding = ceil(biggestSize / 2.0);
}

View File

@ -29,6 +29,10 @@
#import "VTVerticalKeyLabelStripView.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 kCandidateTextLeftMargin = 8.0;
@ -108,7 +112,7 @@ static const CGFloat kCandidateTextLeftMargin = 8.0;
- (void)reloadData
{
_maxCandidateAttrStringWidth = ceil(MAX([_candidateFont pointSize], [_CJKCandidateFont pointSize])) * 2.0 + kCandidateTextPadding;
_maxCandidateAttrStringWidth = ceil(max([_candidateFont pointSize], [_CJKCandidateFont pointSize])) * 2.0 + kCandidateTextPadding;
[_tableView reloadData];
[self layoutCandidateView];
@ -168,7 +172,7 @@ static const CGFloat kCandidateTextLeftMargin = 8.0;
if (selectedRow != -1 && itemCount > 0 && itemCount > labelCount) {
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)
@ -274,7 +278,7 @@ static const CGFloat kCandidateTextLeftMargin = 8.0;
return NO;
}
newIndex = MIN(newIndex + labelCount, itemCount - 1);
newIndex = min(newIndex + labelCount, itemCount - 1);
}
else {
if (newIndex == 0) {
@ -329,9 +333,9 @@ static const CGFloat kCandidateTextLeftMargin = 8.0;
return;
}
CGFloat candidateFontSize = ceil(MAX([_candidateFont pointSize], [_CJKCandidateFont pointSize]));
CGFloat candidateFontSize = ceil(max([_candidateFont pointSize], [_CJKCandidateFont pointSize]));
CGFloat keyLabelFontSize = ceil([_keyLabelFont pointSize]);
CGFloat fontSize = MAX(candidateFontSize, keyLabelFontSize);
CGFloat fontSize = max(candidateFontSize, keyLabelFontSize);
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.labelOffsetY = (keyLabelFontSize >= candidateFontSize) ? 0.0 : floor((candidateFontSize - keyLabelFontSize) / 2.0);
CGFloat rowHeight = fontSize;
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;
}
CGFloat rowHeight = ceil(fontSize * 1.20);
[_tableView setRowHeight:rowHeight];
CGFloat rowSpacing = [_tableView intercellSpacing].height;
CGFloat stripWidth = ceil(keyLabelFontSize * 1.20);
CGFloat tableViewStartWidth = ceil(_maxCandidateAttrStringWidth + scrollerWidth);;
@ -387,7 +376,6 @@ static const CGFloat kCandidateTextLeftMargin = 8.0;
CGFloat windowHeight = keyLabelCount * (rowHeight + rowSpacing);
NSRect frameRect = [[self window] frame];
frameRect = [[self window] frame];
NSPoint topLeftPoint = NSMakePoint(frameRect.origin.x, frameRect.origin.y + frameRect.size.height);
frameRect.size = NSMakeSize(windowWidth, windowHeight);