Adding a TextAreaCursorXY
BlitzMax Forums/BlitzMax Module Tweaks/Adding a TextAreaCursorXY
| ||
This is a module tweak to get Cursor Screen/Client Position from the TextArea gadget, it does this by modding all maxgui modules and adding a TextAreaCursorXY() command to MaxGUI. ----------------------------------- WIN32: we start with modifying win32maxgui.mod in file win32gui/win32textarea.h at line 44 add: int cursorXY( int *x, int *y, int clientpos); in file win32gui/win32textarea2.cpp at line 324 add: int Win32TextArea::cursorXY( int *x, int *y, int clientpos) { POINT p; RECT rect; int inside = 1; GetCaretPos( &p); *x = p.x; *y = p.y; if( clientpos) return 1; // clip to gadget size GetWindowRect( _gadget.hwnd(), &rect); ClientToScreen( _gadget.hwnd(), &p); *x = p.x; *y = p.y; if( *x > rect.right) { *x = rect.right; inside = 0; } if( *y < rect.top) { *y = rect.top; inside = 0; } else if( *y > rect.bottom) { *y = rect.bottom; inside = 0; } return inside; } in file gui/textarea.h at line 30 add: virtual int cursorXY( int *x, int *y, int clientpos)=0; in file gui/textarea.h at line 58 add: int bbTextAreaCursorXY( BBTextArea *t, int *x, int *y, int clientpos); in file gui/textarea.cpp at line 41 add: int bbTextAreaCursorXY( BBTextArea *t, int *x, int *y, int clientpos) { t->debug(); return t->cursorXY( x,y, clientpos); } in file win32gui.bmx at line 211 add: Function bbTextAreaCursorXY( textarea, x Var, y Var, clientpos=False) in file win32gui.bmx at line 851 add: Method GetCursorXY( x Var, y Var, clientpos=False) Return bbTextAreaCursorXY( handle, x,y, clientpos) EndMethod ----------------------------------------------- LINUX: now on to modifying fltkmaxgui.mod We have to modify FLTK itself (only one tiny bit) for this to work. in file fltkglue.cpp at line 180 add: int flGetCursorXY( Fl_TextEditor *edit, int *x, int *y, int clientpos); in file fltkglue.cpp at line 1291 add: int flGetCursorXY( Fl_Text_Editor *edit, int *x, int *y, int clientpos) { int start, endpos, pos; Fl_Text_Buffer *buff; Fl_Group *n; buff = edit->buffer(); buff->selection_position( &start, &endpos); if( endpos > start) pos = ((Fl_Text_Display*)edit)->position_to_xy( start, x,y); else pos = ((Fl_Text_Display*)edit)->position_to_xy( edit->insert_position(), x,y); // clip to gadget size if( pos == 0) *y = edit->h(); else if( pos > 1) *x = pos; if( clientpos) return 1; // get screen coords n = edit; while( n) { *x += n->x(); *y += n->y(); n = n->parent(); } return (pos == 1); } in file fltkimports.bmx at line 312 add: Function flGetCursorXY( editor, x Var, y Var, clientpos=False) in file fltkgui.bmx at line 1727 add: Method GetCursorXY( x:Int Var, y:Int Var, clientpos=False) If fltype <> FL_TEXTEDITOR Then Return False Return flGetCursorXY( flhandle, x, y, clientpos) EndMethod in file FL/Fl_Text_Display.h at line 89 move this to line 134: (making it public so we can call it) int position_to_xy(int pos, int* x, int* y); ----------------------------------- MACOSX: on to brl.cocoamaxgui This needed a small fix, it seems the screen position firstRectFromCharacterRange returns 32 pixels too much (???) in file cocoa.macos.m at line 3064 add: int NSGetCursorXY( nsgadget *gadget, int *x, int *y, int clientpos) { TextView *textarea; NSRange range; NSRect rect; nsgadget *n; int xx=0,yy=0,inside=1; NSRect drect; drect=[[NSScreen deepestScreen] frame]; textarea=(TextView*)gadget->handle; range=[textarea rangeForUserTextChange]; rect=[textarea firstRectForCharacterRange: range]; *x = (int)rect.origin.x; *y = (int)drect.size.height; // set screen height, since we have to un-reverse y *y -= ((int)rect.origin.y) + 32; // fix: since its 32 pixels more than it should be, maybe its the menubar? // get screen position n = gadget; while( n) { xx += n->x; yy += n->y; n = n->group; } if( clientpos) { *x -= xx; *y -= yy; return 1; } // clip to gadget size if( *x > xx + gadget->w) { *x = xx + gadget->w; inside = 0; } if( *y < yy) { *y = yy; inside = 0; } else if( *y > yy + gadget->h) { *y = yy + gadget->h; inside = 0; } return inside; } in file cocoagui.bmx at line 66 add: Function NSGetCursorXY( gadget:TNSGadget, x Var, y Var, clientpos) in file cocoagui.bmx at line 603 add: Method GetCursorXY( x Var, y Var, clientpos=False) Return NSGetCursorXY( Self, x,y, clientpos) EndMethod ----------------------------------------------- MAXGUI: now we add the new command to maxgui.mod in file gadget.bmx at line 511 add: Method GetCursorXY( x Var, y Var, clientpos=False) EndMethod in file gadget.bmx at line 686 add: Method GetCursorXY( x Var, y Var, clientpos=False) Return proxy.GetCursorXY( x,y, clientpos) EndMethod in file maxgui.bmx at line 1012 replace with: See Also: #TextAreaSelLen , #TextAreaCursorXY and #CreateTextArea in file maxgui.bmx at line 1017 add: Rem bbdoc: Find the Screen or Client X,Y coordinates of the cursor in a TextArea gadget. about: Depending on @clientpos returns either Client or Screen position in @x and @y. Returns True if the cursor is visible in the gadget. Returns False if the cursor is hidden either vertically or horizontally, and clips the coordinates to the size of the gadget. <p> See Also: #TextAreaCursor and #CreateTextArea EndRem Function TextAreaCursorXY( textarea:TGadget, x:Int Var, y:Int Var, clientpos:Int=False) Return textarea.GetCursorXY( x,y, clientpos) EndFunction |
| ||
For reference, here are the FLTK (position_to_x_y) and cocoa (firstRectForCharacterRange) links. http://www.koders.com/cpp/fid7B10F36EE0B19A371A61464601DEF25D56B6C6BE.aspx#L543 http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Protocols/NSTextInput_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/NSTextInput/firstRectForCharacterRange: Go grable! BD Oh, and Brucey, if yer watching, I'm sure there's a gtk version out there... ;-) |
| ||
Well, got it working on linux by modifying FLTK little bit. Gonna look into the mac code.. but as i cant test it (i have no mac) it isnt looking bright. |
| ||
Did some code for the mac part, but havent been able to test it. someone up for it? Allso made it return Client or Screen coords depending on third parameter |
| ||
Got MacOSX x86 working in a vm so now that part works as well, Yay! Fully cross-platform with only 1 minor tweak to FLTK, i dont think thats too bad. So how about it BRL ? ;) If your wondering what i want it for, its fully cross-platform AutoComplete window for the MaxIDE-CE! |
| ||
The tweak to make the fltk method public instead of private is odd. It looks like fltk2 definitely makes it public *here*, it's just not exposed in fltk1.1. Skid, what are your thoughts on adding this mod? |