Author: manolo
Date: 2013-01-14 09:23:42 -0800 (Mon, 14 Jan 2013)
New Revision: 9794
Log:
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. 

Modified:
   branches/branch-3.0/include/fltk3/Widget.h
   branches/branch-3.0/include/fltk3/osx.h
   branches/branch-3.0/include/fltk3/run.h
   branches/branch-3.0/src/fltk3/Input.cxx
   branches/branch-3.0/src/fltk3/Input_.cxx
   branches/branch-3.0/src/fltk3/TextDisplay.cxx
   branches/branch-3.0/src/fltk3/TextEditor.cxx
   branches/branch-3.0/src/fltk3/cocoa.mm
   branches/branch-3.0/src/fltk3/compose.cxx

Modified: branches/branch-3.0/include/fltk3/Widget.h
===================================================================
--- branches/branch-3.0/include/fltk3/Widget.h  2013-01-14 09:07:34 UTC (rev 
9793)
+++ branches/branch-3.0/include/fltk3/Widget.h  2013-01-14 17:23:42 UTC (rev 
9794)
@@ -429,6 +429,7 @@
       NO_OVERLAY      = 1<<15,  ///< window not using a hardware overlay plane 
(fltk3::MenuWindow)
       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)
+      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)
       USERFLAG3       = 1<<29,  ///< reserved for 3rd party extensions
       USERFLAG2       = 1<<30,  ///< reserved for 3rd party extensions
@@ -1035,6 +1036,11 @@
      \see fltk3::Widget::as_group(), fltk3::Widget::as_window()
      */
     virtual fltk3::ShapedWindow* as_shaped_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; }
+    
   };
   
   

Modified: branches/branch-3.0/include/fltk3/osx.h
===================================================================
--- branches/branch-3.0/include/fltk3/osx.h     2013-01-14 09:07:34 UTC (rev 
9793)
+++ branches/branch-3.0/include/fltk3/osx.h     2013-01-14 17:23:42 UTC (rev 
9794)
@@ -146,7 +146,7 @@
   static void screen_work_area(int &X, int &Y, int &W, int &H, int n); // 
compute work area of a given screen
   static unsigned short *compute_macKeyLookUp();
   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:
   static void relink(fltk3::Window*, fltk3::Window*);
   bool subwindow;

Modified: branches/branch-3.0/include/fltk3/run.h
===================================================================
--- branches/branch-3.0/include/fltk3/run.h     2013-01-14 09:07:34 UTC (rev 
9793)
+++ branches/branch-3.0/include/fltk3/run.h     2013-01-14 17:23:42 UTC (rev 
9794)
@@ -155,7 +155,7 @@
 #ifdef __APPLE__
   int marked_text_length(); // returns length of marked text
   void reset_marked_text(); // resets marked text
