1 /*-*- c++ -*-********************************************************
2 * wxLayoutList.h - a formatted text rendering engine for wxWidgets *
4 * (C) 1999-2000 by Karsten Ballüder (ballueder@gmx.net) *
7 *******************************************************************/
17 #include "wx/printdlg.h"
18 #include "wx/generic/printps.h"
19 #include "wx/generic/prntdlgg.h"
20 #include "wx/dataobj.h"
22 // skip the following defines if embedded in M application
24 # define WXMENU_LAYOUT_LCLICK 1111
25 # define WXMENU_LAYOUT_RCLICK 1112
26 # define WXMENU_LAYOUT_DBLCLICK 1113
27 #else // for Mahogany only
31 // use the wxWidgets caret class instead of home grown cursor whenever possible
33 # undef WXLAYOUT_USE_CARET
34 # define WXLAYOUT_USE_CARET 1
37 // do not enable debug mode within Mahogany unless in debug mode
38 #if defined(__WXDEBUG__) && (( ! defined(M_BASEDIR) )|| defined(DEBUG))
39 # define WXLAYOUT_DEBUG
43 # define WXLO_TRACE(x) wxLogDebug(x)
44 // activate profiling: # define WXLO_PROFILE
46 # define WXLO_TRACE(x)
49 /* Some profiling code: */
50 #if defined (WXLO_PROFILE)
54 # define WXLO_TIMER_DEFINE(x) static struct timeval x
55 # define WXLO_TIMER_START(x) gettimeofday(&x,NULL)
56 # define WXLO_TIMER_STOP(x) { struct timeval y; \
57 gettimeofday(&y,NULL); \
58 x.tv_sec -= y.tv_sec; x.tv_usec -= y.tv_usec; }
59 # define WXLO_TIMER_PRINT(x) wxLogDebug("Timer " #x " elapsed: %ld", \
60 (long)(x.tv_sec * -1000 - x.tv_usec));
62 # define WXLO_TIMER_DEFINE(x)
63 # define WXLO_TIMER_START(x)
64 # define WXLO_TIMER_STOP(x)
65 # define WXLO_TIMER_PRINT(x)
69 #define WXLO_DEBUG_URECT 0
71 #ifndef WXLO_DEFAULTFONTSIZE
72 # define WXLO_DEFAULTFONTSIZE 12
76 # define WXLO_BITMAP_FORMAT wxBITMAP_TYPE_BMP
78 # define WXLO_BITMAP_FORMAT wxBITMAP_TYPE_PNG
81 /// Types of currently supported layout objects.
82 enum wxLayoutObjectType
84 /// illegal object type, should never appear
85 WXLO_TYPE_INVALID
= 0,
87 /// text object, containing normal text
90 /// command object, containing font or colour changes
93 /// icon object, any kind of image
96 /// a linebreak, does not exist as an object
100 /// Type used for coordinates in drawing. Must be signed.
101 typedef long CoordType
;
103 // Forward declarations.
106 class wxLayoutObject
;
108 class WXDLLEXPORT wxCaret
;
109 class WXDLLEXPORT wxColour
;
110 class WXDLLEXPORT wxDC
;
111 class WXDLLEXPORT wxFont
;
113 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
115 The wxLayout objects which make up the lines.
117 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
119 /** The base class defining the interface to each object which can be
120 part of the layout. Each object needs to draw itself and calculate
129 /** This structure can be used to contain data associated with the
131 It is refcounted, so the caller has to do a DecRef() on it
136 UserData() { m_refcount
= 1; }
137 inline void IncRef() { m_refcount
++; }
138 inline void DecRef() { m_refcount
--; if(m_refcount
== 0) delete this;}
139 inline void SetLabel(const wxString
&l
) { m_label
= l
; }
140 inline const wxString
& GetLabel() const { return m_label
; }
145 virtual ~UserData() { wxASSERT(m_refcount
== 0); }
146 /// prevents gcc from generating stupid warnings
147 friend class dummy_UserData
;
150 /// return the type of this object
151 virtual wxLayoutObjectType
GetType() const { return WXLO_TYPE_INVALID
; }
152 /** Calculates the size of an object.
153 @param dc the wxDC to draw on
154 @param llist the wxLayoutList
156 virtual void Layout(wxDC
&dc
, wxLayoutList
*llist
) = 0;
159 @param dc the wxDC to draw on
160 @param coords where to draw the baseline of the object.
161 @param wxllist pointer to wxLayoutList
162 @param begin if !=-1, from which position on to highlight it
163 @param end if begin !=-1, how many positions to highlight it
165 virtual void Draw(wxDC
& /* dc */,
166 wxPoint
const & /* coords */,
167 wxLayoutList
*WXUNUSED(wxllist
),
168 CoordType
WXUNUSED(begin
) = -1,
169 CoordType
WXUNUSED(end
) = -1) { }
171 /** Calculates and returns the size of the object.
172 @param top where to store height above baseline
173 @param bottom where to store height below baseline
174 @return the size of the object's box in pixels
176 virtual wxPoint
GetSize(CoordType
* top
, CoordType
*bottom
) const
177 { *top
= 0; *bottom
= 0; return wxPoint(0,0); }
179 /// Return just the width of the object on the screen.
180 virtual CoordType
GetWidth() const { return 0; }
182 /// returns the number of cursor positions occupied by this object
183 virtual CoordType
GetLength() const { return 1; }
185 /** Returns the cursor offset relating to the screen x position
186 relative to begin of object.
187 @param dc the wxDC to use for calculations
188 @param xpos relative x position from head of object
189 @return cursor coordinate offset
191 virtual CoordType
GetOffsetScreen( wxDC
& WXUNUSED(dc
),
192 CoordType
WXUNUSED(xpos
) ) const
198 wxLayoutObject() { m_UserData
= NULL
; }
200 /// delete the user data
201 virtual ~wxLayoutObject() { if(m_UserData
) m_UserData
->DecRef(); }
203 #ifdef WXLAYOUT_DEBUG
204 virtual wxString
DebugDump() const;
207 /** Tells the object about some user data. This data is associated
208 with the object and will be deleted at destruction time.
209 It is reference counted.
211 void SetUserData(UserData
*data
)
214 m_UserData
->DecRef();
219 m_UserData
->IncRef();
222 /** Return the user data.
223 Increments the object's reference count. When no longer needed,
224 caller must call DecRef() on the pointer returned.
226 UserData
* GetUserData() const { if(m_UserData
) m_UserData
->IncRef(); return m_UserData
; }
228 /** Makes a copy of this object.
230 virtual wxLayoutObject
*Copy() = 0;
232 /** Clipboard support function. Read and write objects to
235 /// Writes the object to the string.
236 virtual void Write(wxString
&ostr
) = 0;
239 @param str stream to read from, will bee changed
240 @return true on success
242 static wxLayoutObject
*Read(wxString
&istr
);
245 /// returns true if the object is shown on the screen (i.e. not cmd object)
246 bool IsVisibleObject() const { return GetType() != WXLO_TYPE_CMD
; }
249 /// optional data for application's use
250 UserData
*m_UserData
;
251 #if defined (M_BASEDIR) && defined (DEBUG)
252 MOBJECT_NAME(wxLayoutObject
)
256 /// Define a list type of wxLayoutObject pointers.
257 KBLIST_DEFINE(wxLayoutObjectList
, wxLayoutObject
);
259 /// The iterator type.
260 typedef wxLayoutObjectList::iterator wxLOiterator
;
262 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
266 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
267 /** This class implements a wxLayoutObject holding plain text.
269 class wxLayoutObjectText
: public wxLayoutObject
272 wxLayoutObjectText(const wxString
&txt
= wxEmptyString
);
274 virtual wxLayoutObjectType
GetType() const { return WXLO_TYPE_TEXT
; }
275 virtual void Layout(wxDC
&dc
, wxLayoutList
*llist
);
276 virtual void Draw(wxDC
&dc
, wxPoint
const &coords
,
277 wxLayoutList
*wxllist
,
278 CoordType begin
= -1,
281 /** Calculates and returns the size of the object.
282 @param top where to store height above baseline
283 @param bottom where to store height below baseline
284 @return the size of the object's box in pixels
286 virtual wxPoint
GetSize(CoordType
* top
, CoordType
*bottom
) const;
288 /// Return just the width of the object on the screen.
289 virtual CoordType
GetWidth() const { return m_Width
; }
291 /** Returns the cursor offset relating to the screen x position
292 relative to begin of object.
293 @param dc the wxDC to use for calculations
294 @param xpos relative x position from head of object
295 @return cursor coordinate offset
297 virtual CoordType
GetOffsetScreen(wxDC
&dc
, CoordType xpos
) const;
299 virtual void Write(wxString
&ostr
);
300 static wxLayoutObjectText
*Read(wxString
&istr
);
302 #ifdef WXLAYOUT_DEBUG
303 virtual wxString
DebugDump() const;
306 virtual CoordType
GetLength() const { return wxStrlen(m_Text
.c_str()); }
309 wxString
& GetText() { return m_Text
; }
311 void SetText(wxString
const &text
) { m_Text
= text
; }
312 /** Makes a copy of this object.
314 virtual wxLayoutObject
*Copy();
319 /// size of the box containing text
320 long m_Width
, m_Height
;
322 /// Height above baseline.
325 /// Height below baseline.
329 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
333 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
334 /** This class implements a wxLayoutObject holding a graphic.
336 class wxLayoutObjectIcon
: public wxLayoutObject
339 wxLayoutObjectIcon(wxBitmap
*icon
= NULL
);
340 wxLayoutObjectIcon(wxBitmap
const &icon
);
342 ~wxLayoutObjectIcon() { if(m_Icon
) delete m_Icon
; }
344 virtual wxLayoutObjectType
GetType() const { return WXLO_TYPE_ICON
; }
345 virtual void Layout(wxDC
&dc
, wxLayoutList
*llist
);
346 virtual void Draw(wxDC
&dc
, wxPoint
const &coords
,
347 wxLayoutList
*wxllist
,
348 CoordType begin
= -1,
351 /** Calculates and returns the size of the object.
352 @param top where to store height above baseline
353 @param bottom where to store height below baseline
354 @return the size of the object's box in pixels
356 virtual wxPoint
GetSize(CoordType
* top
, CoordType
*bottom
) const;
358 /// Return just the width of the object on the screen.
359 virtual CoordType
GetWidth() const { return m_Icon
->GetWidth(); }
361 // return a pointer to the icon
362 wxBitmap
*GetIcon() const { return m_Icon
; }
364 /** Makes a copy of this object.
366 virtual wxLayoutObject
*Copy();
367 virtual void Write(wxString
&ostr
);
368 static wxLayoutObjectIcon
*Read(wxString
&istr
);
374 /** This structure holds all formatting information.
376 struct wxLayoutStyleInfo
378 wxLayoutStyleInfo(int ifamily
= -1,
384 wxColour
*bg
= NULL
);
386 wxLayoutStyleInfo
& operator=(const wxLayoutStyleInfo
&right
);
388 wxColour
& GetBGColour() { return m_bg
; }
390 /// Font change parameters.
391 int size
, family
, style
, weight
, underline
;
395 int m_fg_valid
, m_bg_valid
; // bool, but must be int!
399 class wxFontCacheEntry
402 wxFontCacheEntry(int family
, int size
, int style
, int weight
,
405 m_Family
= family
; m_Size
= size
; m_Style
= style
;
406 m_Weight
= weight
; m_Underline
= underline
;
407 m_Font
= new wxFont(m_Size
, m_Family
,
408 m_Style
, m_Weight
, m_Underline
);
411 bool Matches(int family
, int size
, int style
, int weight
,
412 bool underline
) const
414 return size
== m_Size
&& family
== m_Family
415 && style
== m_Style
&& weight
== m_Weight
416 && underline
== m_Underline
;
419 wxFont
& GetFont() { return *m_Font
; }
428 // VZ: I wonder why it doesn't use wxLayoutStyleInfo instead of those?
429 int m_Family
, m_Size
, m_Style
, m_Weight
;
433 KBLIST_DEFINE(wxFCEList
, wxFontCacheEntry
);
438 wxFont
& GetFont(int family
, int size
, int style
, int weight
,
441 wxFont
& GetFont(wxLayoutStyleInfo
const &si
)
443 return GetFont(si
.family
, si
.size
, si
.style
, si
.weight
,
448 wxFCEList m_FontList
;
451 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
455 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
456 /** This class implements a wxLayoutObject holding style change commands.
458 class wxLayoutObjectCmd
: public wxLayoutObject
461 virtual wxLayoutObjectType
GetType() const { return WXLO_TYPE_CMD
; }
462 virtual void Layout(wxDC
&dc
, wxLayoutList
*llist
);
463 virtual void Draw(wxDC
&dc
, wxPoint
const &coords
,
464 wxLayoutList
*wxllist
,
465 CoordType begin
= -1,
468 wxLayoutObjectCmd(int family
= -1,
474 wxColour
*bg
= NULL
);
476 wxLayoutObjectCmd(const wxLayoutStyleInfo
&si
);
477 ~wxLayoutObjectCmd();
478 /** Stores the current style in the styleinfo structure */
479 wxLayoutStyleInfo
* GetStyle() const;
480 /** Makes a copy of this object.
482 virtual wxLayoutObject
*Copy();
483 virtual void Write(wxString
&ostr
);
484 static wxLayoutObjectCmd
*Read(wxString
&istr
);
487 wxLayoutStyleInfo
*m_StyleInfo
;
490 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
492 The wxLayoutLine object
494 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
496 /** This class represents a single line of objects to be displayed.
497 It knows its height and total size and whether it needs to be
499 It has pointers to its first and next line so it can automatically
500 update them as needed.
506 @param prev pointer to previous line or NULL
507 @param next pointer to following line or NULL
508 @param llist pointer to layout list
510 wxLayoutLine(wxLayoutLine
*prev
, wxLayoutList
*llist
);
511 /** This function inserts a new object at cursor position xpos.
512 @param xpos where to insert new object
513 @param obj the object to insert
514 @return true if that xpos existed and the object was inserted
516 bool Insert(CoordType xpos
, wxLayoutObject
*obj
);
518 /** This function inserts text at cursor position xpos.
519 @param xpos where to insert
520 @param text the text to insert
521 @return true if that xpos existed and the object was inserted
523 bool Insert(CoordType xpos
, const wxString
& text
);
525 /** This function appends an object to the line.
526 @param obj the object to insert
528 void Append(wxLayoutObject
* obj
)
531 m_ObjectList
.push_back(obj
);
532 m_Length
+= obj
->GetLength();
535 /** This function prepends an object to the line. */
536 void Prepend(wxLayoutObject
* obj
)
539 m_ObjectList
.push_front(obj
);
540 m_Length
+= obj
->GetLength();
543 /** This function appens the next line to this, i.e. joins the two
546 void MergeNextLine(wxLayoutList
*llist
);
548 /** This function deletes npos cursor positions from position xpos.
549 @param xpos where to delete
550 @param npos how many positions
551 @return number of positions still to be deleted
553 CoordType
Delete(CoordType xpos
, CoordType npos
);
555 /** This function breaks the line at a given cursor position.
556 @param xpos where to break it
557 @return pointer to the new line object replacing the old one
559 wxLayoutLine
*Break(CoordType xpos
, wxLayoutList
*llist
);
561 /** This function wraps the line: breaks it at a suitable point
562 and merges it with the next.
564 @return true if broken
566 bool Wrap(CoordType wrapmargin
, wxLayoutList
*llist
);
568 /** Deletes the next word from this position, including leading
570 This function does not delete over font changes, i.e. a word
571 with formatting instructions in the middle of it is treated as
572 two (three actually!) words. In fact, if the cursor is on a non-text object, that
573 one is treated as a word.
574 @param xpos from where to delete
575 @return true if a word was deleted
577 bool DeleteWord(CoordType npos
);
579 /** Finds a suitable position left to the given column to break the
581 @param column we want to break the line to the left of this
582 @return column for breaking line or -1 if no suitable location found
584 CoordType
GetWrapPosition(CoordType column
);
586 /** Finds the object which covers the cursor position xpos in this
588 @param xpos the column number
589 @param offset where to store the difference between xpos and
591 @return iterator to the object or iterator to NULL
593 wxLayoutObjectList::iterator
FindObject(CoordType xpos
, CoordType
596 /** Finds the object which covers the screen position xpos in this
598 @param dc the wxDC to use for calculations
599 @param llist the layout list to which this line belongs
600 @param xpos the screen x coordinate
601 @param offset where to store the difference between xpos and
603 @return iterator to the object or iterator to NULL
605 wxLayoutObjectList::iterator
FindObjectScreen(wxDC
&dc
,
609 bool *found
= NULL
) const ;
611 /** Finds text in this line.
612 @param needle the text to find
613 @param xpos the position where to start the search
614 @return the cursoor coord where it was found or -1
616 CoordType
FindText(const wxString
&needle
, CoordType xpos
= 0) const;
618 /** Get the first object in the list. This is used by the wxlparser
619 functions to export the list.
620 @return iterator to the first object
622 wxLayoutObjectList::iterator
GetFirstObject() const
624 return m_ObjectList
.begin();
627 /// Get the last object in the list.
628 wxLayoutObjectList::iterator
GetLastObject() const
630 return m_ObjectList
.tail();
633 /** Deletes this line, returns pointer to next line.
634 @param update If true, update all following lines.
636 wxLayoutLine
*DeleteLine(bool update
, wxLayoutList
*llist
);
638 /**@name Cursor Management */
640 /** Return the line number of this line.
641 @return the line number
643 inline CoordType
GetLineNumber() const { return m_LineNumber
; }
645 /** Return the length of the line.
646 @return line length in cursor positions
648 inline CoordType
GetLength() const { return m_Length
; }
651 /**@name Drawing and Layout */
653 /** Draws the line on a wxDC.
654 @param dc the wxDC to draw on
655 @param llist the wxLayoutList
656 @param offset an optional offset to shift printout
660 const wxPoint
&offset
= wxPoint(0,0)) const;
662 /** Recalculates the positions of objects and the height of the
664 @param dc the wxDC to draw on
665 @param llist th e wxLayoutList
666 @param cursorPos if not NULL, set cursor screen position in there
667 @param cursorSize if not cursorPos != NULL, set cursor size in there
668 @param cursorStyle if non NULL where to store styleinfo for cursor pos
669 @param cx if cursorPos != NULL, the cursor x position
670 @param suppressStyleUpdate FALSe normally, only to suppress updating of m_StyleInfo
672 void Layout(wxDC
&dc
,
674 wxPoint
*cursorPos
= NULL
,
675 wxPoint
*cursorSize
= NULL
,
676 wxLayoutStyleInfo
*cursorStyle
= NULL
,
678 bool suppressStyleUpdate
= false);
680 /** This function finds an object belonging to a given cursor
681 position. It assumes that Layout() has been called before.
682 @param dc the wxDC to use for calculations
683 @param xpos screen x position
684 @param found if non-NULL set to false if we return the last
685 object before the cursor, to true if we really have an object
687 @return pointer to the object
689 wxLayoutObject
* FindObjectScreen(wxDC
&dc
,
693 /** This sets the style info for the beginning of this line.
694 @param si styleinfo structure
696 void ApplyStyle(const wxLayoutStyleInfo
&si
)
697 { m_StyleInfo
= si
; }
701 /**@name List traversal */
703 /// Returns pointer to next line.
704 wxLayoutLine
*GetNextLine() const { return m_Next
; }
706 /// Returns pointer to previous line.
707 wxLayoutLine
*GetPreviousLine() const { return m_Previous
; }
709 /// Sets the link to the next line.
710 void SetNext(wxLayoutLine
*next
)
711 { m_Next
= next
; if(next
) next
->m_Previous
= this; }
713 /// Sets the link to the previous line.
714 void SetPrevious(wxLayoutLine
*previous
)
715 { m_Previous
= previous
; if(previous
) previous
->m_Next
= this; }
718 /// Returns the position of this line on the canvas.
719 wxPoint
GetPosition() const { return m_Position
; }
721 /// Returns the height of this line.
722 CoordType
GetHeight() const { return m_Height
; }
724 /// Returns the width of this line.
725 CoordType
GetWidth() const { return m_Width
; }
727 /// Recalculates the position of this line on the canvas.
728 wxPoint
RecalculatePosition(wxLayoutList
*llist
);
730 /** Copies the contents of this line to another wxLayoutList
731 @param llist the wxLayoutList destination
732 @param from x cursor coordinate where to start
733 @param to x cursor coordinate where to stop, -1 for end of line
735 void Copy(wxLayoutList
*llist
,
739 #ifdef WXLAYOUT_DEBUG
742 wxLayoutStyleInfo
const & GetStyleInfo() const { return m_StyleInfo
; }
744 /// Returns dirty state
745 bool IsDirty() const { return m_Dirty
; }
747 /** Marks this line as diry.
748 @param left xpos from where it is dirty or -1 for all
750 void MarkDirty(CoordType left
= -1)
754 if ( m_updateLeft
== -1 || left
< m_updateLeft
)
759 if(m_Next
) m_Next
->MarkDirty();
762 /// Reset the dirty flag
763 void MarkClean() { m_Dirty
= false; m_updateLeft
= -1; }
766 /// Destructor is private. Use DeleteLine() to remove it.
769 /**@name Functions to let the lines synchronise with each other. */
771 /** Sets the height of this line. Will mark following lines as
773 @param height new height
775 void SetHeight( CoordType height
, wxLayoutList
* WXUNUSED(llist
) )
777 m_Height
= height
; MarkDirty();
780 /** Updates the line numbers. */
786 CoordType m_LineNumber
;
788 /// The line length in cursor positions.
791 /// The total height of the line.
794 /// The total width of the line on screen.
797 /// The baseline for drawing objects
798 CoordType m_BaseLine
;
800 /// The position on the canvas.
803 /// The list of objects
804 wxLayoutObjectList m_ObjectList
;
806 /// Have we been changed since the last layout?
809 /// The coordinate of the left boundary of the update rectangle (if m_Dirty)
810 CoordType m_updateLeft
;
812 /// Pointer to previous line if it exists.
813 wxLayoutLine
*m_Previous
;
815 /// Pointer to next line if it exists.
816 wxLayoutLine
*m_Next
;
818 /// A StyleInfo structure, holding the current settings.
819 wxLayoutStyleInfo m_StyleInfo
;
821 /// Just to suppress gcc compiler warnings.
825 wxLayoutLine(const wxLayoutLine
&);
829 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
831 The wxLayoutList object
833 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
834 /** The wxLayoutList is a list of wxLayoutLine objects. It provides a
835 higher level of abstraction for the text and can generally be considered
836 as representing "the text".
847 #ifdef WXLAYOUT_USE_CARET
848 /// give us the pointer to the caret to use
849 void SetCaret(wxCaret
*caret
) { m_caret
= caret
; }
850 #endif // WXLAYOUT_USE_CARET
853 void Clear(int family
= wxROMAN
,
854 int size
=WXLO_DEFAULTFONTSIZE
,
861 /// Empty: clear the list but leave font settings.
864 /** Enable or disable auto-formatting. Normally, while editing this
865 should be enabled which is the default. While
866 inserting/deleting lots of text, it makes sense to temporarily
868 @param enable true to enable, false to disable
871 void SetAutoFormatting(bool enable
= true)
872 { m_AutoFormat
= enable
; }
874 /**@name Cursor Management */
876 /** Set new cursor position.
877 @param p new position
878 @return bool if it could be set
880 bool MoveCursorTo(wxPoint
const &p
);
882 /** Move cursor up or down.
884 @return bool if it could be moved
886 bool MoveCursorVertically(int n
);
888 /** Move cursor left or right.
889 @param n = number of positions to move
890 @return bool if it could be moved
892 bool MoveCursorHorizontally(int n
);
894 /** Move cursor to the left or right counting in words
895 @param n = number of positions in words
896 @param untilNext: puts the cursor at the start of the next word if true,
897 leaves it at the end of the current one otherwise
898 @return bool if it could be moved
900 bool MoveCursorWord(int n
, bool untilNext
= true);
902 /// Move cursor to end of line.
903 void MoveCursorToEndOfLine()
905 wxASSERT(m_CursorLine
);
906 MoveCursorHorizontally(m_CursorLine
->GetLength()-m_CursorPos
.x
);
909 /// Move cursor to the start of line.
910 void MoveCursorToBeginOfLine()
911 { MoveCursorHorizontally(-m_CursorPos
.x
); }
913 /// get the number of lines in the list
914 size_t GetNumLines() const { return m_numLines
; }
916 /// Returns current cursor position.
917 const wxPoint
&GetCursorPos(wxDC
& WXUNUSED(dc
) ) const
918 { return m_CursorPos
; }
919 const wxPoint
&GetCursorPos() const { return m_CursorPos
; }
920 wxLayoutLine
* GetCursorLine() { return m_CursorLine
; }
922 /// move cursor to the end of text
923 void MoveCursorToEnd()
925 MoveCursorTo(wxPoint(0, GetNumLines() - 1));
926 MoveCursorToEndOfLine();
931 /**@name Editing functions.
932 All of these functions return true on success and false on
935 /// Insert text at current cursor position.
936 bool Insert(wxString
const &text
);
938 /// Insert some other object at current cursor position.
939 bool Insert(wxLayoutObject
*obj
);
941 /// Inserts objects at current cursor positions
942 bool Insert(wxLayoutList
*llist
);
944 /// Inserts a linebreak at current cursor position.
946 /** Wraps the current line. Searches to the left of the cursor to
947 break the line. Does nothing if the cursor position is before
948 the break position parameter.
949 @param column the break position for the line, maximum length
950 @return true if line got broken
952 bool WrapLine(CoordType column
);
954 /** Wraps the complete buffer.
955 @param column the break position for the line, maximum length
956 @return true if line got broken
958 bool WrapAll(CoordType column
);
959 /** This function deletes npos cursor positions.
960 @param npos how many positions
961 @return true if everything got deleted
963 bool Delete(CoordType npos
);
965 /** Delete the next n lines.
966 @param n how many lines to delete
967 @return how many it could not delete
969 int DeleteLines(int n
);
971 /// Delete to end of line.
972 void DeleteToEndOfLine()
974 wxASSERT(m_CursorLine
);
975 Delete(m_CursorLine
->GetLength()-m_CursorPos
.x
);
978 /// Delete to begin of line.
979 void DeleteToBeginOfLine()
981 wxASSERT(m_CursorLine
);
982 CoordType n
= m_CursorPos
.x
;
983 #ifdef WXLAYOUT_DEBUG
984 wxASSERT(MoveCursorHorizontally(-n
));
986 MoveCursorHorizontally(-n
);
991 /** Delete the next word.
995 wxASSERT(m_CursorLine
);
996 m_CursorLine
->DeleteWord(m_CursorPos
.x
);
1001 /** Finds text in this list.
1002 @param needle the text to find
1003 @param cpos the position where to start the search
1004 @return the cursor coord where it was found or (-1,-1)
1006 wxPoint
FindText(const wxString
&needle
, const wxPoint
&cpos
= wxPoint(0,0)) const;
1008 /**@name Formatting options */
1010 /// sets font parameters
1011 void SetFont(int family
, int size
, int style
,
1012 int weight
, int underline
,
1016 /// sets font parameters, colours by name
1017 void SetFont(int family
=-1, int size
= -1, int style
=-1,
1018 int weight
=-1, int underline
= -1,
1019 wxChar
const *fg
= NULL
,
1020 wxChar
const *bg
= NULL
);
1022 /// changes to the next larger font size
1023 inline void SetFontLarger()
1024 { SetFont(-1,(12*m_CurrentStyleInfo
.size
)/10); }
1026 /// changes to the next smaller font size
1027 inline void SetFontSmaller()
1028 { SetFont(-1,(10*m_CurrentStyleInfo
.size
)/12); }
1031 inline void SetFontFamily(int family
) { SetFont(family
); }
1034 inline void SetFontSize(int size
) { SetFont(-1,size
); }
1037 inline void SetFontStyle(int style
) { SetFont(-1,-1,style
); }
1040 inline void SetFontWeight(int weight
) { SetFont(-1,-1,-1,weight
); }
1042 /// toggle underline flag
1043 inline void SetFontUnderline(bool ul
) { SetFont(-1,-1,-1,-1,(int)ul
); }
1045 /// set font colours by name
1046 inline void SetFontColour(wxChar
const *fg
, wxChar
const *bg
= NULL
)
1047 { SetFont(-1,-1,-1,-1,-1,fg
,bg
); }
1049 /// set font colours by colour
1050 inline void SetFontColour(wxColour
*fg
, wxColour
*bg
= NULL
)
1051 { SetFont(-1,-1,-1,-1,-1,fg
,bg
); }
1054 Returns a pointer to the default settings.
1055 This is only valid temporarily and should not be stored
1057 @return the default settings of the list
1059 wxLayoutStyleInfo
&GetDefaultStyleInfo() { return m_DefaultStyleInfo
; }
1060 wxLayoutStyleInfo
&GetStyleInfo() { return m_CurrentStyleInfo
; }
1061 const wxLayoutStyleInfo
&GetStyleInfo() const { return m_CurrentStyleInfo
; }
1062 const wxLayoutStyleInfo
&GetCursorStyleInfo() const { return m_CursorStyleInfo
; }
1064 /// is the current font underlined?
1065 bool IsFontUnderlined() const { return GetCursorStyleInfo().underline
!= 0; }
1067 /// is the current font bold?
1068 bool IsFontBold() const { return GetCursorStyleInfo().weight
== wxBOLD
; }
1070 /// is the current font italic?
1071 bool IsFontItalic() const { return GetCursorStyleInfo().style
== wxITALIC
; }
1073 /// set underline if it was off, turn it off if it was on
1074 void ToggleFontUnderline()
1075 { SetFontUnderline(!IsFontUnderlined()); }
1077 /// make font bold if it was normal or make it normal if it was bold
1078 void ToggleFontWeight()
1079 { SetFontWeight(IsFontBold() ? wxNORMAL
: wxBOLD
); }
1081 /// make font italic if it was normal or make it normal if it was italic
1082 void ToggleFontItalics()
1083 { SetFontStyle(IsFontItalic() ? wxNORMAL
: wxITALIC
); }
1089 /** Draws the complete list on a wxDC.
1090 @param dc the wxDC to draw on
1091 @param offset an optional offset to shift printout
1092 @param top optional y coordinate where to start drawing
1093 @param bottom optional y coordinate where to stop drawing
1094 @param clipStrictly if set, do not draw objects which reach
1095 beyond "bottom". Set this when printing.
1098 const wxPoint
&offset
= wxPoint(0,0),
1099 CoordType top
= -1, CoordType bottom
= -1,
1100 bool clipStrictly
= false);
1102 /** Calculates new layout for the list, like Draw() but does not
1104 @param dc the wxDC to draw on
1105 @param bottom optional y coordinate where to stop calculating
1106 @param forceAll force re-layout of all lines
1107 @param cpos Can hold a cursorposition, and will be overwritten
1108 with the corresponding DC position.
1109 @param csize Will hold the cursor size relating to cpos.
1111 void Layout(wxDC
&dc
, CoordType bottom
= -1, bool forceAll
= false,
1112 wxPoint
*cpos
= NULL
,
1113 wxPoint
*csize
= NULL
);
1115 /** Ensure that the whole list will be recalculate on the next call
1116 to Layout() or Draw().
1117 @param redrawAll true or false to reset it
1119 void ForceTotalLayout(bool redrawAll
= true)
1120 { m_ReLayoutAll
= redrawAll
; }
1122 /** Returns the screen coordinates relating to a given cursor
1123 position and the size of the cursor at that position.
1124 @param dc for which to calculate it
1125 @param cpos Cursor position to look for.
1126 @param csize If non-NULL, will be set to the cursor size.
1127 @return The cursor position on the DC.
1129 wxPoint
GetScreenPos(wxDC
&dc
, const wxPoint
&cpos
, wxPoint
*csize
= NULL
);
1131 /** Calculates new sizes for everything in the list, like Layout()
1132 but this is needed after the list got changed.
1133 @param dc the wxDC to draw on
1134 @param bottom optional y coordinate where to stop calculating
1136 void Recalculate(wxDC
&dc
, CoordType bottom
= -1);
1138 /** Returns the size of the list in screen coordinates.
1139 The return value only makes sense after the list has been
1141 @return a wxPoint holding the maximal x/y coordinates used for
1144 wxPoint
GetSize() const;
1146 /** Returns the cursor position on the screen.
1148 wxPoint
GetCursorScreenPos() const;
1150 /** Draws the cursor.
1151 @param active If true, draw a bold cursor to mark window as
1153 @param translate optional translation of cursor coords on screen
1155 void DrawCursor(wxDC
&dc
,
1157 const wxPoint
& translate
= wxPoint(0,0));
1159 /** This function finds an object belonging to a given screen
1160 position. It assumes that Layout() has been called before.
1161 @param pos screen position
1162 @param cursorPos if non NULL, store cursor position in there
1163 @param found if used, set this to true if we really found an
1164 object, to false if we had to take the object near to it
1165 @return pointer to the object
1167 wxLayoutObject
* FindObjectScreen(wxDC
&dc
,
1169 wxPoint
*cursorPos
= NULL
,
1170 bool *found
= NULL
);
1172 /** Called by the objects to update the update rectangle.
1173 @param x horizontal coordinate to include in rectangle
1174 @param y vertical coordinate to include in rectangle
1176 void SetUpdateRect(CoordType x
, CoordType y
);
1178 /** Called by the objects to update the update rectangle.
1179 @param p a point to include in it
1181 void SetUpdateRect(const wxPoint
&p
)
1182 { SetUpdateRect(p
.x
,p
.y
); }
1184 /// adds the cursor position to the update rectangle
1185 void AddCursorPosToUpdateRect()
1187 #ifndef WXLAYOUT_USE_CARET
1188 SetUpdateRect(m_CursorScreenPos
);
1189 SetUpdateRect(m_CursorScreenPos
+m_CursorSize
);
1190 //#else - the caret will take care of refreshing itself
1191 #endif // !WXLAYOUT_USE_CARET
1194 /// Invalidates the update rectangle.
1195 void InvalidateUpdateRect() { m_UpdateRectValid
= false; }
1197 /// Returns the update rectangle.
1198 const wxRect
*GetUpdateRect() const { return &m_UpdateRect
; }
1201 /// get the current cursor size
1202 const wxPoint
& GetCursorSize() const { return m_CursorSize
; }
1204 /**@name For exporting one object after another. */
1206 /** Returns a pointer to the first line in the list. */
1207 wxLayoutLine
*GetFirstLine()
1209 wxASSERT(m_FirstLine
);
1214 /// Begin selecting text
1215 void StartSelection(const wxPoint
& cpos
= wxPoint(-1,-1),
1216 const wxPoint
& spos
= wxPoint(-1,-1));
1218 // Continue selecting text
1219 void ContinueSelection(const wxPoint
& cpos
= wxPoint(-1,-1),
1220 const wxPoint
& spos
= wxPoint(-1,-1));
1222 /// End selecting text.
1223 void EndSelection(const wxPoint
& cpos
= wxPoint(-1,-1),
1224 const wxPoint
& spos
= wxPoint(-1,-1));
1226 /// Discard the current selection
1227 void DiscardSelection();
1229 /// Are we still selecting text?
1230 bool IsSelecting() const;
1232 /// Is the given point (text coords) selected?
1233 bool IsSelected(const wxPoint
&cursor
) const;
1235 /// Do we have a non null selection?
1236 bool HasSelection() const
1237 { return m_Selection
.m_valid
|| m_Selection
.m_selecting
; }
1239 /** Return the selection as a wxLayoutList.
1240 @param invalidate if true, the selection will be invalidated after this and can no longer be used.
1241 @return Another layout list object holding the selection, must be freed by caller
1243 wxLayoutList
*GetSelection(class wxLayoutDataObject
*wxldo
= NULL
, bool invalidate
= true);
1245 /// Delete selected bit
1246 void DeleteSelection();
1248 wxLayoutList
*Copy(const wxPoint
&from
= wxPoint(0,0),
1249 const wxPoint
&to
= wxPoint(-1,-1));
1251 /// starts highlighting of text for selections
1252 void StartHighlighting(wxDC
&dc
);
1254 /// ends highlighting of text for selections
1255 void EndHighlighting(wxDC
&dc
);
1257 /** Tests whether this layout line is selected and needs
1259 @param line to test for
1260 @param from set to first cursorpos to be highlighted (for returncode == -1)
1261 @param to set to last cursorpos to be highlighted (for returncode == -1)
1262 @return 0 = not selected, 1 = fully selected, -1 = partially
1265 int IsSelected(const wxLayoutLine
*line
, CoordType
*from
, CoordType
*to
);
1267 void ApplyStyle(wxLayoutStyleInfo
const &si
, wxDC
&dc
);
1268 #ifdef WXLAYOUT_DEBUG
1272 // for wxLayoutLine usage only
1273 void IncNumLines() { m_numLines
++; }
1274 void DecNumLines() { m_numLines
--; }
1276 /// get the line by number
1277 wxLayoutLine
*GetLine(CoordType index
) const;
1279 /** Reads objects from a string and inserts them. Returns NULL if
1280 string is empty or a linebreak was found.
1281 @param istr stream to read from, will bee changed
1283 void Read(wxString
&istr
);
1287 void InternalClear();
1289 /// The list of lines.
1290 wxLayoutLine
*m_FirstLine
;
1292 /// The number of lines in the list (store instead recalculating for speed)
1295 /// The update rectangle which needs to be refreshed:
1296 wxRect m_UpdateRect
;
1298 /// Is the update rectangle valid?
1299 bool m_UpdateRectValid
;
1301 /// Shall we auto-format?
1304 /// Shall we re-layout everything?
1307 /**@name Cursor Management */
1309 /// Where the text cursor (column,line) is.
1310 wxPoint m_CursorPos
;
1312 /// Where the cursor should be drawn.
1313 wxPoint m_CursorScreenPos
;
1315 /// The line where the cursor is.
1316 wxLayoutLine
*m_CursorLine
;
1318 /// The size of the cursor.
1319 wxPoint m_CursorSize
;
1321 /// Has the cursor moved (is m_CursorScreenPos up to date)?
1324 #ifdef WXLAYOUT_USE_CARET
1327 #endif // WXLAYOUT_USE_CARET
1330 /// selection.state and begin/end coordinates
1333 Selection() { m_valid
= m_selecting
= m_discarded
= false; }
1337 bool m_discarded
; // may be true only until the next redraw
1339 // returns true if we already have the screen coordinates of the
1340 // selection start and end
1341 bool HasValidScreenCoords() const
1342 { return m_ScreenA
.x
!= -1 && m_ScreenB
.x
!= -1; }
1344 // the start and end of the selection coordinates in pixels
1345 wxPoint m_ScreenA
, m_ScreenB
;
1347 // these coordinates are in text positions, not in pixels
1348 wxPoint m_CursorA
, m_CursorB
;
1350 /** @name Font parameters. */
1352 /// this object manages the fonts for us
1353 wxFontCache m_FontCache
;
1355 /// the default setting:
1356 wxLayoutStyleInfo m_DefaultStyleInfo
;
1358 /// the current setting:
1359 wxLayoutStyleInfo m_CurrentStyleInfo
;
1361 /// the current setting:
1362 wxLayoutStyleInfo m_CursorStyleInfo
;
1366 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1368 The wxLayoutDataObject for exporting data to the clipboard in our
1371 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1372 class wxLayoutDataObject
: public wxCustomDataObject
1375 wxLayoutDataObject()
1377 SetFormat(wxT("application/wxlayoutlist"));
1380 // type safe wrappers
1381 void SetLayoutData(const wxString
& text
)
1382 { SetData(text
.length() + 1, text
.c_str()); }
1384 const wxChar
*GetLayoutData() const { return (const wxChar
*)GetData(); }
1387 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1389 The wxLayoutPrintout object for printing within the wxWidgets print
1392 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1393 /** This class implements a wxPrintout for printing a wxLayoutList within
1394 the wxWidgets printing framework.
1396 class wxLayoutPrintout
: public wxPrintout
1400 @param llist pointer to the wxLayoutList to be printed
1401 @param title title for PS file or windows
1403 wxLayoutPrintout(wxLayoutList
*llist
,
1404 wxString
const & title
=
1405 _T("wxLayout Printout"));
1408 ~wxLayoutPrintout(){};
1410 /** Function which prints the n-th page.
1411 @param page the page number to print
1412 @return bool true if we are not at end of document yet
1414 bool OnPrintPage(int page
);
1415 /** Checks whether page exists in document.
1416 @param page number of page
1417 @return true if page exists
1419 bool HasPage(int page
);
1421 /** Gets called from wxWidgets to find out which pages are existing.
1422 I'm not totally sure about the parameters though.
1423 @param minPage the first page in the document
1424 @param maxPage the last page in the document
1425 @param selPageFrom the first page to be printed
1426 @param selPageTo the last page to be printed
1428 void GetPageInfo(int *minPage
, int *maxPage
,
1429 int *selPageFrom
, int *selPageTo
);
1431 /** This little function scales the DC so that the printout has
1432 roughly the same size as the output on screen.
1433 @param dc the wxDC to scale
1434 @return the scale that was applied
1436 float ScaleDC(wxDC
*dc
);
1439 virtual void DrawHeader(wxDC &dc, wxPoint topleft, wxPoint bottomright, int pageno);
1443 /// The list to print.
1444 wxLayoutList
*m_llist
;
1446 /// Title for PS file or window.
1449 /// The real paper size.
1450 int m_PageHeight
, m_PageWidth
;
1452 /// How much we actually print per page.
1453 int m_PrintoutHeight
;
1455 /// How many pages we need to print.
1458 /// Top left corner where we start printing.