diff --git a/src/meson.build b/src/meson.build index 90c981792..13570c139 100644 --- a/src/meson.build +++ b/src/meson.build @@ -168,7 +168,6 @@ if host_machine.system() == 'darwin' 'font_file_lister_coretext.mm', 'osx/osx_utils.mm', 'osx/retina_helper.mm', - 'osx/scintilla_ime.mm', ] elif host_machine.system() == 'windows' aegisub_src += [ diff --git a/src/osx/scintilla_ime.mm b/src/osx/scintilla_ime.mm deleted file mode 100644 index 4806d1797..000000000 --- a/src/osx/scintilla_ime.mm +++ /dev/null @@ -1,212 +0,0 @@ -// Copyright (c) 2014, Thomas Goyne -// -// Permission to use, copy, modify, and distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -// Aegisub Project http://www.aegisub.org/ - -#import -#import -#import - -// from src/osx/cocoa/window.mm -@interface wxNSView : NSView { - BOOL _hasToolTip; - NSTrackingRectTag _lastToolTipTrackTag; - id _lastToolTipOwner; - void *_lastUserData; -} -@end - -@interface IMEState : NSObject -@property (nonatomic) NSRange markedRange; -@property (nonatomic) bool undoActive; -@end - -@implementation IMEState -- (id)init { - self = [super init]; - self.markedRange = NSMakeRange(NSNotFound, 0); - self.undoActive = false; - return self; -} -@end - -@interface ScintillaNSView : wxNSView -@property (nonatomic, readonly) wxStyledTextCtrl *stc; -@property (nonatomic, readonly) IMEState *state; -@end - -@implementation ScintillaNSView -- (Class)superclass { - return [wxNSView superclass]; -} - -- (wxStyledTextCtrl *)stc { - return static_cast(wxWidgetImpl::FindFromWXWidget(self)->GetWXPeer()); -} - -- (IMEState *)state { - return objc_getAssociatedObject(self, [IMEState class]); -} - -- (void)invalidate { - self.state.markedRange = NSMakeRange(NSNotFound, 0); - [self.inputContext discardMarkedText]; -} - -#pragma mark - NSTextInputClient - -- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange - actualRange:(NSRangePointer)actualRange -{ - return nil; -} - -- (NSUInteger)characterIndexForPoint:(NSPoint)point { - return self.stc->PositionFromPoint(wxPoint(point.x, point.y)); -} - -- (BOOL)drawsVerticallyForCharacterAtIndex:(NSUInteger)charIndex { - return NO; -} - -- (NSRect)firstRectForCharacterRange:(NSRange)range - actualRange:(NSRangePointer)actualRange -{ - auto stc = self.stc; - int line = stc->LineFromPosition(range.location); - int height = stc->TextHeight(line); - auto pt = stc->PointFromPosition(range.location); - - int width = 0; - if (range.length > 0) { - // If the end of the range is on the next line, the range should be - // truncated to the current line and actualRange should be set to the - // truncated range - int end_line = stc->LineFromPosition(range.location + range.length); - if (end_line > line) { - range.length = stc->PositionFromLine(line + 1) - 1 - range.location; - *actualRange = range; - } - - auto end_pt = stc->PointFromPosition(range.location + range.length); - width = end_pt.x - pt.x; - } - - auto rect = NSMakeRect(pt.x, pt.y, width, height); - rect = [self convertRect:rect toView:nil]; - return [self.window convertRectToScreen:rect]; -} - -- (BOOL)hasMarkedText { - return self.state.markedRange.length > 0; -} - -- (void)insertText:(id)str replacementRange:(NSRange)replacementRange { - [self unmarkText]; - [super insertText:str replacementRange:replacementRange]; -} - -- (NSRange)markedRange { - return self.state.markedRange; -} - -- (NSRange)selectedRange { - long from = 0, to = 0; - self.stc->GetSelection(&from, &to); - return NSMakeRange(from, to - from); -} - -- (void)setMarkedText:(id)str - selectedRange:(NSRange)range - replacementRange:(NSRange)replacementRange -{ - if ([str isKindOfClass:[NSAttributedString class]]) - str = [str string]; - - auto stc = self.stc; - auto state = self.state; - - int pos = stc->GetInsertionPoint(); - if (state.markedRange.length > 0) { - pos = state.markedRange.location; - stc->DeleteRange(pos, state.markedRange.length); - stc->SetSelection(pos, pos); - } else { - state.undoActive = stc->GetUndoCollection(); - if (state.undoActive) - stc->SetUndoCollection(false); - } - - auto utf8 = [str UTF8String]; - auto utf8len = strlen(utf8); - stc->AddTextRaw(utf8, utf8len); - - state.markedRange = NSMakeRange(pos, utf8len); - - stc->SetIndicatorCurrent(1); - stc->IndicatorFillRange(pos, utf8len); - - // Re-enable undo if we got a zero-length string as that means we're done - if (!utf8len && state.undoActive) - stc->SetUndoCollection(true); - else { - int start = pos; - // Range is in utf-16 code units - if (range.location > 0) - start += [[str substringToIndex:range.location] lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; - int length = [[str substringWithRange:range] lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; - stc->SetSelection(start, start + length); - } -} - -- (void)unmarkText { - auto state = self.state; - if (state.markedRange.length > 0) { - self.stc->DeleteRange(state.markedRange.location, state.markedRange.length); - state.markedRange = NSMakeRange(NSNotFound, 0); - if (state.undoActive) - self.stc->SetUndoCollection(true); - } -} - -- (NSArray *)validAttributesForMarkedText { - return @[]; -} -@end - -namespace osx { namespace ime { -void inject(wxStyledTextCtrl *ctrl) { - id view = (id)ctrl->GetHandle(); - object_setClass(view, [ScintillaNSView class]); - - auto state = [IMEState new]; - objc_setAssociatedObject(view, [IMEState class], state, - OBJC_ASSOCIATION_RETAIN_NONATOMIC); - [state release]; -} - -void invalidate(wxStyledTextCtrl *ctrl) { - [(ScintillaNSView *)ctrl->GetHandle() invalidate]; -} - -bool process_key_event(wxStyledTextCtrl *ctrl, wxKeyEvent &evt) { - if (evt.GetModifiers() != 0) return false; - if (evt.GetKeyCode() != WXK_RETURN && evt.GetKeyCode() != WXK_TAB) return false; - if (![(ScintillaNSView *)ctrl->GetHandle() hasMarkedText]) return false; - - evt.Skip(); - return true; -} - -} } diff --git a/src/subs_edit_box.cpp b/src/subs_edit_box.cpp index ca08b4177..8ae123713 100644 --- a/src/subs_edit_box.cpp +++ b/src/subs_edit_box.cpp @@ -52,7 +52,6 @@ #include "text_selection_controller.h" #include "timeedit_ctrl.h" #include "tooltip_manager.h" -#include "utils.h" #include "validators.h" #include @@ -427,8 +426,7 @@ void SubsEditBox::UpdateFrameTiming(agi::vfr::Framerate const& fps) { } void SubsEditBox::OnKeyDown(wxKeyEvent &event) { - if (!osx::ime::process_key_event(edit_ctrl, event)) - hotkey::check("Subtitle Edit Box", c, event); + hotkey::check("Subtitle Edit Box", c, event); } void SubsEditBox::OnChange(wxStyledTextEvent &event) { diff --git a/src/subs_edit_ctrl.cpp b/src/subs_edit_ctrl.cpp index d744900eb..d2d31ee6b 100644 --- a/src/subs_edit_ctrl.cpp +++ b/src/subs_edit_ctrl.cpp @@ -83,8 +83,6 @@ SubsTextEditCtrl::SubsTextEditCtrl(wxWindow* parent, wxSize wsize, long style, a , thesaurus(agi::make_unique()) , context(context) { - osx::ime::inject(this); - // Set properties SetWrapMode(wxSTC_WRAP_WORD); SetMarginWidth(1,0); @@ -187,7 +185,6 @@ void SubsTextEditCtrl::OnLoseFocus(wxFocusEvent &event) { } void SubsTextEditCtrl::OnKeyDown(wxKeyEvent &event) { - if (osx::ime::process_key_event(this, event)) return; event.Skip(); // Workaround for wxSTC eating tabs. @@ -245,10 +242,6 @@ void SubsTextEditCtrl::SetStyles() { // Misspelling indicator IndicatorSetStyle(0,wxSTC_INDIC_SQUIGGLE); IndicatorSetForeground(0,wxColour(255,0,0)); - - // IME pending text indicator - IndicatorSetStyle(1, wxSTC_INDIC_PLAIN); - IndicatorSetUnder(1, true); } void SubsTextEditCtrl::UpdateStyle() { @@ -313,7 +306,6 @@ void SubsTextEditCtrl::UpdateCallTip() { } void SubsTextEditCtrl::SetTextTo(std::string const& text) { - osx::ime::invalidate(this); SetEvtHandlerEnabled(false); Freeze(); diff --git a/src/utils.cpp b/src/utils.cpp index 69c53bd1c..a014b0a29 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -217,13 +217,6 @@ void SetFloatOnParent(wxWindow *) { } RetinaHelper::RetinaHelper(wxWindow *) { } RetinaHelper::~RetinaHelper() { } int RetinaHelper::GetScaleFactor() const { return 1; } - -// OS X implementation in scintilla_ime.mm -namespace osx { namespace ime { - void inject(wxStyledTextCtrl *) { } - void invalidate(wxStyledTextCtrl *) { } - bool process_key_event(wxStyledTextCtrl *, wxKeyEvent&) { return false; } -} } #endif wxString FontFace(std::string opt_prefix) { diff --git a/src/utils.h b/src/utils.h index 269100de8..02ef78aac 100644 --- a/src/utils.h +++ b/src/utils.h @@ -106,13 +106,4 @@ namespace osx { bool activate_top_window_other_than(wxFrame *wx); // Bring all windows to the front, maintaining relative z-order void bring_to_front(); - -namespace ime { - /// Inject the IME helper into the given wxSTC - void inject(wxStyledTextCtrl *ctrl); - /// Invalidate any pending text from the IME - void invalidate(wxStyledTextCtrl *ctrl); - /// Give the IME a chance to process a key event and return whether it did - bool process_key_event(wxStyledTextCtrl *ctrl, wxKeyEvent &); -} }