summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Fl_Input.cxx3
-rw-r--r--src/Fl_Input_.cxx4
-rw-r--r--src/Fl_Text_Display.cxx3
-rw-r--r--src/Fl_Text_Editor.cxx5
-rw-r--r--src/Fl_cocoa.mm66
-rw-r--r--src/Fl_compose.cxx38
6 files changed, 86 insertions, 33 deletions
diff --git a/src/Fl_Input.cxx b/src/Fl_Input.cxx
index 80d7cf955..d712a7d8f 100644
--- a/src/Fl_Input.cxx
+++ b/src/Fl_Input.cxx
@@ -780,12 +780,14 @@ Fl_Float_Input::Fl_Float_Input(int X,int Y,int W,int H,const char *l)
: Fl_Input(X,Y,W,H,l)
{
type(FL_FLOAT_INPUT);
+ clear_flag(MAC_USE_ACCENTS_MENU);
}
Fl_Int_Input::Fl_Int_Input(int X,int Y,int W,int H,const char *l)
: Fl_Input(X,Y,W,H,l) {
type(FL_INT_INPUT);
+ clear_flag(MAC_USE_ACCENTS_MENU);
}
@@ -810,6 +812,7 @@ Fl_Multiline_Output::Fl_Multiline_Output(int X,int Y,int W,int H,const char *l)
Fl_Secret_Input::Fl_Secret_Input(int X,int Y,int W,int H,const char *l)
: Fl_Input(X,Y,W,H,l) {
type(FL_SECRET_INPUT);
+ clear_flag(MAC_USE_ACCENTS_MENU);
}
int Fl_Secret_Input::handle(int event) {
diff --git a/src/Fl_Input_.cxx b/src/Fl_Input_.cxx
index 644d954c3..0cfc6a8fe 100644
--- a/src/Fl_Input_.cxx
+++ b/src/Fl_Input_.cxx
@@ -388,6 +388,9 @@ void Fl_Input_::drawtext(int X, int Y, int W, int H) {
} else {
fl_rectf((int)(xpos+curx+0.5), Y+ypos, 2, height);
}
+#ifdef __APPLE__
+ Fl::insertion_point_location(xpos+curx, Y+ypos+height, height);
+#endif
}
CONTINUE:
@@ -1119,6 +1122,7 @@ Fl_Input_::Fl_Input_(int X, int Y, int W, int H, const char* l)
maximum_size_ = 32767;
shortcut_ = 0;
set_flag(SHORTCUT_LABEL);
+ set_flag(MAC_USE_ACCENTS_MENU);
tab_nav(1);
}
diff --git a/src/Fl_Text_Display.cxx b/src/Fl_Text_Display.cxx
index 5f086eaa2..e8af2c555 100644
--- a/src/Fl_Text_Display.cxx
+++ b/src/Fl_Text_Display.cxx
@@ -2067,6 +2067,9 @@ void Fl_Text_Display::draw_cursor( int X, int Y ) {
if ( X < text_area.x - 1 || X > text_area.x + text_area.w )
return;
+#ifdef __APPLE__
+ Fl::insertion_point_location(X, bot, fontHeight);
+#endif
/* For cursors other than the block, make them around 2/3 of a character
width, rounded to an even number of pixels so that X will draw an
odd number centered on the stem at x. */
diff --git a/src/Fl_Text_Editor.cxx b/src/Fl_Text_Editor.cxx
index b580951ae..cc57725ed 100644
--- a/src/Fl_Text_Editor.cxx
+++ b/src/Fl_Text_Editor.cxx
@@ -73,6 +73,7 @@ Fl_Text_Editor::Fl_Text_Editor(int X, int Y, int W, int H, const char* l)
mCursorOn = 1;
insert_mode_ = 1;
key_bindings = 0;
+ set_flag(MAC_USE_ACCENTS_MENU);
// handle the default key bindings
add_default_key_bindings(&key_bindings);
@@ -526,12 +527,8 @@ int Fl_Text_Editor::handle_key() {
}
#ifdef __APPLE__
if (Fl::marked_text_length()) {
- int x, y;
int pos = this->insert_position();
this->buffer()->select(pos - Fl::marked_text_length(), pos);
- this->position_to_xy( this->insert_position(), &x, &y);
- y += this->textsize();
- Fl::insertion_point_location(x, y);
}
#endif
show_insert_position();
diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm
index 4d0732106..2188c7e6b 100644
--- a/src/Fl_cocoa.mm
+++ b/src/Fl_cocoa.mm
@@ -1668,9 +1668,14 @@ static void q_set_window_title(NSWindow *nsw, const char * name, const char *mi
}
-@interface FLView : NSView <NSTextInput> {
+@interface FLView : NSView <NSTextInput
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+, NSTextInputClient
+#endif
+> {
BOOL in_key_event;
NSInteger identifier;
+ NSRange selectedRange;
}
+ (void)prepareEtext:(NSString*)aString;
- (id)init;
@@ -1949,27 +1954,34 @@ static void q_set_window_title(NSWindow *nsw, const char * name, const char *mi
}
// These functions implement text input.
-// On the way to fully support CJK text input, this is the way to go.
- (void)doCommandBySelector:(SEL)aSelector {
}
-
- (void)insertText:(id)aString {
+ [self insertText:aString replacementRange:NSMakeRange(NSNotFound, 0)];
+}
+- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange {
NSString *received;
if ([aString isKindOfClass:[NSAttributedString class]]) {
received = [(NSAttributedString*)aString string];
} else {
received = (NSString*)aString;
}
- //NSLog(@"insertText: received=%@ Fl::marked_text_length()=%d",received,Fl::marked_text_length());
-
+ /*NSLog(@"insertText=%@ l=%d Fl::marked_text_length()=%d range=%d,%d",
+ received,strlen([received UTF8String]),Fl::marked_text_length(),replacementRange.location,replacementRange.length);*/
fl_lock_function();
+ Fl_Window *target = [(FLWindow*)[self window] getFl_Window];
+ while (replacementRange.length--) { // delete replacementRange.length characters before insertion point
+ int saved_keysym = Fl::e_keysym;
+ Fl::e_keysym = FL_BackSpace;
+ Fl::handle(FL_KEYBOARD, target);
+ Fl::e_keysym = saved_keysym;
+ }
[FLView prepareEtext:received];
// We can get called outside of key events (e.g., from the character palette, from CJK text input).
// Transform character palette actions to FL_PASTE events.
- Fl_Window *target = [(FLWindow*)[self window] getFl_Window];
Fl_X::next_marked_length = 0;
Fl::handle( (in_key_event || Fl::marked_text_length()) ? FL_KEYBOARD : FL_PASTE, target);
-
+ selectedRange = NSMakeRange(100, 0); // 100 is an arbitrary value
// for some reason, with the palette, the window does not redraw until the next mouse move or button push
// sending a 'redraw()' or 'awake()' does not solve the issue!
Fl::flush();
@@ -1977,6 +1989,10 @@ static void q_set_window_title(NSWindow *nsw, const char * name, const char *mi
}
- (void)setMarkedText:(id)aString selectedRange:(NSRange)newSelection {
+ [self setMarkedText:aString selectedRange:newSelection replacementRange:NSMakeRange(NSNotFound, 0)];
+}
+
+- (void)setMarkedText:(id)aString selectedRange:(NSRange)newSelection replacementRange:(NSRange)replacementRange {
NSString *received;
if ([aString isKindOfClass:[NSAttributedString class]]) {
received = [(NSAttributedString*)aString string];
@@ -1984,15 +2000,21 @@ static void q_set_window_title(NSWindow *nsw, const char * name, const char *mi
received = (NSString*)aString;
}
fl_lock_function();
- // This code creates the OS X behaviour of seeing dead keys as things
- // are being composed.
- [FLView prepareEtext:received];
- /*NSLog(@"setMarkedText:%@ %d %d Fl::marked_text_length()=%d Fl::e_length=%d",
- received, newSelection.location, newSelection.length, Fl::marked_text_length(), Fl::e_length);*/
+ /*NSLog(@"setMarkedText:%@ l=%d newSelection=%d,%d Fl::marked_text_length()=%d replacement=%d,%d",
+ received, strlen([received UTF8String]), newSelection.location, newSelection.length, Fl::marked_text_length(),
+ replacementRange.location, replacementRange.length);*/
Fl_Window *target = [(FLWindow*)[self window] getFl_Window];
+ while (replacementRange.length--) { // delete replacementRange.length characters before insertion point
+ Fl::e_keysym = FL_BackSpace;
+ Fl::compose_state = 0;
+ Fl_X::next_marked_length = 0;
+ Fl::handle(FL_KEYBOARD, target);
+ Fl::e_keysym = 'a'; // pretend a letter key was hit
+ }
+ [FLView prepareEtext:received];
Fl_X::next_marked_length = Fl::e_length;
Fl::handle(FL_KEYBOARD, target);
-
+ selectedRange = NSMakeRange(100, newSelection.length);
fl_unlock_function();
}
@@ -2004,6 +2026,8 @@ static void q_set_window_title(NSWindow *nsw, const char * name, const char *mi
}
- (NSRange)selectedRange {
+ Fl_Widget *w = Fl::focus();
+ if (w && w->use_accents_menu()) return selectedRange;
return NSMakeRange(NSNotFound, 0);
}
@@ -2018,6 +2042,9 @@ static void q_set_window_title(NSWindow *nsw, const char * name, const char *mi
}
- (NSAttributedString *)attributedSubstringFromRange:(NSRange)aRange {
+ return [self attributedSubstringForProposedRange:aRange actualRange:NULL];
+}
+- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange {
//NSLog(@"attributedSubstringFromRange: %d %d",aRange.location,aRange.length);
return nil;
}
@@ -2027,7 +2054,10 @@ static void q_set_window_title(NSWindow *nsw, const char * name, const char *mi
}
- (NSRect)firstRectForCharacterRange:(NSRange)aRange {
- //NSLog(@"firstRectForCharacterRange %d %d",aRange.location, aRange.length);
+ return [self firstRectForCharacterRange:aRange actualRange:NULL];
+}
+- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange {
+ //NSLog(@"firstRectForCharacterRange %d %d actualRange=%p",aRange.location, aRange.length,actualRange);
NSRect glyphRect;
fl_lock_function();
Fl_Widget *focus = Fl::focus();
@@ -2035,8 +2065,8 @@ static void q_set_window_title(NSWindow *nsw, const char * name, const char *mi
if (!focus) focus = wfocus;
glyphRect.size.width = 0;
- int x, y;
- if (Fl_X::insertion_point_location(&x, &y)) {
+ int x, y, height;
+ if (Fl_X::insertion_point_location(&x, &y, &height)) {
glyphRect.origin.x = (CGFloat)x;
glyphRect.origin.y = (CGFloat)y;
} else {
@@ -2048,8 +2078,9 @@ static void q_set_window_title(NSWindow *nsw, const char * name, const char *mi
glyphRect.origin.x = focus->x();
glyphRect.origin.y = focus->y() + focus->h();
}
+ height = 12;
}
- glyphRect.size.height = 12;
+ glyphRect.size.height = height;
Fl_Window *win = focus->as_window();
if (!win) win = focus->window();
while (win != NULL && win != wfocus) {
@@ -2060,6 +2091,7 @@ static void q_set_window_title(NSWindow *nsw, const char * name, const char *mi
// Convert the rect to screen coordinates
glyphRect.origin.y = wfocus->h() - glyphRect.origin.y;
glyphRect.origin = [[self window] convertBaseToScreen:glyphRect.origin];
+ if (actualRange) *actualRange = aRange;
fl_unlock_function();
return glyphRect;
}
diff --git a/src/Fl_compose.cxx b/src/Fl_compose.cxx
index 138d3477c..47f4e7e3a 100644
--- a/src/Fl_compose.cxx
+++ b/src/Fl_compose.cxx
@@ -16,6 +16,12 @@
// http://www.fltk.org/str.php
//
+/**
+\file Fl_compose.cxx
+Utility functions to support text input.
+*/
+
+
#include <FL/Fl.H>
#include <FL/x.H>
@@ -44,22 +50,27 @@ extern XIC fl_xim_ic;
keys, and del is set to zero. You could insert the text anyways, if
you don't know what else to do.
- <p>On the Mac OS platform, text editing widgets should preferentially signal
- marked text, that is, temporary text replaced by other text during the text
- input process. Such signaling is usually done underlining marked text. Widgets can call
+ <p>On the Mac OS platform, text input can involve marked text, that is,
+ temporary text replaced by other text during the input process. This occurs,
+ e.g., when using dead keys or when entering CJK characters.
+ Text editing widgets should preferentially signal
+ marked text, usually underlining it. Widgets can call
<tt>int Fl::marked_text_length()</tt> <i>after</i> having called Fl::compose(int&)
to obtain the length in bytes of marked text that always finishes at the
current insertion point. It's the widget's task to underline marked text.
- Widgets should also call <tt>void Fl::reset_marked_text()</tt> when processing FL_UNFOCUS events.
- Optionally, widgets can also call
- <tt>void Fl::insertion_point_location(int x, int y)</tt> to indicate the window
- coordinates of the bottom of the current insertion point.
+ Widgets should also call <tt>void Fl::reset_marked_text()</tt> when processing FL_UNFOCUS
+ events. Optionally, widgets can also call
+ <tt>void Fl::insertion_point_location(int x, int y, int height)</tt> to indicate the window
+ coordinates of the bottom of the current insertion point and the line height.
This way, auxiliary windows that help choosing among alternative characters
appear just below the insertion point. If widgets don't do that,
auxiliary windows appear at the widget's bottom. The
- Fl_Input and Fl_Text_Editor widgets signal marked text underlining it.
- If none of this is done by a user-defined text editing widget, complex
- (e.g., CJK) text input will work, but will not signal to the user what text is marked.
+ Fl_Input and Fl_Text_Editor widgets underline marked text.
+ If none of this is done by a user-defined text editing widget,
+ text input will work, but will not signal to the user what text is marked.
+ Finally, text editing widgets should call <tt>set_flag(MAC_USE_ACCENTS_MENU);</tt>
+ in their constructor if they want to use the feature introduced with Mac OS 10.7 "Lion"
+ where pressing and holding a key on the keyboard opens an accented-character menu window.
<p>Though the current implementation returns immediately, future
versions may take quite awhile, as they may pop up a window or do
@@ -100,6 +111,7 @@ int Fl::marked_text_length() {
static int insertion_point_x = 0;
static int insertion_point_y = 0;
+static int insertion_point_height = 0;
static bool insertion_point_location_is_valid = false;
void Fl::reset_marked_text() {
@@ -107,18 +119,20 @@ void Fl::reset_marked_text() {
Fl_X::next_marked_length = 0;
insertion_point_location_is_valid = false;
}
-int Fl_X::insertion_point_location(int *px, int *py)
+int Fl_X::insertion_point_location(int *px, int *py, int *pheight)
// return true if the current coordinates of the insertion point are available
{
if ( ! insertion_point_location_is_valid ) return false;
*px = insertion_point_x;
*py = insertion_point_y;
+ *pheight = insertion_point_height;
return true;
}
-void Fl::insertion_point_location(int x, int y) {
+void Fl::insertion_point_location(int x, int y, int height) {
insertion_point_location_is_valid = true;
insertion_point_x = x;
insertion_point_y = y;
+ insertion_point_height = height;
}
#endif // __APPLE__