diff --git a/Source/CandidateUI/VTCandidateController.h b/Source/CandidateUI/VTCandidateController.h index 264207e7..ebbda761 100644 --- a/Source/CandidateUI/VTCandidateController.h +++ b/Source/CandidateUI/VTCandidateController.h @@ -42,6 +42,7 @@ NSArray *_keyLabels; NSFont *_keyLabelFont; NSFont *_candidateFont; + BOOL _visible; } - (void)reloadData; diff --git a/Source/CandidateUI/VTCandidateController.m b/Source/CandidateUI/VTCandidateController.m index da5ab8d8..c7db63d9 100644 --- a/Source/CandidateUI/VTCandidateController.m +++ b/Source/CandidateUI/VTCandidateController.m @@ -81,6 +81,17 @@ - (void)setWindowTopLeftPoint:(NSPoint)topLeftPoint bottomOutOfScreenAdjustmentHeight:(CGFloat)height { + // Since layout is now deferred, the origin setting should also be deferred so that + // the correct visible frame dimensions are used. + NSArray *params = [NSArray arrayWithObjects:[NSValue valueWithPoint:topLeftPoint], [NSNumber numberWithDouble:height], nil]; + [self performSelector:@selector(deferredSetWindowTopLeftPoint:) withObject:params afterDelay:0.0]; +} + +- (void)deferredSetWindowTopLeftPoint:(NSArray *)params +{ + NSPoint topLeftPoint = [[params objectAtIndex:0] pointValue]; + CGFloat height = [[params objectAtIndex:1] doubleValue]; + NSPoint adjustedPoint = topLeftPoint; CGFloat adjustedHeight = height; @@ -132,11 +143,13 @@ - (BOOL)visible { - return [[self window] isVisible]; + // Because setVisible: defers its action, we need to use our own visible. Do not use [[self window] isVisible]. + return _visible; } - (void)setVisible:(BOOL)visible { + _visible = visible; if (visible) { [[self window] performSelector:@selector(orderFront:) withObject:self afterDelay:0.0]; } diff --git a/Source/CandidateUI/VTVerticalCandidateController.m b/Source/CandidateUI/VTVerticalCandidateController.m index 2d6a21da..2c04f5d8 100644 --- a/Source/CandidateUI/VTVerticalCandidateController.m +++ b/Source/CandidateUI/VTVerticalCandidateController.m @@ -162,18 +162,27 @@ static const CGFloat kCandidateTextLeftMargin = 8.0; return (selectedRow == -1) ? NSUIntegerMax : selectedRow; } -- (void)setSelectedCandidateIndex:(NSUInteger)newIndex +- (void)setSelectedCandidateIndex:(NSUInteger)aNewIndex { + NSUInteger newIndex = aNewIndex; + NSInteger selectedRow = [_tableView selectedRow]; NSUInteger labelCount = [_keyLabels count]; NSUInteger itemCount = [_delegate candidateCountForController:self]; - + + if (newIndex == NSUIntegerMax) { + if (itemCount == 0) { + [_tableView deselectAll:self]; + return; + } + newIndex = 0; + } + NSUInteger lastVisibleRow = newIndex; - 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) @@ -182,7 +191,7 @@ static const CGFloat kCandidateTextLeftMargin = 8.0; if (itemCount > labelCount) { [_tableView scrollRowToVisible:lastVisibleRow]; } - + [_tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:newIndex] byExtendingSelection:NO]; } @@ -237,7 +246,7 @@ static const CGFloat kCandidateTextLeftMargin = 8.0; } } - if (newHilightIndex != _keyLabelStripView.highlightedIndex) { + if (newHilightIndex != _keyLabelStripView.highlightedIndex && newHilightIndex >= 0) { _keyLabelStripView.highlightedIndex = newHilightIndex; [_keyLabelStripView setNeedsDisplay:YES]; } @@ -341,6 +350,12 @@ static const CGFloat kCandidateTextLeftMargin = 8.0; } - (void)layoutCandidateView +{ + [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(doLayoutCanaditeView) object:nil]; + [self performSelector:@selector(doLayoutCanaditeView) withObject:nil afterDelay:0.0]; +} + +- (void)doLayoutCanaditeView { NSUInteger count = [_delegate candidateCountForController:self]; if (!count) { @@ -382,9 +397,19 @@ static const CGFloat kCandidateTextLeftMargin = 8.0; CGFloat rowHeight = ceil(fontSize * 1.25); [_tableView setRowHeight:rowHeight]; - + + CGFloat maxKeyLabelWidth = keyLabelFontSize; + NSDictionary *textAttr = [NSDictionary dictionaryWithObjectsAndKeys: + _keyLabelFont, NSFontAttributeName, + nil]; + NSSize boundingBox = NSMakeSize(1600.0, 1600.0); + for (NSString *label in _keyLabels) { + NSRect rect = [label boundingRectWithSize:boundingBox options:NSStringDrawingUsesLineFragmentOrigin attributes:textAttr]; + maxKeyLabelWidth = max(rect.size.width, maxKeyLabelWidth); + } + CGFloat rowSpacing = [_tableView intercellSpacing].height; - CGFloat stripWidth = ceil(keyLabelFontSize * 1.20); + CGFloat stripWidth = ceil(maxKeyLabelWidth * 1.20); CGFloat tableViewStartWidth = ceil(_maxCandidateAttrStringWidth + scrollerWidth);; CGFloat windowWidth = stripWidth + 1.0 + tableViewStartWidth; CGFloat windowHeight = keyLabelCount * (rowHeight + rowSpacing);