// FV_Cursor.h /* Part of the AbiWord. * * Author: Mikael Nordell (tamlin@algonet.se) * !!! Not yet released for public consumption!!! * !!! Don NOT CVS commit this !!! * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ #ifndef FV_CURSOR_H #define FV_CURSOR_H #include "ut_types.h" #include "pt_types.h" // fwd. decl. class FV_View; class fp_Line; class fp_Run; class UT_Timer; class FL_DocLayout; class fl_BlockLayout; class FV_Caret; class FV_Cursor { public: FV_Cursor(FV_View& view, FL_DocLayout& layout); ~FV_Cursor(); // the following accessors returns' are related to current DocPos. fp_Run* getCurrentRun(); // returns 0 if no current run fp_Line* getCurrentLine(); // returns 0 if no current line fl_BlockLayout* getCurrentBlockLayout();// BlockLayout for current DocPos PT_DocPosition getDocPos() const; UT_sint32 getContainerRelativeX() const; UT_sint32 getContainerRelativeY() const; UT_sint32 getPointHeight() const; // The bEOL argument is needed since a document position // can have IP at either EOL line 1 or BOL line 2. void setDocPos(PT_DocPosition dp, UT_Bool bEOL = UT_FALSE); // should this really be in the public part of the interface? // It returns the display/layout x-position of IP in // fp_Container (fp_Column) relative coordinate system. UT_uint32 getDisplayX(); // The user interface for FV_Caret. void disable(); // visibly no-op if cursor already is drawn void enable(); // visibly no-op if cursor already is erased void setBlink(UT_Bool bBlink); // Tells it wether to "blink" or not. // these are the move commands for the cursor. void up(); // Implemented. Seems to work OK. void down(); // Implemented. Seems to work OK. void left(); // Implemented. Seems to work OK. void right(); // Implemented. Seems to work OK. void pageUp(); // Not implemented yet! void pageDown(); // Not implemented yet! void home(); // Implemented. Seems to work OK. void end(); // Implemented. Seems to work OK. void wordLeft(); // Not implemented yet! void wordRight(); // Not implemented yet! UT_Bool isAtEOL() const; UT_Bool isAtBOL() const; // This might be dropped or put in protected. protected: // These are the [relative] movement handlers for the cursor. // They are free for any derived classes to override and implement // other behaviour. No calling of baseclass' version is needed. virtual void _up(); virtual void _down(); virtual void _left(); virtual void _right(); virtual void _pageUp(); virtual void _pageDown(); virtual void _home(); virtual void _end(); virtual void _wordLeft(); virtual void _wordRight(); // interface for derived classes void _updateInternal(); void _setEOL(UT_Bool bEOL = UT_TRUE); void _setBOL(UT_Bool bBOL = UT_TRUE); void _setStickyX(UT_sint32 x); // 0 is non-sticky UT_sint32 _getStickyX(); // 0 is non-sticky fp_Line* _getPrevLine(); // realtive current DocPos fp_Line* _getNextLine(); // realtive current DocPos // Coordinate system conversion UT_sint32 _containerToLineX(const fp_Line& line, UT_sint32 containerX); // Returns closest match. // x < first run on line returns first run on line. // x > last run on line returns last run on line. fp_Run* _getRunAtColumnOffset(const fp_Line& line, UT_sint32 x); private: FV_Cursor(const FV_Cursor& rhs); // no impl. void operator=(const FV_Cursor& rhs); // no impl. UT_Bool _isRelativeMovementAllowed(); void _do_movement(void (FV_Cursor::*pmfn)()); // Since this class uses some hairy stuff inside, depends upon // more than a few other classes, and has changed rather frequently // during development, I decided to use the 'pimpl' idiom. // This might (will?) change before the release of this class. class FV_Cursor_impl* m_pimpl; }; ////////////////////////////////////////////////////////////////// // The following class is used internally by FV_Cursor // It should possibly (probably) be moved into its own file(s), but for // now, during development, it's left here due to the close relationship // with FV_Cursor. class FV_Caret { public: FV_Caret(FV_Cursor& cursor, FV_View& view); ~FV_Caret(); void enable(); void disable(); UT_Bool isEnabled() const { return m_nDisableCount == 0; } void setBlink(UT_Bool bBlink); class callbackHelper { // This [inner] class is here for two reasons. // 1. To inhibit any function but the one in the // friend declaration to make the caret blink. // 2. To display how friendship actually can strengthen // encapsulation (compared to giving this free function // friendship to the class FV_Caret).. friend void FV_Caret_CursorTimerCallback(UT_Timer* pTimer); static void _callback(FV_Caret& caret) { if (caret.isEnabled()) { caret._blink(); } } }; private: friend callbackHelper; FV_Caret(const FV_Caret& rhs); // no impl. void operator=(const FV_Caret& rhs); // no impl. void _blink(); UT_Bool _createTimer(); FV_Cursor& m_cursor; FV_View& m_view; UT_Timer* m_pAutoCursorTimer; // without interlocked inc/dec the best we can do is to use volatile... volatile UT_uint32 m_nDisableCount; UT_Bool m_bCursorBlink; UT_Bool m_bCursorIsOn; }; class FV_CursorDisabler { public: FV_CursorDisabler(FV_Cursor& cursor) : m_cursor(cursor) { // The reson for using 'cursor' rather than 'm_cursor' is that this // approach uses less memory (RAM) accesses. cursor.disable(); } ~FV_CursorDisabler() { m_cursor.enable(); } private: FV_Cursor& m_cursor; }; #endif // FV_CURSOR_H