mirror of
https://github.com/fltk/fltk.git
synced 2026-06-01 14:52:46 +08:00
Re-organize cross-platform support for text input methods.
FLTK 1.3 supports complex text input methods (TIMs) for the 3 platforms (X11, Windows, macOS). This support has an interface with FLTK that is common for X11 and Windows, via (undocumented) functions fl_set_spot(), fl_set_status() and fl_reset_spot(). In contrast, and because it's been developed independently, the interface between the macOS TIM and FLTK 1.3 is completely different : static functions FL::insertion_point_location() and Fl::reset_marked_text(). The present change implements a single TIM/FLTK interface used by all platforms based on functions fl_set_spot() and fl_reset_spot(). The previous macOS-specific functions FL::insertion_point_location() and Fl::reset_marked_text() are maintained only for compatibility with 1.3 and deprecated.
This commit is contained in:
@@ -146,8 +146,11 @@ public:
|
||||
|
||||
static Fl_Screen_Driver *screen_driver();
|
||||
static Fl_System_Driver *system_driver();
|
||||
static void reset_marked_text(); // resets marked text
|
||||
static void insertion_point_location(int x, int y, int height); // sets window coordinates & height of insertion point
|
||||
#ifdef __APPLE__ // deprecated in 1.4 - only for compatibility with 1.3
|
||||
static void reset_marked_text();
|
||||
static void insertion_point_location(int x, int y, int height);
|
||||
#endif
|
||||
|
||||
|
||||
/** Get the box shadow width of all "shadow" boxtypes in pixels.
|
||||
\since 1.4.0
|
||||
|
||||
+18
-2
@@ -1076,9 +1076,25 @@ FL_EXPORT const char *fl_expand_text(const char *from, char *buf, int maxbuf, do
|
||||
// XIM:
|
||||
/** \todo provide user documentation for fl_set_status function */
|
||||
FL_EXPORT void fl_set_status(int X, int Y, int W, int H);
|
||||
/** \todo provide user documentation for fl_set_spot function */
|
||||
/** Inform text input methods about the current text insertion cursor.
|
||||
\param font Font currently in use in text input.
|
||||
\param size Size of the current font.
|
||||
\param X,Y Position of the bottom of the current text insertion cursor.
|
||||
\param W,H Width and height of the current text insertion cursor.
|
||||
\param win Points to the Fl_Window object containing the current text widget, or NULL.
|
||||
*/
|
||||
FL_EXPORT void fl_set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win = 0);
|
||||
/** \todo provide user documentation for fl_reset_spot function*/
|
||||
/** Resets marked text.
|
||||
|
||||
In many languages, typing a character can involve multiple keystrokes. For
|
||||
example, the Ä can be composed of two dots (¨) on top of the
|
||||
character, followed by the letter A (on a Mac with U.S. keyboard, you'd
|
||||
type Alt-U, Shift-A. To inform the user that the dots may be followed by
|
||||
another character, the ¨ is underlined).
|
||||
|
||||
Call this function if character composition needs to be aborted for some
|
||||
reason. One such example would be the text input widget losing focus.
|
||||
*/
|
||||
FL_EXPORT void fl_reset_spot(void);
|
||||
|
||||
|
||||
|
||||
-25
@@ -1885,31 +1885,6 @@ int Fl::dnd()
|
||||
return Fl::screen_driver()->dnd();
|
||||
}
|
||||
|
||||
/**
|
||||
Resets marked text.
|
||||
|
||||
In many languages, typing a character can involve multiple keystrokes. For
|
||||
example, the Ä can be composed of two dots (¨) on top of the
|
||||
character, followed by the letter A (on a Mac with U.S. keyboard, you'd
|
||||
type Alt-U, Shift-A. To inform the user that the dots may be followed by
|
||||
another character, the ¨ is underlined).
|
||||
|
||||
Call this function if character composition needs to be aborted for some
|
||||
reason. One such example would be the text input widget losing focus.
|
||||
*/
|
||||
void Fl::reset_marked_text() {
|
||||
Fl::screen_driver()->reset_marked_text();
|
||||
}
|
||||
|
||||
/**
|
||||
Sets window coordinates and height of insertion point.
|
||||
|
||||
\see Fl::compose(int& del) for a detailed description.
|
||||
*/
|
||||
void Fl::insertion_point_location(int x, int y, int height) {
|
||||
Fl::screen_driver()->insertion_point_location(x, y, height);
|
||||
}
|
||||
|
||||
int Fl::event_key(int k) {
|
||||
return system_driver()->event_key(k);
|
||||
}
|
||||
|
||||
+1
-1
@@ -469,7 +469,7 @@ int Fl_Input::handle(int event) {
|
||||
case FL_UNFOCUS:
|
||||
if (Fl::screen_driver()->has_marked_text() && Fl::compose_state) {
|
||||
this->mark( this->position() );
|
||||
Fl::reset_marked_text();
|
||||
fl_reset_spot();
|
||||
}
|
||||
break;
|
||||
case FL_FOCUS:
|
||||
|
||||
@@ -377,7 +377,6 @@ void Fl_Input_::drawtext(int X, int Y, int W, int H) {
|
||||
} else {
|
||||
fl_rectf((int)(xpos+curx+0.5), Y+ypos, 2, height);
|
||||
}
|
||||
Fl::insertion_point_location((int)xpos+curx, Y+ypos+height, height);
|
||||
ypos_cur = ypos+height; //fix issue #270
|
||||
}
|
||||
|
||||
|
||||
@@ -122,12 +122,9 @@ public:
|
||||
|
||||
static int secret_input_character;
|
||||
/* Implement to indicate whether complex text input may involve marked text.
|
||||
When it does, has_marked_text returns non zero and reset_marked_text() and
|
||||
insertion_point_location() must also be implemented.
|
||||
When it does, has_marked_text returns non zero.
|
||||
*/
|
||||
virtual int has_marked_text() const { return 0; }
|
||||
virtual void reset_marked_text() {}
|
||||
virtual void insertion_point_location(int /*x*/, int /*y*/, int /*height*/) {}
|
||||
// implement so text-editing widgets support dead keys
|
||||
virtual int compose(int &del) {
|
||||
del = 0;
|
||||
|
||||
@@ -2424,7 +2424,6 @@ void Fl_Text_Display::draw_cursor( int X, int Y ) {
|
||||
if ( X < text_area.x - 1 || X > text_area.x + text_area.w )
|
||||
return;
|
||||
|
||||
Fl::insertion_point_location(X, bot, fontHeight);
|
||||
/* 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. */
|
||||
|
||||
@@ -670,9 +670,10 @@ int Fl_Text_Editor::handle(int event) {
|
||||
if (Fl::screen_driver()->has_marked_text() && buffer()->selected() && Fl::compose_state) {
|
||||
int pos = insert_position();
|
||||
buffer()->select(pos, pos);
|
||||
Fl::reset_marked_text();
|
||||
fl_reset_spot();
|
||||
}
|
||||
if (buffer()->selected()) redraw(); // Redraw selections...
|
||||
// FALLTHROUGH
|
||||
case FL_HIDE:
|
||||
if (when() & FL_WHEN_RELEASE) maybe_do_callback();
|
||||
return 1;
|
||||
|
||||
+11
-2
@@ -2674,7 +2674,7 @@ static FLTextInputContext* fltextinputcontext_instance = nil;
|
||||
|
||||
- (void)unmarkText {
|
||||
fl_lock_function();
|
||||
Fl::reset_marked_text();
|
||||
Fl_Cocoa_Screen_Driver::reset_marked_text();
|
||||
fl_unlock_function();
|
||||
//NSLog(@"unmarkText");
|
||||
}
|
||||
@@ -2720,7 +2720,7 @@ static FLTextInputContext* fltextinputcontext_instance = nil;
|
||||
glyphRect.size.width = 0;
|
||||
|
||||
int x, y, height;
|
||||
if (((Fl_Cocoa_Screen_Driver*)Fl::screen_driver())->insertion_point_location(&x, &y, &height)) {
|
||||
if (Fl_Cocoa_Screen_Driver::insertion_point_location(&x, &y, &height)) {
|
||||
glyphRect.origin.x = (CGFloat)x;
|
||||
glyphRect.origin.y = (CGFloat)y;
|
||||
} else {
|
||||
@@ -4624,3 +4624,12 @@ void Fl_Cocoa_Screen_Driver::default_icons(const Fl_RGB_Image *icons[], int coun
|
||||
default_icon = rgb_to_nsimage(icons[0]);
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated in 1.4 - only for backward compatibility with 1.3
|
||||
void Fl::insertion_point_location(int x, int y, int height) {
|
||||
Fl_Cocoa_Screen_Driver::insertion_point_location(x, y, height);
|
||||
}
|
||||
// Deprecated in 1.4 - only for backward compatibility with 1.3
|
||||
void Fl::reset_marked_text() {
|
||||
Fl_Cocoa_Screen_Driver::reset_marked_text();
|
||||
}
|
||||
|
||||
+19
-16
@@ -40,32 +40,35 @@ int Fl::compose_state = 0;
|
||||
<p>If <i>false</i> is returned, the keys should be treated as function
|
||||
keys, and del is set to zero. You could insert the text anyways, if
|
||||
you don't know what else to do.
|
||||
|
||||
<p>Text editing widgets can preferentially call fl_set_spot() 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
|
||||
with some text input methods appear just below or above the insertion point.
|
||||
If widgets don't do that, such auxiliary windows appear at the widget's bottom.
|
||||
|
||||
<p>On the Mac OS platform, text input can involve marked text, that is,
|
||||
<p>On some platforms, 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.
|
||||
e.g., under macOS when using dead keys or when entering CJK characters.
|
||||
Text editing widgets should preferentially signal
|
||||
marked text, usually underlining it. Widgets can use
|
||||
<tt>int Fl::compose_state</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. 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 underline marked text.
|
||||
void fl_reset_spot() when processing FL_UNFOCUS
|
||||
events. The 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 certain keys 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
|
||||
other user-interface things to allow characters to be selected.
|
||||
<p>Finally, text editing widgets should call <tt>set_flag(MAC_USE_ACCENTS_MENU);</tt>
|
||||
in their constructor if they want to use, on the macOS platform, the feature introduced with Mac OS 10.7 "Lion"
|
||||
where pressing and holding certain keys on the keyboard opens a diacritic marks popup window.
|
||||
|
||||
\note For compatibility with FLTK 1.3, text editing widgets can call
|
||||
<tt>Fl::insertion_point_location(int x, int y, int height)</tt> and <tt>Fl::reset_marked_text()</tt>
|
||||
<u>only under the macOS platform</u> to indicate/reset the coordinates of the current insertion point.
|
||||
This is deprecated in version 1.4 because redundant with the platform-independent
|
||||
fl_set_spot() and fl_reset_spot() functions.
|
||||
*/
|
||||
int Fl::compose(int& del) {
|
||||
return Fl::screen_driver()->compose(del);
|
||||
|
||||
@@ -86,9 +86,9 @@ public:
|
||||
virtual int has_timeout(Fl_Timeout_Handler cb, void *argp);
|
||||
virtual void remove_timeout(Fl_Timeout_Handler cb, void *argp);
|
||||
virtual int has_marked_text() const;
|
||||
virtual void reset_marked_text();
|
||||
virtual void insertion_point_location(int x, int y, int height);
|
||||
int insertion_point_location(int *px, int *py, int *pheight);
|
||||
static void reset_marked_text();
|
||||
static void insertion_point_location(int x, int y, int height);
|
||||
static int insertion_point_location(int *px, int *py, int *pheight);
|
||||
virtual int dnd(int use_selection);
|
||||
virtual int compose(int &del);
|
||||
virtual int input_widget_handle_key(int key, unsigned mods, unsigned shift, Fl_Input *input);
|
||||
|
||||
@@ -174,6 +174,8 @@ protected:
|
||||
virtual void restore_scale(float);
|
||||
virtual void antialias(int state);
|
||||
virtual int antialias();
|
||||
virtual void set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win);
|
||||
virtual void reset_spot();
|
||||
};
|
||||
|
||||
class Fl_Quartz_Printer_Graphics_Driver : public Fl_Quartz_Graphics_Driver {
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include <config.h>
|
||||
#include "Fl_Quartz_Graphics_Driver.H"
|
||||
#include "../Darwin/Fl_Darwin_System_Driver.H"
|
||||
#include "../../Fl_Screen_Driver.H"
|
||||
#include "../Cocoa/Fl_Cocoa_Screen_Driver.H"
|
||||
#include <FL/platform.H>
|
||||
#include <FL/fl_draw.H>
|
||||
#include <FL/Fl_Image_Surface.H>
|
||||
@@ -182,3 +182,11 @@ void Fl_Quartz_Graphics_Driver::restore_scale(float s) {
|
||||
CGContextScaleCTM(gc_, s, s);
|
||||
}
|
||||
}
|
||||
|
||||
void Fl_Quartz_Graphics_Driver::set_spot(int /*font*/, int size, int X, int Y, int /*W*/, int /*H*/, Fl_Window* /*win*/) {
|
||||
Fl_Cocoa_Screen_Driver::insertion_point_location(X, Y, size);
|
||||
}
|
||||
|
||||
void Fl_Quartz_Graphics_Driver::reset_spot() {
|
||||
Fl_Cocoa_Screen_Driver::reset_marked_text();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user