summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormichi_cc <michi_cc@openttd.org>2013-08-05 20:37:44 +0000
committermichi_cc <michi_cc@openttd.org>2013-08-05 20:37:44 +0000
commitf5e41314922604c160efc4ac18c77056a1b66400 (patch)
tree38f170e1e3a23264104803d4b573ab43644e23a0
parentc64e297e0c3f5f1f59a21d1ad3e12e6834e155d7 (diff)
downloadopenttd-f5e41314922604c160efc4ac18c77056a1b66400.tar.xz
(svn r25689) -Add: [OSX] Display the IME composition string ourself.
-rw-r--r--src/console_gui.cpp18
-rw-r--r--src/querystring_gui.h31
-rw-r--r--src/video/cocoa/cocoa_v.mm69
-rw-r--r--src/window.cpp40
-rw-r--r--src/window_gui.h3
5 files changed, 159 insertions, 2 deletions
diff --git a/src/console_gui.cpp b/src/console_gui.cpp
index 69cf7a4d7..d7ef57a44 100644
--- a/src/console_gui.cpp
+++ b/src/console_gui.cpp
@@ -320,6 +320,24 @@ struct IConsoleWindow : Window
}
}
+ 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);
diff --git a/src/querystring_gui.h b/src/querystring_gui.h
index a652b382d..db6e33076 100644
--- a/src/querystring_gui.h
+++ b/src/querystring_gui.h
@@ -55,6 +55,37 @@ public:
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);
diff --git a/src/video/cocoa/cocoa_v.mm b/src/video/cocoa/cocoa_v.mm
index 1a0ea1a60..16069bb24 100644
--- 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 @@ void cocoaReleaseAutoreleasePool()
+/**
+ * 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 @@ void cocoaReleaseAutoreleasePool()
/** 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 @@ void cocoaReleaseAutoreleasePool()
/** 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. */
diff --git a/src/window.cpp b/src/window.cpp
index 1197b0c6e..907f575c6 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -324,6 +324,46 @@ QueryString *Window::GetQueryString(uint widnum)
}
/**
+ * 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.
*/
diff --git a/src/window_gui.h b/src/window_gui.h
index 0fd76cfcc..494e5bfcb 100644
--- a/src/window_gui.h
+++ b/src/window_gui.h
@@ -345,6 +345,9 @@ public:
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);