From 73fdad898f8574f2e83712e12b6b0e1c717ad0c7 Mon Sep 17 00:00:00 2001 From: LEO Yoon-Tsaw Date: Sun, 28 Apr 2024 11:09:47 -0400 Subject: [PATCH] Enable moving caret position by mouse click --- SquirrelConfig.m | 16 ++++++------- SquirrelInputController.h | 1 + SquirrelInputController.m | 18 +++++++++++++++ SquirrelPanel.m | 48 ++++++++++++++++++++++++++++----------- 4 files changed, 62 insertions(+), 21 deletions(-) diff --git a/SquirrelConfig.m b/SquirrelConfig.m index 7d26d75c1..ecd0ffe37 100644 --- a/SquirrelConfig.m +++ b/SquirrelConfig.m @@ -189,15 +189,15 @@ - (NSColor*)colorFromString:(NSString*)string { sscanf(string.UTF8String, "0x%02x%02x%02x", &b, &g, &r); } if ([self.colorSpace isEqualToString:@"display_p3"]) { - return [NSColor colorWithDisplayP3Red:r / 255.0 - green:g / 255.0 - blue:b / 255.0 - alpha:a / 255.0]; + return [NSColor colorWithDisplayP3Red:(CGFloat)r / 255. + green:(CGFloat)g / 255. + blue:(CGFloat)b / 255. + alpha:(CGFloat)a / 255.]; } else { // sRGB by default - return [NSColor colorWithSRGBRed:r / 255.0 - green:g / 255.0 - blue:b / 255.0 - alpha:a / 255.0]; + return [NSColor colorWithSRGBRed:(CGFloat)r / 255. + green:(CGFloat)g / 255. + blue:(CGFloat)b / 255. + alpha:(CGFloat)a / 255.]; } } diff --git a/SquirrelInputController.h b/SquirrelInputController.h index 5e718b325..cea5029de 100644 --- a/SquirrelInputController.h +++ b/SquirrelInputController.h @@ -3,5 +3,6 @@ @interface SquirrelInputController : IMKInputController - (BOOL)selectCandidate:(NSInteger)index; +- (BOOL)moveCaret:(BOOL)forward; - (BOOL)pageUp:(BOOL)up; @end diff --git a/SquirrelInputController.m b/SquirrelInputController.m index 285e60c20..b93c41ceb 100644 --- a/SquirrelInputController.m +++ b/SquirrelInputController.m @@ -253,6 +253,24 @@ - (BOOL)pageUp:(BOOL)up { return handled; } +- (BOOL)moveCaret:(BOOL)forward { + size_t current_caret_pos = rime_get_api()->get_caret_pos(_session); + const char* input = rime_get_api()->get_input(_session); + if (forward) { + if (current_caret_pos <= 0) { + return NO; + } + rime_get_api()->set_caret_pos(_session, current_caret_pos - 1); + } else { + if (current_caret_pos >= strlen(input)) { + return NO; + } + rime_get_api()->set_caret_pos(_session, current_caret_pos + 1); + } + [self rimeUpdate]; + return YES; +} + - (void)onChordTimer:(NSTimer*)timer { // chord release triggered by timer int processed_keys = 0; diff --git a/SquirrelPanel.m b/SquirrelPanel.m index 37f056797..1fd79a2a2 100644 --- a/SquirrelPanel.m +++ b/SquirrelPanel.m @@ -829,6 +829,10 @@ - (void)drawRect:(NSRect)dirtyRect { CGPathRef preeditPath = CGPathCreateMutable(); SquirrelTheme* theme = self.currentTheme; + NSPoint textFieldOrigin = dirtyRect.origin; + textFieldOrigin.y += theme.edgeInset.height; + textFieldOrigin.x += theme.edgeInset.width; + // Draw preedit Rect NSRect backgroundRect = dirtyRect; NSRect containingRect = dirtyRect; @@ -1026,9 +1030,13 @@ - (void)drawRect:(NSRect)dirtyRect { } [panelLayer addSublayer:layer]; } + [_textView + setTextContainerInset:NSMakeSize(textFieldOrigin.x, textFieldOrigin.y)]; } -- (BOOL)clickAtPoint:(NSPoint)_point index:(NSInteger*)_index { +- (BOOL)clickAtPoint:(NSPoint)_point + index:(NSInteger*)_index + preeditIndex:(NSInteger*)_preeditIndex { if (CGPathContainsPoint(_shape.path, nil, _point, NO)) { NSPoint point = NSMakePoint(_point.x - self.textView.textContainerInset.width, @@ -1047,11 +1055,20 @@ - (BOOL)clickAtPoint:(NSPoint)_point index:(NSInteger*)_index { point = NSMakePoint(point.x - NSMinX(lineFragment.typographicBounds), point.y - NSMinY(lineFragment.typographicBounds)); index += [lineFragment characterIndexForPoint:point]; - for (NSUInteger i = 0; i < _candidateRanges.count; i += 1) { - NSRange range = [_candidateRanges[i] rangeValue]; - if (index >= range.location && index < NSMaxRange(range)) { - *_index = i; - break; + if (index >= _preeditRange.location && + index < NSMaxRange(_preeditRange)) { + if (_preeditIndex) { + *_preeditIndex = index; + } + } else { + for (NSUInteger i = 0; i < _candidateRanges.count; i += 1) { + NSRange range = [_candidateRanges[i] rangeValue]; + if (index >= range.location && index < NSMaxRange(range)) { + if (_index) { + *_index = i; + } + break; + } } } break; @@ -1227,7 +1244,7 @@ - (void)sendEvent:(NSEvent*)event { case NSEventTypeLeftMouseDown: { NSPoint point = [self mousePosition]; NSInteger index = -1; - if ([_view clickAtPoint:point index:&index]) { + if ([_view clickAtPoint:point index:&index preeditIndex:nil]) { if (index >= 0 && index < _candidates.count) { _index = index; } @@ -1236,7 +1253,15 @@ - (void)sendEvent:(NSEvent*)event { case NSEventTypeLeftMouseUp: { NSPoint point = [self mousePosition]; NSInteger index = -1; - if ([_view clickAtPoint:point index:&index]) { + NSInteger preeditIndex = -1; + if ([_view clickAtPoint:point index:&index preeditIndex:&preeditIndex]) { + if (preeditIndex >= 0 && preeditIndex < _preedit.length) { + if (preeditIndex < _caretPos) { + [_inputController moveCaret:YES]; + } else if (preeditIndex > _caretPos) { + [_inputController moveCaret:NO]; + } + } if (index >= 0 && index < _candidates.count && index == _index) { [_inputController selectCandidate:index]; } @@ -1261,7 +1286,7 @@ - (void)sendEvent:(NSEvent*)event { case NSEventTypeMouseMoved: { NSPoint point = [self mousePosition]; NSInteger index = -1; - if ([_view clickAtPoint:point index:&index]) { + if ([_view clickAtPoint:point index:&index preeditIndex:nil]) { if (index >= 0 && index < _candidates.count && _cursorIndex != index) { [self showPreedit:_preedit selRange:_selRange @@ -1459,12 +1484,9 @@ - (void)show { [self.contentView setBoundsOrigin:NSMakePoint(0, 0)]; [_view.textView setBoundsOrigin:NSMakePoint(0, 0)]; } + BOOL translucency = theme.translucency; [_view setFrame:self.contentView.bounds]; [_view.textView setFrame:self.contentView.bounds]; - [_view.textView setTextContainerInset:NSMakeSize(theme.edgeInset.width, - theme.edgeInset.height)]; - - BOOL translucency = theme.translucency; if (translucency) { [_back setFrame:self.contentView.bounds]; _back.appearance = NSApp.effectiveAppearance;