Handle out-of-screen conditions. Improve drawing code.
This commit is contained in:
parent
b492cb1f10
commit
dd43b08d82
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue