initial TextInput context callback

This commit is contained in:
Jack Andersen 2015-12-25 19:21:13 -10:00
parent 92c47a5e77
commit fb1282c3e4
2 changed files with 220 additions and 1 deletions

View File

@ -103,6 +103,24 @@ enum class EModifierKey
}; };
ENABLE_BITWISE_ENUM(EModifierKey) ENABLE_BITWISE_ENUM(EModifierKey)
struct ITextInputCallback
{
virtual bool hasMarkedText() const=0;
virtual std::pair<int,int> markedRange() const=0;
virtual std::pair<int,int> selectedRange() const=0;
virtual void setMarkedText(const std::string& str,
const std::pair<int,int>& selectedRange,
const std::pair<int,int>& replacementRange)=0;
virtual void unmarkText()=0;
virtual std::string substringForRange(const std::pair<int,int>& range,
std::pair<int,int>& actualRange) const=0;
virtual void insertText(const std::string& str, const std::pair<int,int>& range)=0;
virtual int characterIndexAtPoint(const SWindowCoord& point) const=0;
virtual SWindowRect rectForCharacterRange(const std::pair<int,int>& range,
std::pair<int,int>& actualRange) const=0;
};
class IWindowCallback class IWindowCallback
{ {
public: public:
@ -139,7 +157,10 @@ public:
virtual void modKeyDown(EModifierKey mod, bool isRepeat) virtual void modKeyDown(EModifierKey mod, bool isRepeat)
{(void)mod;(void)isRepeat;} {(void)mod;(void)isRepeat;}
virtual void modKeyUp(EModifierKey mod) {(void)mod;} virtual void modKeyUp(EModifierKey mod) {(void)mod;}
virtual void utf8FragmentDown(const std::string& str) {(void)str;} virtual void utf8FragmentDown(const std::string& str) {(void)str;}
virtual ITextInputCallback* getTextInputCallback() {return nullptr;}
virtual void focusLost() {} virtual void focusLost() {}
virtual void focusGained() {} virtual void focusGained() {}
virtual void windowMoved(const SWindowRect& rect) virtual void windowMoved(const SWindowRect& rect)

View File

@ -123,12 +123,13 @@ class GraphicsContextCocoaGL;
class GraphicsContextCocoaMetal; class GraphicsContextCocoaMetal;
} }
@interface BooCocoaResponder : NSResponder @interface BooCocoaResponder : NSResponder <NSTextInputClient>
{ {
@public @public
NSUInteger lastModifiers; NSUInteger lastModifiers;
boo::GraphicsContextCocoa* booContext; boo::GraphicsContextCocoa* booContext;
NSView* parentView; NSView* parentView;
NSTextInputContext* textContext;
} }
- (id)initWithBooContext:(boo::GraphicsContextCocoa*)bctx View:(NSView*)view; - (id)initWithBooContext:(boo::GraphicsContextCocoa*)bctx View:(NSView*)view;
@end @end
@ -426,9 +427,174 @@ IGraphicsContext* _GraphicsContextCocoaMetalNew(IGraphicsContext::EGraphicsAPI a
lastModifiers = 0; lastModifiers = 0;
booContext = bctx; booContext = bctx;
parentView = view; parentView = view;
textContext = [[NSTextInputContext alloc] initWithClient:self];
return self; return self;
} }
- (BOOL)hasMarkedText
{
if (booContext->m_callback)
{
boo::ITextInputCallback* textCb = booContext->m_callback->getTextInputCallback();
if (textCb)
return textCb->hasMarkedText();
}
return false;
}
- (NSRange)markedRange
{
if (booContext->m_callback)
{
boo::ITextInputCallback* textCb = booContext->m_callback->getTextInputCallback();
if (textCb)
{
std::pair<int,int> rng = textCb->markedRange();
return NSMakeRange(rng.first < 0 ? NSNotFound : rng.first, rng.second);
}
}
return NSMakeRange(NSNotFound, 0);
}
- (NSRange)selectedRange
{
if (booContext->m_callback)
{
boo::ITextInputCallback* textCb = booContext->m_callback->getTextInputCallback();
if (textCb)
{
std::pair<int,int> rng = textCb->selectedRange();
return NSMakeRange(rng.first < 0 ? NSNotFound : rng.first, rng.second);
}
}
return NSMakeRange(NSNotFound, 0);
}
- (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange
{
if (booContext->m_callback)
{
boo::ITextInputCallback* textCb = booContext->m_callback->getTextInputCallback();
if (textCb)
{
NSString* plainStr;
if ([aString isKindOfClass:[NSAttributedString class]])
plainStr = ((NSAttributedString*)aString).string;
else
{
plainStr = aString;
[plainStr retain];
}
textCb->setMarkedText([plainStr UTF8String],
std::make_pair(selectedRange.location, selectedRange.length),
std::make_pair(replacementRange.location, replacementRange.length));
[plainStr release];
}
}
}
- (void)unmarkText
{
if (booContext->m_callback)
{
boo::ITextInputCallback* textCb = booContext->m_callback->getTextInputCallback();
if (textCb)
textCb->unmarkText();
}
}
- (NSArray<NSString*>*)validAttributesForMarkedText
{
return [NSArray array];
}
- (NSAttributedString*)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
{
if (booContext->m_callback)
{
boo::ITextInputCallback* textCb = booContext->m_callback->getTextInputCallback();
if (textCb)
{
std::pair<int,int> actualRng;
std::string str = textCb->substringForRange(std::make_pair(aRange.location, aRange.length), actualRng);
if (str.empty())
return nil;
actualRange->location = actualRng.first;
actualRange->length = actualRng.second;
NSString* nsStr = [NSString stringWithUTF8String:str.c_str()];
NSAttributedString* ret = [[NSAttributedString alloc] initWithString:nsStr];
[nsStr release];
return ret;
}
}
return nil;
}
- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange
{
if (booContext->m_callback)
{
boo::ITextInputCallback* textCb = booContext->m_callback->getTextInputCallback();
if (textCb)
{
NSString* plainStr;
if ([aString isKindOfClass:[NSAttributedString class]])
plainStr = ((NSAttributedString*)aString).string;
else
{
plainStr = aString;
[plainStr retain];
}
textCb->insertText([plainStr UTF8String],
std::make_pair(replacementRange.location, replacementRange.length));
[plainStr release];
}
}
}
- (NSUInteger)characterIndexForPoint:(NSPoint)aPoint
{
if (booContext->m_callback)
{
boo::ITextInputCallback* textCb = booContext->m_callback->getTextInputCallback();
if (textCb)
{
NSPoint backingPoint = [parentView convertPointToBacking:aPoint];
boo::SWindowCoord coord = {{int(backingPoint.x), int(backingPoint.y)}, {int(aPoint.x), int(aPoint.y)}};
int idx = textCb->characterIndexAtPoint(coord);
if (idx < 0)
return NSNotFound;
return idx;
}
}
return NSNotFound;
}
- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
{
if (booContext->m_callback)
{
boo::ITextInputCallback* textCb = booContext->m_callback->getTextInputCallback();
if (textCb)
{
std::pair<int,int> actualRng;
boo::SWindowRect rect =
textCb->rectForCharacterRange(std::make_pair(aRange.location, aRange.length), actualRng);
actualRange->location = actualRng.first;
actualRange->length = actualRng.second;
return [[parentView window] convertRectToScreen:
[parentView convertRectFromBacking:NSMakeRect(rect.location[0], rect.location[1],
rect.size[0], rect.size[1])]];
}
}
return NSMakeRect(0, 0, 0, 0);
}
- (void)doCommandBySelector:(SEL)aSelector
{
}
static inline boo::EModifierKey getMod(NSUInteger flags) static inline boo::EModifierKey getMod(NSUInteger flags)
{ {
boo::EModifierKey ret = boo::EModifierKey::None; boo::EModifierKey ret = boo::EModifierKey::None;
@ -470,6 +636,7 @@ static inline boo::EMouseButton getButton(NSEvent* event)
}; };
booContext->m_callback->mouseDown(coord, boo::EMouseButton::Primary, booContext->m_callback->mouseDown(coord, boo::EMouseButton::Primary,
getMod([theEvent modifierFlags])); getMod([theEvent modifierFlags]));
[textContext handleEvent:theEvent];
} }
- (void)mouseUp:(NSEvent*)theEvent - (void)mouseUp:(NSEvent*)theEvent
@ -487,6 +654,7 @@ static inline boo::EMouseButton getButton(NSEvent* event)
}; };
booContext->m_callback->mouseUp(coord, boo::EMouseButton::Primary, booContext->m_callback->mouseUp(coord, boo::EMouseButton::Primary,
getMod([theEvent modifierFlags])); getMod([theEvent modifierFlags]));
[textContext handleEvent:theEvent];
} }
- (void)rightMouseDown:(NSEvent*)theEvent - (void)rightMouseDown:(NSEvent*)theEvent
@ -504,6 +672,7 @@ static inline boo::EMouseButton getButton(NSEvent* event)
}; };
booContext->m_callback->mouseDown(coord, boo::EMouseButton::Secondary, booContext->m_callback->mouseDown(coord, boo::EMouseButton::Secondary,
getMod([theEvent modifierFlags])); getMod([theEvent modifierFlags]));
[textContext handleEvent:theEvent];
} }
- (void)rightMouseUp:(NSEvent*)theEvent - (void)rightMouseUp:(NSEvent*)theEvent
@ -521,6 +690,7 @@ static inline boo::EMouseButton getButton(NSEvent* event)
}; };
booContext->m_callback->mouseUp(coord, boo::EMouseButton::Secondary, booContext->m_callback->mouseUp(coord, boo::EMouseButton::Secondary,
getMod([theEvent modifierFlags])); getMod([theEvent modifierFlags]));
[textContext handleEvent:theEvent];
} }
- (void)otherMouseDown:(NSEvent*)theEvent - (void)otherMouseDown:(NSEvent*)theEvent
@ -540,6 +710,7 @@ static inline boo::EMouseButton getButton(NSEvent* event)
{float(liw.x / frame.size.width), float(liw.y / frame.size.height)} {float(liw.x / frame.size.width), float(liw.y / frame.size.height)}
}; };
booContext->m_callback->mouseDown(coord, button, getMod([theEvent modifierFlags])); booContext->m_callback->mouseDown(coord, button, getMod([theEvent modifierFlags]));
[textContext handleEvent:theEvent];
} }
- (void)otherMouseUp:(NSEvent*)theEvent - (void)otherMouseUp:(NSEvent*)theEvent
@ -559,6 +730,7 @@ static inline boo::EMouseButton getButton(NSEvent* event)
{float(liw.x / frame.size.width), float(liw.y / frame.size.height)} {float(liw.x / frame.size.width), float(liw.y / frame.size.height)}
}; };
booContext->m_callback->mouseUp(coord, button, getMod([theEvent modifierFlags])); booContext->m_callback->mouseUp(coord, button, getMod([theEvent modifierFlags]));
[textContext handleEvent:theEvent];
} }
- (void)mouseMoved:(NSEvent*)theEvent - (void)mouseMoved:(NSEvent*)theEvent
@ -578,6 +750,7 @@ static inline boo::EMouseButton getButton(NSEvent* event)
}; };
booContext->m_callback->mouseMove(coord); booContext->m_callback->mouseMove(coord);
} }
[textContext handleEvent:theEvent];
} }
- (void)mouseDragged:(NSEvent*)theEvent - (void)mouseDragged:(NSEvent*)theEvent
@ -614,6 +787,7 @@ static inline boo::EMouseButton getButton(NSEvent* event)
(bool)[theEvent hasPreciseScrollingDeltas] (bool)[theEvent hasPreciseScrollingDeltas]
}; };
booContext->m_callback->scroll(coord, scroll); booContext->m_callback->scroll(coord, scroll);
[textContext handleEvent:theEvent];
} }
- (void)touchesBeganWithEvent:(NSEvent*)event - (void)touchesBeganWithEvent:(NSEvent*)event
@ -798,6 +972,7 @@ static boo::ESpecialKey translateKeycode(short code)
booContext->m_callback->charKeyDown([chars characterAtIndex:0], booContext->m_callback->charKeyDown([chars characterAtIndex:0],
getMod(theEvent.modifierFlags), getMod(theEvent.modifierFlags),
theEvent.isARepeat); theEvent.isARepeat);
[textContext handleEvent:theEvent];
} }
- (void)keyUp:(NSEvent*)theEvent - (void)keyUp:(NSEvent*)theEvent
@ -812,6 +987,7 @@ static boo::ESpecialKey translateKeycode(short code)
else if ([chars length]) else if ([chars length])
booContext->m_callback->charKeyUp([chars characterAtIndex:0], booContext->m_callback->charKeyUp([chars characterAtIndex:0],
getMod(theEvent.modifierFlags)); getMod(theEvent.modifierFlags));
[textContext handleEvent:theEvent];
} }
- (void)flagsChanged:(NSEvent*)theEvent - (void)flagsChanged:(NSEvent*)theEvent
@ -845,6 +1021,7 @@ static boo::ESpecialKey translateKeycode(short code)
lastModifiers = modFlags; lastModifiers = modFlags;
} }
[textContext handleEvent:theEvent];
} }
- (BOOL)acceptsTouchEvents - (BOOL)acceptsTouchEvents
@ -857,6 +1034,12 @@ static boo::ESpecialKey translateKeycode(short code)
return YES; return YES;
} }
- (void)dealloc
{
[textContext release];
[super dealloc];
}
@end @end
@implementation GraphicsContextCocoaGLInternal @implementation GraphicsContextCocoaGLInternal
@ -1152,6 +1335,21 @@ public:
}); });
} }
void claimKeyboardFocus(const int coord[2])
{
}
bool clipboardCopy(EClipboardType type, const uint8_t* data, size_t sz)
{
}
std::unique_ptr<uint8_t[]> clipboardPaste(EClipboardType type, size_t& sz)
{
}
ETouchType getTouchType() const ETouchType getTouchType() const
{ {
return ETouchType::Trackpad; return ETouchType::Trackpad;