-  void insertion_point_location(int x, int y); // sets window coordinates of 
insertion point
+  void insertion_point_location(int x, int y, int height); // sets window 
coordinates & height of insertion point
 #endif
 #endif
   /**

Modified: branches/branch-3.0/src/fltk3/Input.cxx
===================================================================
--- branches/branch-3.0/src/fltk3/Input.cxx     2013-01-14 09:07:34 UTC (rev 
9793)
+++ branches/branch-3.0/src/fltk3/Input.cxx     2013-01-14 17:23:42 UTC (rev 
9794)
@@ -810,12 +810,14 @@
 fltk3::FloatInput::FloatInput(int X,int Y,int W,int H,const char *l)
 : fltk3::NumericInput(X,Y,W,H,l) {
   type(fltk3::FLOAT_INPUT);
+  clear_flag(MAC_USE_ACCENTS_MENU);
 }
 
 
 fltk3::IntInput::IntInput(int X,int Y,int W,int H,const char *l)
 : fltk3::Input(X,Y,W,H,l) {
   type(fltk3::INT_INPUT);
+  clear_flag(MAC_USE_ACCENTS_MENU);
 }
 
 
@@ -840,6 +842,7 @@
 fltk3::SecretInput::SecretInput(int X,int Y,int W,int H,const char *l)
 : fltk3::Input(X,Y,W,H,l) {
   type(fltk3::SECRET_INPUT);
+  clear_flag(MAC_USE_ACCENTS_MENU);
 }
 
 int fltk3::SecretInput::handle(int event) {

Modified: branches/branch-3.0/src/fltk3/Input_.cxx
===================================================================
--- branches/branch-3.0/src/fltk3/Input_.cxx    2013-01-14 09:07:34 UTC (rev 
9793)
+++ branches/branch-3.0/src/fltk3/Input_.cxx    2013-01-14 17:23:42 UTC (rev 
9794)
@@ -400,6 +400,9 @@
       } else {
         fltk3::rectf((int)(xpos+curx+0.5), Y+ypos, 2, height);
       }
+#ifdef __APPLE__
+      fltk3::insertion_point_location(xpos+curx, Y+ypos+height, height);
+#endif
     }
 
   CONTINUE:
@@ -1149,6 +1152,7 @@
   maximum_size_ = 32767;
   shortcut_ = 0;
   set_flag(SHORTCUT_LABEL);
+  set_flag(MAC_USE_ACCENTS_MENU);
   tab_nav(1);
 }
 

Modified: branches/branch-3.0/src/fltk3/TextDisplay.cxx
===================================================================
--- branches/branch-3.0/src/fltk3/TextDisplay.cxx       2013-01-14 09:07:34 UTC 
(rev 9793)
+++ branches/branch-3.0/src/fltk3/TextDisplay.cxx       2013-01-14 17:23:42 UTC 
(rev 9794)
@@ -2076,6 +2076,10 @@
   
   if ( X < text_area.x - 1 || X > text_area.x + text_area.w )
     return;
+ 
+#ifdef __APPLE__
+  fltk3::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

Modified: branches/branch-3.0/src/fltk3/TextEditor.cxx
===================================================================
--- branches/branch-3.0/src/fltk3/TextEditor.cxx        2013-01-14 09:07:34 UTC 
(rev 9793)
+++ branches/branch-3.0/src/fltk3/TextEditor.cxx        2013-01-14 17:23:42 UTC 
(rev 9794)
@@ -82,6 +82,7 @@
   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);
@@ -538,12 +539,8 @@
     }
 #ifdef __APPLE__
     if (fltk3::marked_text_length()) {
-      int x, y;
       int pos = this->insert_position();
       this->buffer()->select(pos - fltk3::marked_text_length(), pos);
-      this->position_to_xy( this->insert_position(), &x, &y);
-      y += this->textsize();
-      fltk3::insertion_point_location(x, y);
     }
 #endif
     show_insert_position();

Modified: branches/branch-3.0/src/fltk3/cocoa.mm
===================================================================
--- branches/branch-3.0/src/fltk3/cocoa.mm      2013-01-14 09:07:34 UTC (rev 
9793)
+++ branches/branch-3.0/src/fltk3/cocoa.mm      2013-01-14 17:23:42 UTC (rev 
9794)
@@ -1645,11 +1645,15 @@
 }
 
 
-@interface FLView : NSView <NSTextInput> 
-{
+@interface FLView : NSView <NSTextInput
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+, NSTextInputClient
+#endif
+> {
   @private
   BOOL in_key_event;
   NSInteger identifier;
+  NSRange selectedRange;
 }
 + (void)prepareEtext:(NSString*)aString;
 - (id)init;
@@ -1928,27 +1932,36 @@
 }
 
 // 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=%@ fltk3::marked_text_length()=%d",received, 
fltk3::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();
+  fltk3::Window *target = [(FLWindow*)[self window] getFl_Window];
+  while (replacementRange.length--) { // delete replacementRange.length 
characters before insertion point
+    int saved_keysym = fltk3::e_keysym;
+    fltk3::e_keysym = fltk3::BackSpaceKey;
+    fltk3::handle(fltk3::KEYBOARD, target);
+    fltk3::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.
-  fltk3::Window *target = [(FLWindow*)[self window] getFl_Window];
   Fl_X::next_marked_length = 0;
   fltk3::handle( (in_key_event || fltk3::marked_text_length()) ? 
fltk3::KEYBOARD : fltk3::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!
   fltk3::flush();
@@ -1956,6 +1969,10 @@
 }
 
 - (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];
@@ -1963,14 +1980,21 @@
     received = (NSString*)aString;
   }
   fl_lock_function();
-  // This code creates the OS X behaviour of seeing dead keys as things
-  // are being composed.
+  /*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);*/
+  fltk3::Window *target = [(FLWindow*)[self window] getFl_Window];
+  while (replacementRange.length--) { // delete replacementRange.length 
characters before insertion point
+    fltk3::e_keysym = fltk3::BackSpaceKey;
+    fltk3::compose_state = 0;
+    Fl_X::next_marked_length = 0;
+    fltk3::handle(fltk3::KEYBOARD, target);
+    fltk3::e_keysym = 'a'; // pretend a letter key was hit
+  }
   [FLView prepareEtext:received];
