X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/96eb3b1a82b0b80b285e3fd19cb161c31a6b1d3f..4b04699b670b4ab4632229fa0264d154acd3bec1:/samples/richedit/wxllist.h diff --git a/samples/richedit/wxllist.h b/samples/richedit/wxllist.h index d0d7c94ae6..c965f6b322 100644 --- a/samples/richedit/wxllist.h +++ b/samples/richedit/wxllist.h @@ -1,7 +1,7 @@ /*-*- c++ -*-******************************************************** * wxLayoutList.h - a formatted text rendering engine for wxWindows * * * - * (C) 1999 by Karsten Ballüder (Ballueder@usa.net) * + * (C) 1999-2000 by Karsten Ballüder (ballueder@gmx.net) * * * * $Id$ *******************************************************************/ @@ -16,37 +16,60 @@ #include "kbList.h" -#include "wx/wx.h" -#include "wx/print.h" -#include "wx/printdlg.h" -#include "wx/generic/printps.h" -#include "wx/generic/prntdlgg.h" -#include "wx/dataobj.h" +#include +#include +#include +#include +#include +#include // skip the following defines if embedded in M application #ifndef M_BASEDIR # define WXMENU_LAYOUT_LCLICK 1111 # define WXMENU_LAYOUT_RCLICK 1112 # define WXMENU_LAYOUT_DBLCLICK 1113 +#else // for Mahogany only +# include "MObject.h" #endif // use the wxWindows caret class instead of home grown cursor whenever possible #ifdef __WXMSW__ - #undef WXLAYOUT_USE_CARET - #define WXLAYOUT_USE_CARET 1 +# undef WXLAYOUT_USE_CARET +# define WXLAYOUT_USE_CARET 1 #endif // __WXMSW__ -// do not enable debug mode within Mahogany -#if defined(__WXDEBUG__) && ! defined(M_BASEDIR) +// do not enable debug mode within Mahogany unless in debug mode +#if defined(__WXDEBUG__) && (( ! defined(M_BASEDIR) )|| defined(DEBUG)) # define WXLAYOUT_DEBUG #endif #ifdef WXLAYOUT_DEBUG # define WXLO_TRACE(x) wxLogDebug(x) +// activate profiling: # define WXLO_PROFILE #else # define WXLO_TRACE(x) #endif +/* Some profiling code: */ +#if defined (WXLO_PROFILE) +#include +#include + +# define WXLO_TIMER_DEFINE(x) static struct timeval x +# define WXLO_TIMER_START(x) gettimeofday(&x,NULL) +# define WXLO_TIMER_STOP(x) { struct timeval y; \ + gettimeofday(&y,NULL); \ + x.tv_sec -= y.tv_sec; x.tv_usec -= y.tv_usec; } +# define WXLO_TIMER_PRINT(x) wxLogDebug("Timer " #x " elapsed: %ld", \ + (long)(x.tv_sec * -1000 - x.tv_usec)); +#else +# define WXLO_TIMER_DEFINE(x) +# define WXLO_TIMER_START(x) +# define WXLO_TIMER_STOP(x) +# define WXLO_TIMER_PRINT(x) +#endif + + #define WXLO_DEBUG_URECT 0 #ifndef WXLO_DEFAULTFONTSIZE @@ -69,7 +92,9 @@ enum wxLayoutObjectType /// command object, containing font or colour changes WXLO_TYPE_CMD, /// icon object, any kind of image - WXLO_TYPE_ICON + WXLO_TYPE_ICON, + /// a linebreak, does not exist as an object + WXLO_TYPE_LINEBREAK }; /// Type used for coordinates in drawing. Must be signed. @@ -96,6 +121,9 @@ class WXDLLEXPORT wxFont; its size. */ class wxLayoutObject +#ifdef M_BASEDIR + : public MObject +#endif { public: /** This structure can be used to contain data associated with the @@ -166,7 +194,7 @@ public: virtual ~wxLayoutObject() { if(m_UserData) m_UserData->DecRef(); } #ifdef WXLAYOUT_DEBUG - virtual void Debug(void); + virtual wxString DebugDump(void) const; #endif /** Tells the object about some user data. This data is associated @@ -203,9 +231,16 @@ public: */ static wxLayoutObject *Read(wxString &istr); //@} + + /// returns TRUE if the object is shown on the screen (i.e. not cmd object) + bool IsVisibleObject() const { return GetType() != WXLO_TYPE_CMD; } + protected: /// optional data for application's use UserData *m_UserData; +#if defined (M_BASEDIR) && defined (DEBUG) + MOBJECT_NAME(wxLayoutObject) +#endif }; /// Define a list type of wxLayoutObject pointers. @@ -214,7 +249,7 @@ KBLIST_DEFINE(wxLayoutObjectList, wxLayoutObject); /// An illegal iterator to save typing. #define NULLIT (wxLayoutObjectList::iterator(NULL)) /// The iterator type. -#define wxLOiterator wxLayoutObjectList::iterator +typedef wxLayoutObjectList::iterator wxLOiterator; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * @@ -254,10 +289,10 @@ public: static wxLayoutObjectText *Read(wxString &istr); #ifdef WXLAYOUT_DEBUG - virtual void Debug(void); + virtual wxString DebugDump(void) const; #endif - virtual CoordType GetLength(void) const { return strlen(m_Text.c_str()); } + virtual CoordType GetLength(void) const { return wxStrlen(m_Text.c_str()); } // for editing: wxString & GetText(void) { return m_Text; } @@ -316,8 +351,7 @@ private: wxBitmap *m_Icon; }; -/** This structure holds all formatting information. Members which are - undefined (for a CmdObject this means: no change), are set to -1. +/** This structure holds all formatting information. */ struct wxLayoutStyleInfo { @@ -328,11 +362,10 @@ struct wxLayoutStyleInfo int iul = -1, wxColour *fg = NULL, wxColour *bg = NULL); - wxColour & GetBGColour() - { - return m_bg; - } wxLayoutStyleInfo & operator=(const wxLayoutStyleInfo &right); + + wxColour & GetBGColour() { return m_bg; } + /// Font change parameters. int size, family, style, weight, underline; /// Colours @@ -340,7 +373,7 @@ struct wxLayoutStyleInfo int m_fg_valid, m_bg_valid; // bool, but must be int! }; - +/// a cached font class wxFontCacheEntry { public: @@ -366,6 +399,8 @@ public: } private: wxFont *m_Font; + + // VZ: I wonder why it doesn't use wxLayoutStyleInfo instead of those? int m_Family, m_Size, m_Style, m_Weight; bool m_Underline; }; @@ -409,6 +444,7 @@ public: int underline = -1, wxColour *fg = NULL, wxColour *bg = NULL); + wxLayoutObjectCmd(const wxLayoutStyleInfo &si); ~wxLayoutObjectCmd(); /** Stores the current style in the styleinfo structure */ wxLayoutStyleInfo * GetStyle(void) const; @@ -462,11 +498,18 @@ public: void Append(wxLayoutObject * obj) { wxASSERT(obj); - m_ObjectList.push_back(obj); m_Length += obj->GetLength(); } + /** This function prepends an object to the line. */ + void Prepend(wxLayoutObject * obj) + { + wxASSERT(obj); + m_ObjectList.push_front(obj); + m_Length += obj->GetLength(); + } + /** This function appens the next line to this, i.e. joins the two lines into one. */ @@ -485,6 +528,13 @@ public: */ wxLayoutLine *Break(CoordType xpos, wxLayoutList *llist); + /** This function wraps the line: breaks it at a suitable point + and merges it with the next. + @param wrapmargin + @return TRUE if broken + */ + bool Wrap(CoordType wrapmargin, wxLayoutList *llist); + /** Deletes the next word from this position, including leading whitespace. This function does not delete over font changes, i.e. a word @@ -516,12 +566,14 @@ public: /** Finds the object which covers the screen position xpos in this line. @param dc the wxDC to use for calculations + @param llist the layout list to which this line belongs @param xpos the screen x coordinate @param offset where to store the difference between xpos and the object's head @return iterator to the object or NULLIT */ wxLayoutObjectList::iterator FindObjectScreen(wxDC &dc, + wxLayoutList *llist, CoordType xpos, CoordType *offset, bool *found = NULL) const ; @@ -537,11 +589,18 @@ public: functions to export the list. @return iterator to the first object */ - wxLayoutObjectList::iterator GetFirstObject(void) + wxLayoutObjectList::iterator GetFirstObject(void) const { return m_ObjectList.begin(); } + /** Get the last object in the list. + */ + wxLayoutObjectList::iterator GetLastObject(void) const + { + return m_ObjectList.tail(); + } + /** Deletes this line, returns pointer to next line. @param update If true, update all following lines. */ @@ -576,6 +635,7 @@ public: @param llist th e wxLayoutList @param cursorPos if not NULL, set cursor screen position in there @param cursorSize if not cursorPos != NULL, set cursor size in there + @param cursorStyle if non NULL where to store styleinfo for cursor pos @param cx if cursorPos != NULL, the cursor x position @param suppressStyleUpdate FALSe normally, only to suppress updating of m_StyleInfo */ @@ -583,6 +643,7 @@ public: wxLayoutList *llist, wxPoint *cursorPos = NULL, wxPoint *cursorSize = NULL, + wxLayoutStyleInfo *cursorStyle = NULL, int cx = 0, bool suppressStyleUpdate = FALSE); /** This function finds an object belonging to a given cursor @@ -594,13 +655,14 @@ public: for that position @return pointer to the object */ - wxLayoutObject * FindObjectScreen(wxDC &dc, CoordType xpos, bool - *found = NULL); + wxLayoutObject * FindObjectScreen(wxDC &dc, + CoordType xpos, + bool *found = NULL); /** This sets the style info for the beginning of this line. @param si styleinfo structure */ void ApplyStyle(const wxLayoutStyleInfo &si) - { m_StyleInfo = si; } + { m_StyleInfo = si; } //@} @@ -624,15 +686,6 @@ public: CoordType GetHeight(void) const { return m_Height; } /// Returns the width of this line. CoordType GetWidth(void) const { return m_Width; } - /** This will recalculate the position and size of this line. - If called recursively it will abort if the position of an - object is unchanged, assuming that none of the following - objects need to move. - @param recurse if greater 0 then it will be used as the - minimum(!) recursion level, continue with all lines till the end of - the list or until the coordinates no longer changed. - */ - void RecalculatePositions(int recurse, wxLayoutList *llist); /// Recalculates the position of this line on the canvas. wxPoint RecalculatePosition(wxLayoutList *llist); @@ -646,7 +699,7 @@ public: CoordType to = -1); #ifdef WXLAYOUT_DEBUG - void Debug(void); + void Debug(void) const; #endif wxLayoutStyleInfo const & GetStyleInfo() const { return m_StyleInfo; } @@ -664,11 +717,8 @@ public: } m_Dirty = true; + if(m_Next) m_Next->MarkDirty(); } - /** Marks the following lines as dirty. - @param recurse if -1 recurse to end of list, otherwise depth of recursion. - */ - void MarkNextDirty(int recurse = 0); /// Reset the dirty flag void MarkClean() { m_Dirty = false; m_updateLeft = -1; } @@ -683,17 +733,10 @@ private: @param height new height */ void SetHeight(CoordType height, wxLayoutList *llist) - { m_Height = height; RecalculatePositions(true, llist); } + { m_Height = height; MarkDirty(); } - /** Moves the linenumbers one on, because a line has been inserted - or deleted. - @param delta either +1 or -1 - */ - void MoveLines(int delta) - { - m_LineNumber += delta; - if(m_Next) m_Next->MoveLines(delta); - } + /** Updates the line numbers. */ + void ReNumber(void); //@} private: /// The line number. @@ -760,6 +803,14 @@ public: /// Empty: clear the list but leave font settings. void Empty(void); + /** Enable or disable auto-formatting. Normally, while editing this + should be enabled which is the default. While + inserting/deleting lots of text, it makes sense to temporarily + disable this. + @param enable TRUE to enable, FALSE to disable + */ + void SetAutoFormatting(bool enable = TRUE) + { m_AutoFormat = enable; } /**@name Cursor Management */ //@{ /** Set new cursor position. @@ -779,9 +830,11 @@ public: bool MoveCursorHorizontally(int n); /** Move cursor to the left or right counting in words @param n = number of positions in words + @param untilNext: puts the cursor at the start of the next word if true, + leaves it at the end of the current one otherwise @return bool if it could be moved */ - bool MoveCursorWord(int n); + bool MoveCursorWord(int n, bool untilNext = true); /// Move cursor to end of line. void MoveCursorToEndOfLine(void) @@ -790,13 +843,24 @@ public: MoveCursorHorizontally(m_CursorLine->GetLength()-m_CursorPos.x); } - /// Move cursor to begin of line. + /// Move cursor to the start of line. void MoveCursorToBeginOfLine(void) { MoveCursorHorizontally(-m_CursorPos.x); } + /// get the number of lines in the list + size_t GetNumLines() const { return m_numLines; } + /// Returns current cursor position. const wxPoint &GetCursorPos(wxDC &dc) const { return m_CursorPos; } const wxPoint &GetCursorPos() const { return m_CursorPos; } + wxLayoutLine * GetCursorLine(void) { return m_CursorLine; } + + /// move cursor to the end of text + void MoveCursorToEnd(void) + { + MoveCursorTo(wxPoint(0, GetNumLines() - 1)); + MoveCursorToEndOfLine(); + } //@} @@ -820,6 +884,12 @@ public: @return true if line got broken */ bool WrapLine(CoordType column); + + /** Wraps the complete buffer. + @param column the break position for the line, maximum length + @return true if line got broken + */ + bool WrapAll(CoordType column); /** This function deletes npos cursor positions. @param npos how many positions @return true if everything got deleted @@ -904,7 +974,6 @@ public: inline void SetFontColour(wxColour *fg, wxColour *bg = NULL) { SetFont(-1,-1,-1,-1,-1,fg,bg); } - /** Returns a pointer to the default settings. This is only valid temporarily and should not be stored @@ -913,6 +982,28 @@ public: */ wxLayoutStyleInfo &GetDefaultStyleInfo(void) { return m_DefaultStyleInfo ; } wxLayoutStyleInfo &GetStyleInfo(void) { return m_CurrentStyleInfo ; } + const wxLayoutStyleInfo &GetStyleInfo(void) const { return m_CurrentStyleInfo ; } + const wxLayoutStyleInfo &GetCursorStyleInfo(void) const { return m_CursorStyleInfo ; } + + /// is the current font underlined? + bool IsFontUnderlined() const { return GetCursorStyleInfo().underline != 0; } + /// is the current font bold? + bool IsFontBold() const { return GetCursorStyleInfo().weight == wxBOLD; } + /// is the current font italic? + bool IsFontItalic() const { return GetCursorStyleInfo().style == wxITALIC; } + + /// set underline if it was off, turn it off if it was on + void ToggleFontUnderline() + { SetFontUnderline(!IsFontUnderlined()); } + + /// make font bold if it was normal or make it normal if it was bold + void ToggleFontWeight() + { SetFontWeight(IsFontBold() ? wxNORMAL : wxBOLD); } + + /// make font italic if it was normal or make it normal if it was italic + void ToggleFontItalics() + { SetFontStyle(IsFontItalic() ? wxNORMAL : wxITALIC); } + //@} /**@name Drawing */ @@ -922,10 +1013,13 @@ public: @param offset an optional offset to shift printout @param top optional y coordinate where to start drawing @param bottom optional y coordinate where to stop drawing + @param clipStrictly if set, do not draw objects which reach + beyond "bottom". Set this when printing. */ void Draw(wxDC &dc, const wxPoint &offset = wxPoint(0,0), - CoordType top = -1, CoordType bottom = -1); + CoordType top = -1, CoordType bottom = -1, + bool clipStrictly = false); /** Calculates new layout for the list, like Draw() but does not actually draw it. @@ -940,6 +1034,13 @@ public: wxPoint *cpos = NULL, wxPoint *csize = NULL); + /** Ensure that the whole list will be recalculate on the next call + to Layout() or Draw(). + @param redrawAll TRUE or FALSE to reset it + */ + void ForceTotalLayout(bool redrawAll = TRUE) + { m_ReLayoutAll = redrawAll; } + /** Returns the screen coordinates relating to a given cursor position and the size of the cursor at that position. @param dc for which to calculate it @@ -965,14 +1066,8 @@ public: wxPoint GetSize(void) const; /** Returns the cursor position on the screen. - @return cursor position in pixels */ - wxPoint GetCursorScreenPos(wxDC &dc); - - /** Calculates the cursor position on the screen. - @param dc the dc to use for cursor position calculations - */ - void UpdateCursorScreenPos(wxDC &dc); + wxPoint GetCursorScreenPos(void) const; /** Draws the cursor. @param active If true, draw a bold cursor to mark window as @@ -1009,11 +1104,11 @@ public: /// adds the cursor position to the update rectangle void AddCursorPosToUpdateRect() { - #ifndef WXLAYOUT_USE_CARET - SetUpdateRect(m_CursorScreenPos); - SetUpdateRect(m_CursorScreenPos+m_CursorSize); +#ifndef WXLAYOUT_USE_CARET + SetUpdateRect(m_CursorScreenPos); + SetUpdateRect(m_CursorScreenPos+m_CursorSize); //#else - the caret will take care of refreshing itself - #endif // !WXLAYOUT_USE_CARET +#endif // !WXLAYOUT_USE_CARET } /// Invalidates the update rectangle. void InvalidateUpdateRect(void) { m_UpdateRectValid = false; } @@ -1046,9 +1141,9 @@ public: /// Discard the current selection void DiscardSelection(); /// Are we still selecting text? - bool IsSelecting(void); + bool IsSelecting(void) const; /// Is the given point (text coords) selected? - bool IsSelected(const wxPoint &cursor); + bool IsSelected(const wxPoint &cursor) const; /// Do we have a non null selection? bool HasSelection() const { return m_Selection.m_valid || m_Selection.m_selecting; } @@ -1085,16 +1180,37 @@ public: void Debug(void); #endif + // for wxLayoutLine usage only + void IncNumLines() { m_numLines++; } + void DecNumLines() { m_numLines--; } + + /// get the line by number + wxLayoutLine *GetLine(CoordType index) const; + + /** Reads objects from a string and inserts them. Returns NULL if + string is empty or a linebreak was found. + @param istr stream to read from, will bee changed + */ + void Read(wxString &istr); + private: /// Clear the list. void InternalClear(void); /// The list of lines. wxLayoutLine *m_FirstLine; + /// The number of lines in the list (store instead recalculating for speed) + size_t m_numLines; + /// The update rectangle which needs to be refreshed: wxRect m_UpdateRect; /// Is the update rectangle valid? bool m_UpdateRectValid; + + /// Shall we auto-format? + bool m_AutoFormat; + /// Shall we re-layout everything? + bool m_ReLayoutAll; /**@name Cursor Management */ //@{ /// Where the text cursor (column,line) is. @@ -1116,9 +1232,11 @@ private: /// selection.state and begin/end coordinates struct Selection { - Selection() { m_valid = false; m_selecting = false; } + Selection() { m_valid = m_selecting = m_discarded = false; } + bool m_valid; bool m_selecting; + bool m_discarded; // may be TRUE only until the next redraw // returns true if we already have the screen coordinates of the // selection start and end @@ -1139,6 +1257,8 @@ private: wxLayoutStyleInfo m_DefaultStyleInfo; /// the current setting: wxLayoutStyleInfo m_CurrentStyleInfo; + /// the current setting: + wxLayoutStyleInfo m_CursorStyleInfo; //@} }; @@ -1148,14 +1268,18 @@ private: own format. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -class wxLayoutDataObject : public wxPrivateDataObject +class wxLayoutDataObject : public wxCustomDataObject { public: - wxLayoutDataObject(void) + wxLayoutDataObject() { - SetId("application/wxlayoutlist"); - //m_format.SetAtom((GdkAtom) 222222); + SetFormat(wxT("application/wxlayoutlist")); } + + // type safe wrappers + void SetLayoutData(const wxString& text) + { SetData(text.length() + 1, text.c_str()); } + const char *GetLayoutData() const { return (const char *)GetData(); } }; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *