Mercurial > hg > openttd
changeset 20714:fdf6e212a787 draft
-Add: [OSX] Display the IME composition string ourself.
author | Michael Lutz <michi@icosahedron.de> |
---|---|
date | Fri, 26 Jul 2013 01:41:39 +0200 |
parents | 6baaec6722b9 |
children | db681959a377 |
files | src/console_gui.cpp src/querystring_gui.h src/video/cocoa/cocoa_v.mm src/window.cpp src/window_gui.h |
diffstat | 5 files changed, 159 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/src/console_gui.cpp +++ b/src/console_gui.cpp @@ -320,6 +320,24 @@ } } + virtual const char *GetFocusedText() const + { + return _iconsole_cmdline.buf; + } + + virtual const char *GetCaret() const + { + return _iconsole_cmdline.buf + _iconsole_cmdline.caretpos; + } + + virtual const char *GetMarkedText(size_t *length) const + { + if (_iconsole_cmdline.markend == 0) return NULL; + + *length = _iconsole_cmdline.markend - _iconsole_cmdline.markpos; + return _iconsole_cmdline.buf + _iconsole_cmdline.markpos; + } + virtual Point GetCaretPosition() const { int delta = min(this->width - this->line_offset - _iconsole_cmdline.pixels - ICON_RIGHT_BORDERWIDTH, 0);
--- a/src/querystring_gui.h +++ b/src/querystring_gui.h @@ -55,6 +55,37 @@ void HandleEditBox(Window *w, int wid); Point GetCaretPosition(const Window *w, int wid) const; + + /** + * Get the current text. + * @return Current text. + */ + const char *GetText() const + { + return this->text.buf; + } + + /** + * Get the position of the caret in the text buffer. + * @return Pointer to the caret in the text buffer. + */ + const char *GetCaret() const + { + return this->text.buf + this->text.caretpos; + } + + /** + * Get the currently marked text. + * @param[out] length Length of the marked text. + * @return Begining of the marked area or NULL if no text is marked. + */ + const char *GetMarkedText(size_t *length) const + { + if (this->text.markend == 0) return NULL; + + *length = this->text.markend - this->text.markpos; + return this->text.buf + this->text.markpos; + } }; void ShowOnScreenKeyboard(Window *parent, int button);
--- a/src/video/cocoa/cocoa_v.mm +++ b/src/video/cocoa/cocoa_v.mm @@ -33,6 +33,8 @@ #include "../../blitter/factory.hpp" #include "../../fileio_func.h" #include "../../gfx_func.h" +#include "../../window_func.h" +#include "../../window_gui.h" #import <sys/param.h> /* for MAXPATHLEN */ @@ -693,6 +695,43 @@ +/** + * Count the number of UTF-16 code points in a range of an UTF-8 string. + * @param from Start of the range. + * @param to End of the range. + * @return Number of UTF-16 code points in the range. + */ +static NSUInteger CountUtf16Units(const char *from, const char *to) +{ + NSUInteger i = 0; + + while (from < to) { + WChar c; + size_t len = Utf8Decode(&c, from); + i += len < 4 ? 1 : 2; // Watch for surrogate pairs. + from += len; + } + + return i; +} + +/** + * Advance an UTF-8 string by a number of equivalent UTF-16 code points. + * @param str UTF-8 string. + * @param count Number of UTF-16 code points to advance the string by. + * @return Advanced string pointer. + */ +static const char *Utf8AdvanceByUtf16Units(const char *str, NSUInteger count) +{ + for (NSUInteger i = 0; i < count && *str != '\0'; ) { + WChar c; + size_t len = Utf8Decode(&c, str); + i += len < 4 ? 1 : 2; // Watch for surrogates. + str += len; + } + + return str; +} @implementation OTTD_CocoaView /** @@ -802,6 +841,15 @@ /** Set a new marked text and reposition the caret. */ - (void)setMarkedText:(id)aString selectedRange:(NSRange)selRange { + NSString *s = [ aString isKindOfClass:[ NSAttributedString class ] ] ? [ aString string ] : (NSString *)aString; + + const char *utf8 = [ s UTF8String ]; + if (utf8 != NULL) { + /* Convert caret index into a pointer in the UTF-8 string. */ + const char *selection = Utf8AdvanceByUtf16Units(utf8, selRange.location); + + HandleTextInput(utf8, true, selection); + } } /** Unmark the current marked text. */ @@ -813,19 +861,36 @@ /** Get the caret position. */ - (NSRange)selectedRange { - return NSMakeRange(NSNotFound, 0); + if (!EditBoxInGlobalFocus()) return NSMakeRange(NSNotFound, 0); + + NSUInteger start = CountUtf16Units(_focused_window->GetFocusedText(), _focused_window->GetCaret()); + return NSMakeRange(start, 0); } /** Get the currently marked range. */ - (NSRange)markedRange { + if (!EditBoxInGlobalFocus()) return NSMakeRange(NSNotFound, 0); + + size_t mark_len; + const char *mark = _focused_window->GetMarkedText(&mark_len); + if (mark != NULL) { + NSUInteger start = CountUtf16Units(_focused_window->GetFocusedText(), mark); + NSUInteger len = CountUtf16Units(mark, mark + mark_len); + + return NSMakeRange(start, len); + } + return NSMakeRange(NSNotFound, 0); } /** Is any text marked? */ - (BOOL)hasMarkedText { - return NO; + if (!EditBoxInGlobalFocus()) return NO; + + size_t len; + return _focused_window->GetMarkedText(&len) != NULL; } /** Get a string corresponding to the given range. */
--- a/src/window.cpp +++ b/src/window.cpp @@ -324,6 +324,46 @@ } /** + * Get the current input text if an edit box has the focus. + * @return The currently focused input text or NULL if no input focused. + */ +/* virtual */ const char *Window::GetFocusedText() const +{ + if (this->nested_focus != NULL && this->nested_focus->type == WWT_EDITBOX) { + return this->GetQueryString(this->nested_focus->index)->GetText(); + } + + return NULL; +} + +/** + * Get the string at the caret if an edit box has the focus. + * @return The text at the caret or NULL if no edit box is focused. + */ +/* virtual */ const char *Window::GetCaret() const +{ + if (this->nested_focus != NULL && this->nested_focus->type == WWT_EDITBOX) { + return this->GetQueryString(this->nested_focus->index)->GetCaret(); + } + + return NULL; +} + +/** + * Get the range of the currently marked input text. + * @param[out] length Length of the marked text. + * @return Pointer to the start of the marked text or NULL if no text is marked. + */ +/* virtual */ const char *Window::GetMarkedText(size_t *length) const +{ + if (this->nested_focus != NULL && this->nested_focus->type == WWT_EDITBOX) { + return this->GetQueryString(this->nested_focus->index)->GetMarkedText(length); + } + + return NULL; +} + +/** * Get the current caret position if an edit box has the focus. * @return Top-left location of the caret, relative to the window. */
--- a/src/window_gui.h +++ b/src/window_gui.h @@ -345,6 +345,9 @@ const QueryString *GetQueryString(uint widnum) const; QueryString *GetQueryString(uint widnum); + virtual const char *GetFocusedText() const; + virtual const char *GetCaret() const; + virtual const char *GetMarkedText(size_t *length) const; virtual Point GetCaretPosition() const; void InitNested(WindowNumber number = 0);