-  /*NSLog(@"setMarkedText:%@ %d %d fltk3::marked_text_length()=%d 
fltk3::e_length=%d", 
-   received, newSelection.location, newSelection.length, 
fltk3::marked_text_length(), fltk3::e_length);*/
-  fltk3::Window *target = [(FLWindow*)[self window] getFl_Window];
   Fl_X::next_marked_length = fltk3::e_length;
   fltk3::handle(fltk3::KEYBOARD, target);
+  selectedRange = NSMakeRange(100, newSelection.length);
   fl_unlock_function();
 }
 
@@ -1982,6 +2006,8 @@
 }
 
 - (NSRange)selectedRange {
+  fltk3::Widget *w = fltk3::focus();
+  if (w && w->use_accents_menu()) return selectedRange;
   return NSMakeRange(NSNotFound, 0);
 }
 
@@ -1996,7 +2022,11 @@
 }
 
 - (NSAttributedString *)attributedSubstringFromRange:(NSRange)aRange {
-  //NSLog(@"attributedSubstringFromRange: %d 
%d",aRange.location,aRange.length);
+  return [self attributedSubstringForProposedRange:aRange actualRange:NULL];
+}
+
+- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange 
actualRange:(NSRangePointer)actualRange {
+  //NSLog(@"attributedSubstringForProposedRange: %d 
%d",aRange.location,aRange.length);
   return nil;
 }
 
@@ -2005,7 +2035,11 @@
 }
 
 - (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();
   fltk3::Widget *focus = fltk3::focus();
@@ -2013,15 +2047,16 @@
   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 {
     glyphRect.origin.x = 0;
     glyphRect.origin.y = focus->h();
+    height = 12;
   }
-  glyphRect.size.height = 12;
+  glyphRect.size.height = height;
   fltk3::Widget *win = focus;
   while (win != NULL && win != wfocus) {
     glyphRect.origin.x += win->x();
@@ -2031,6 +2066,7 @@
   // 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;
 }
@@ -2039,6 +2075,10 @@
   return 0;
 }
 
+- (NSInteger)windowLevel {
+  return [[self window] level];
+}
+
 - (NSInteger)conversationIdentifier {
   return identifier;
 }

Modified: branches/branch-3.0/src/fltk3/compose.cxx
===================================================================
--- branches/branch-3.0/src/fltk3/compose.cxx   2013-01-14 09:07:34 UTC (rev 
9793)
+++ branches/branch-3.0/src/fltk3/compose.cxx   2013-01-14 17:23:42 UTC (rev 
9794)
@@ -53,22 +53,27 @@
  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 fltk3::marked_text_length()</tt> <i>after</i> having called 
fltk3::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 fltk3::reset_marked_text()</tt> when 
processing FL_UNFOCUS events.
- Optionally, widgets can also call
- <tt>void fltk3::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 fltk3::reset_marked_text()</tt> when 
processing fltk3::UNFOCUS
+ events. Optionally, widgets can also call
+ <tt>void fltk3::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
- fltk3::Input and fltk3::TextEditor 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. 
+ fltk3::Input and fltk3::TextEditor 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
@@ -109,6 +114,7 @@
 
 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 fltk3::reset_marked_text() {
@@ -116,18 +122,20 @@
   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 fltk3::insertion_point_location(int x, int y) {
+void fltk3::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__
 

_______________________________________________
fltk-commit mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-commit

Reply via email to