Mac OS: added support for the text input feature introduced in OS 10.7 "Lion" where pressing and holding
some key opens a window with possible accented characters. This feature is used by the Fl_Input_ and Fl_Text_Editor widgets. User-defined text input widgets can optionally use this feature, but the default behavior is to not use it. Fl_Secret_Input turns it off, for example. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@9792 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
e042966ae7
commit
482c4a5e0a
2
FL/Fl.H
2
FL/Fl.H
@ -147,7 +147,7 @@ public: // should be private!
|
|||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
static int marked_text_length(void); // returns length of marked text
|
static int marked_text_length(void); // returns length of marked text
|
||||||
static void reset_marked_text(); // resets marked text
|
static void reset_marked_text(); // resets marked text
|
||||||
static void insertion_point_location(int x, int y); // sets window coordinates of insertion point
|
static void insertion_point_location(int x, int y, int height); // sets window coordinates & height of insertion point
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
/**
|
/**
|
||||||
|
@ -171,6 +171,7 @@ protected:
|
|||||||
GROUP_RELATIVE = 1<<16, ///< position this widget relative to the parent group, not to the window
|
GROUP_RELATIVE = 1<<16, ///< position this widget relative to the parent group, not to the window
|
||||||
COPIED_TOOLTIP = 1<<17, ///< the widget tooltip is internally copied, its destruction is handled by the widget
|
COPIED_TOOLTIP = 1<<17, ///< the widget tooltip is internally copied, its destruction is handled by the widget
|
||||||
FULLSCREEN = 1<<18, ///< a fullscreen window (Fl_Window)
|
FULLSCREEN = 1<<18, ///< a fullscreen window (Fl_Window)
|
||||||
|
MAC_USE_ACCENTS_MENU = 1<<19, ///< On the Mac OS platform, pressing and holding a key on the keyboard opens an accented-character menu window (Fl_Input_, Fl_Text_Editor)
|
||||||
// (space for more flags)
|
// (space for more flags)
|
||||||
USERFLAG3 = 1<<29, ///< reserved for 3rd party extensions
|
USERFLAG3 = 1<<29, ///< reserved for 3rd party extensions
|
||||||
USERFLAG2 = 1<<30, ///< reserved for 3rd party extensions
|
USERFLAG2 = 1<<30, ///< reserved for 3rd party extensions
|
||||||
@ -976,6 +977,10 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual class Fl_Gl_Window* as_gl_window() {return 0;}
|
virtual class Fl_Gl_Window* as_gl_window() {return 0;}
|
||||||
|
|
||||||
|
/** Returns non zero if MAC_USE_ACCENTS_MENU flag is set, 0 otherwise.
|
||||||
|
*/
|
||||||
|
int use_accents_menu() { return flags() & MAC_USE_ACCENTS_MENU; }
|
||||||
|
|
||||||
/** For back compatibility only.
|
/** For back compatibility only.
|
||||||
\deprecated Use selection_color() instead.
|
\deprecated Use selection_color() instead.
|
||||||
*/
|
*/
|
||||||
|
2
FL/mac.H
2
FL/mac.H
@ -132,7 +132,7 @@ public:
|
|||||||
static void *get_carbon_function(const char *name);
|
static void *get_carbon_function(const char *name);
|
||||||
static void screen_work_area(int &X, int &Y, int &W, int &H, int n); // compute work area of a given screen
|
static void screen_work_area(int &X, int &Y, int &W, int &H, int n); // compute work area of a given screen
|
||||||
static int next_marked_length; // next length of marked text after current marked text will have been replaced
|
static int next_marked_length; // next length of marked text after current marked text will have been replaced
|
||||||
static int insertion_point_location(int *px, int *py); // computes window coordinates of insertion point
|
static int insertion_point_location(int *px, int *py, int *pheight); // computes window coordinates & height of insertion point
|
||||||
private:
|
private:
|
||||||
static void relink(Fl_Window*, Fl_Window*);
|
static void relink(Fl_Window*, Fl_Window*);
|
||||||
bool subwindow;
|
bool subwindow;
|
||||||
|
@ -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)
|
: Fl_Input(X,Y,W,H,l)
|
||||||
{
|
{
|
||||||
type(FL_FLOAT_INPUT);
|
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_Int_Input::Fl_Int_Input(int X,int Y,int W,int H,const char *l)
|
||||||
: Fl_Input(X,Y,W,H,l) {
|
: Fl_Input(X,Y,W,H,l) {
|
||||||
type(FL_INT_INPUT);
|
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_Secret_Input::Fl_Secret_Input(int X,int Y,int W,int H,const char *l)
|
||||||
: Fl_Input(X,Y,W,H,l) {
|
: Fl_Input(X,Y,W,H,l) {
|
||||||
type(FL_SECRET_INPUT);
|
type(FL_SECRET_INPUT);
|
||||||
|
clear_flag(MAC_USE_ACCENTS_MENU);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Fl_Secret_Input::handle(int event) {
|
int Fl_Secret_Input::handle(int event) {
|
||||||
|
@ -388,6 +388,9 @@ void Fl_Input_::drawtext(int X, int Y, int W, int H) {
|
|||||||
} else {
|
} else {
|
||||||
fl_rectf((int)(xpos+curx+0.5), Y+ypos, 2, height);
|
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:
|
CONTINUE:
|
||||||
@ -1119,6 +1122,7 @@ Fl_Input_::Fl_Input_(int X, int Y, int W, int H, const char* l)
|
|||||||
maximum_size_ = 32767;
|
maximum_size_ = 32767;
|
||||||
shortcut_ = 0;
|
shortcut_ = 0;
|
||||||
set_flag(SHORTCUT_LABEL);
|
set_flag(SHORTCUT_LABEL);
|
||||||
|
set_flag(MAC_USE_ACCENTS_MENU);
|
||||||
tab_nav(1);
|
tab_nav(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 )
|
if ( X < text_area.x - 1 || X > text_area.x + text_area.w )
|
||||||
return;
|
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
|
/* 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
|
width, rounded to an even number of pixels so that X will draw an
|
||||||
odd number centered on the stem at x. */
|
odd number centered on the stem at x. */
|
||||||
|
@ -73,6 +73,7 @@ Fl_Text_Editor::Fl_Text_Editor(int X, int Y, int W, int H, const char* l)
|
|||||||
mCursorOn = 1;
|
mCursorOn = 1;
|
||||||
insert_mode_ = 1;
|
insert_mode_ = 1;
|
||||||
key_bindings = 0;
|
key_bindings = 0;
|
||||||
|
set_flag(MAC_USE_ACCENTS_MENU);
|
||||||
|
|
||||||
// handle the default key bindings
|
// handle the default key bindings
|
||||||
add_default_key_bindings(&key_bindings);
|
add_default_key_bindings(&key_bindings);
|
||||||
@ -526,12 +527,8 @@ int Fl_Text_Editor::handle_key() {
|
|||||||
}
|
}
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
if (Fl::marked_text_length()) {
|
if (Fl::marked_text_length()) {
|
||||||
int x, y;
|
|
||||||
int pos = this->insert_position();
|
int pos = this->insert_position();
|
||||||
this->buffer()->select(pos - Fl::marked_text_length(), pos);
|
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
|
#endif
|
||||||
show_insert_position();
|
show_insert_position();
|
||||||
|
@ -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;
|
BOOL in_key_event;
|
||||||
NSInteger identifier;
|
NSInteger identifier;
|
||||||
|
NSRange selectedRange;
|
||||||
}
|
}
|
||||||
+ (void)prepareEtext:(NSString*)aString;
|
+ (void)prepareEtext:(NSString*)aString;
|
||||||
- (id)init;
|
- (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.
|
// 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)doCommandBySelector:(SEL)aSelector {
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)insertText:(id)aString {
|
- (void)insertText:(id)aString {
|
||||||
|
[self insertText:aString replacementRange:NSMakeRange(NSNotFound, 0)];
|
||||||
|
}
|
||||||
|
- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange {
|
||||||
NSString *received;
|
NSString *received;
|
||||||
if ([aString isKindOfClass:[NSAttributedString class]]) {
|
if ([aString isKindOfClass:[NSAttributedString class]]) {
|
||||||
received = [(NSAttributedString*)aString string];
|
received = [(NSAttributedString*)aString string];
|
||||||
} else {
|
} else {
|
||||||
received = (NSString*)aString;
|
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_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];
|
[FLView prepareEtext:received];
|
||||||
// We can get called outside of key events (e.g., from the character palette, from CJK text input).
|
// 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.
|
// Transform character palette actions to FL_PASTE events.
|
||||||
Fl_Window *target = [(FLWindow*)[self window] getFl_Window];
|
|
||||||
Fl_X::next_marked_length = 0;
|
Fl_X::next_marked_length = 0;
|
||||||
Fl::handle( (in_key_event || Fl::marked_text_length()) ? FL_KEYBOARD : FL_PASTE, target);
|
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
|
// 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!
|
// sending a 'redraw()' or 'awake()' does not solve the issue!
|
||||||
Fl::flush();
|
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 {
|
- (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;
|
NSString *received;
|
||||||
if ([aString isKindOfClass:[NSAttributedString class]]) {
|
if ([aString isKindOfClass:[NSAttributedString class]]) {
|
||||||
received = [(NSAttributedString*)aString string];
|
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;
|
received = (NSString*)aString;
|
||||||
}
|
}
|
||||||
fl_lock_function();
|
fl_lock_function();
|
||||||
// This code creates the OS X behaviour of seeing dead keys as things
|
/*NSLog(@"setMarkedText:%@ l=%d newSelection=%d,%d Fl::marked_text_length()=%d replacement=%d,%d",
|
||||||
// are being composed.
|
received, strlen([received UTF8String]), newSelection.location, newSelection.length, Fl::marked_text_length(),
|
||||||
[FLView prepareEtext:received];
|
replacementRange.location, replacementRange.length);*/
|
||||||
/*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);*/
|
|
||||||
Fl_Window *target = [(FLWindow*)[self window] getFl_Window];
|
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_X::next_marked_length = Fl::e_length;
|
||||||
Fl::handle(FL_KEYBOARD, target);
|
Fl::handle(FL_KEYBOARD, target);
|
||||||
|
selectedRange = NSMakeRange(100, newSelection.length);
|
||||||
fl_unlock_function();
|
fl_unlock_function();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2004,6 +2026,8 @@ static void q_set_window_title(NSWindow *nsw, const char * name, const char *mi
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (NSRange)selectedRange {
|
- (NSRange)selectedRange {
|
||||||
|
Fl_Widget *w = Fl::focus();
|
||||||
|
if (w && w->use_accents_menu()) return selectedRange;
|
||||||
return NSMakeRange(NSNotFound, 0);
|
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 {
|
- (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);
|
//NSLog(@"attributedSubstringFromRange: %d %d",aRange.location,aRange.length);
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
@ -2027,7 +2054,10 @@ static void q_set_window_title(NSWindow *nsw, const char * name, const char *mi
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (NSRect)firstRectForCharacterRange:(NSRange)aRange {
|
- (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;
|
NSRect glyphRect;
|
||||||
fl_lock_function();
|
fl_lock_function();
|
||||||
Fl_Widget *focus = Fl::focus();
|
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;
|
if (!focus) focus = wfocus;
|
||||||
glyphRect.size.width = 0;
|
glyphRect.size.width = 0;
|
||||||
|
|
||||||
int x, y;
|
int x, y, height;
|
||||||
if (Fl_X::insertion_point_location(&x, &y)) {
|
if (Fl_X::insertion_point_location(&x, &y, &height)) {
|
||||||
glyphRect.origin.x = (CGFloat)x;
|
glyphRect.origin.x = (CGFloat)x;
|
||||||
glyphRect.origin.y = (CGFloat)y;
|
glyphRect.origin.y = (CGFloat)y;
|
||||||
} else {
|
} 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.x = focus->x();
|
||||||
glyphRect.origin.y = focus->y() + focus->h();
|
glyphRect.origin.y = focus->y() + focus->h();
|
||||||
}
|
}
|
||||||
|
height = 12;
|
||||||
}
|
}
|
||||||
glyphRect.size.height = 12;
|
glyphRect.size.height = height;
|
||||||
Fl_Window *win = focus->as_window();
|
Fl_Window *win = focus->as_window();
|
||||||
if (!win) win = focus->window();
|
if (!win) win = focus->window();
|
||||||
while (win != NULL && win != wfocus) {
|
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
|
// Convert the rect to screen coordinates
|
||||||
glyphRect.origin.y = wfocus->h() - glyphRect.origin.y;
|
glyphRect.origin.y = wfocus->h() - glyphRect.origin.y;
|
||||||
glyphRect.origin = [[self window] convertBaseToScreen:glyphRect.origin];
|
glyphRect.origin = [[self window] convertBaseToScreen:glyphRect.origin];
|
||||||
|
if (actualRange) *actualRange = aRange;
|
||||||
fl_unlock_function();
|
fl_unlock_function();
|
||||||
return glyphRect;
|
return glyphRect;
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,12 @@
|
|||||||
// http://www.fltk.org/str.php
|
// http://www.fltk.org/str.php
|
||||||
//
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
\file Fl_compose.cxx
|
||||||
|
Utility functions to support text input.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <FL/Fl.H>
|
#include <FL/Fl.H>
|
||||||
#include <FL/x.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
|
keys, and del is set to zero. You could insert the text anyways, if
|
||||||
you don't know what else to do.
|
you don't know what else to do.
|
||||||
|
|
||||||
<p>On the Mac OS platform, text editing widgets should preferentially signal
|
<p>On the Mac OS platform, text input can involve marked text, that is,
|
||||||
marked text, that is, temporary text replaced by other text during the text
|
temporary text replaced by other text during the input process. This occurs,
|
||||||
input process. Such signaling is usually done underlining marked text. Widgets can call
|
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&)
|
<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
|
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.
|
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.
|
Widgets should also call <tt>void Fl::reset_marked_text()</tt> when processing FL_UNFOCUS
|
||||||
Optionally, widgets can also call
|
events. Optionally, widgets can also call
|
||||||
<tt>void Fl::insertion_point_location(int x, int y)</tt> to indicate the window
|
<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.
|
coordinates of the bottom of the current insertion point and the line height.
|
||||||
This way, auxiliary windows that help choosing among alternative characters
|
This way, auxiliary windows that help choosing among alternative characters
|
||||||
appear just below the insertion point. If widgets don't do that,
|
appear just below the insertion point. If widgets don't do that,
|
||||||
auxiliary windows appear at the widget's bottom. The
|
auxiliary windows appear at the widget's bottom. The
|
||||||
Fl_Input and Fl_Text_Editor widgets signal marked text underlining it.
|
Fl_Input and Fl_Text_Editor widgets underline marked text.
|
||||||
If none of this is done by a user-defined text editing widget, complex
|
If none of this is done by a user-defined text editing widget,
|
||||||
(e.g., CJK) text input will work, but will not signal to the user what text is marked.
|
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
|
<p>Though the current implementation returns immediately, future
|
||||||
versions may take quite awhile, as they may pop up a window or do
|
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_x = 0;
|
||||||
static int insertion_point_y = 0;
|
static int insertion_point_y = 0;
|
||||||
|
static int insertion_point_height = 0;
|
||||||
static bool insertion_point_location_is_valid = false;
|
static bool insertion_point_location_is_valid = false;
|
||||||
|
|
||||||
void Fl::reset_marked_text() {
|
void Fl::reset_marked_text() {
|
||||||
@ -107,18 +119,20 @@ void Fl::reset_marked_text() {
|
|||||||
Fl_X::next_marked_length = 0;
|
Fl_X::next_marked_length = 0;
|
||||||
insertion_point_location_is_valid = false;
|
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
|
// return true if the current coordinates of the insertion point are available
|
||||||
{
|
{
|
||||||
if ( ! insertion_point_location_is_valid ) return false;
|
if ( ! insertion_point_location_is_valid ) return false;
|
||||||
*px = insertion_point_x;
|
*px = insertion_point_x;
|
||||||
*py = insertion_point_y;
|
*py = insertion_point_y;
|
||||||
|
*pheight = insertion_point_height;
|
||||||
return true;
|
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_location_is_valid = true;
|
||||||
insertion_point_x = x;
|
insertion_point_x = x;
|
||||||
insertion_point_y = y;
|
insertion_point_y = y;
|
||||||
|
insertion_point_height = height;
|
||||||
}
|
}
|
||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user