1 /*-*- c++ -*-********************************************************
2 * wxLayoutList.h - a formatted text rendering engine for wxWindows *
4 * (C) 1999-2000 by Karsten Ballüder (ballueder@gmx.net) *
7 *******************************************************************/
14 # pragma interface "wxllist.h"
21 #include "wx/printdlg.h"
22 #include "wx/generic/printps.h"
23 #include "wx/generic/prntdlgg.h"
24 #include "wx/dataobj.h"
26 // skip the following defines if embedded in M application
28 # define WXMENU_LAYOUT_LCLICK 1111
29 # define WXMENU_LAYOUT_RCLICK 1112
30 # define WXMENU_LAYOUT_DBLCLICK 1113
31 #else // for Mahogany only
35 // use the wxWindows caret class instead of home grown cursor whenever possible
37 # undef WXLAYOUT_USE_CARET
38 # define WXLAYOUT_USE_CARET 1
41 // do not enable debug mode within Mahogany unless in debug mode
42 #if defined(__WXDEBUG__) && (( ! defined(M_BASEDIR) )|| defined(DEBUG))
43 # define WXLAYOUT_DEBUG
47 # define WXLO_TRACE(x) wxLogDebug(x)
48 // activate profiling: # define WXLO_PROFILE
50 # define WXLO_TRACE(x)
53 /* Some profiling code: */
54 #if defined (WXLO_PROFILE)
58 # define WXLO_TIMER_DEFINE(x) static struct timeval x
59 # define WXLO_TIMER_START(x) gettimeofday(&x,NULL)
60 # define WXLO_TIMER_STOP(x) { struct timeval y; \
61 gettimeofday(&y,NULL); \
62 x.tv_sec -= y.tv_sec; x.tv_usec -= y.tv_usec; }
63 # define WXLO_TIMER_PRINT(x) wxLogDebug("Timer " #x " elapsed: %ld", \
64 (long)(x.tv_sec * -1000 - x.tv_usec));
66 # define WXLO_TIMER_DEFINE(x)
67 # define WXLO_TIMER_START(x)
68 # define WXLO_TIMER_STOP(x)
69 # define WXLO_TIMER_PRINT(x)
73 #define WXLO_DEBUG_URECT 0
75 #ifndef WXLO_DEFAULTFONTSIZE
76 # define WXLO_DEFAULTFONTSIZE 12
80 # define WXLO_BITMAP_FORMAT wxBITMAP_TYPE_BMP
82 # define WXLO_BITMAP_FORMAT wxBITMAP_TYPE_PNG
85 /// Types of currently supported layout objects.
86 enum wxLayoutObjectType
88 /// illegal object type, should never appear
89 WXLO_TYPE_INVALID
= 0,
91 /// text object, containing normal text
94 /// command object, containing font or colour changes
97 /// icon object, any kind of image
100 /// a linebreak, does not exist as an object
104 /// Type used for coordinates in drawing. Must be signed.
105 typedef long CoordType
;
107 // Forward declarations.
110 class wxLayoutObject
;
112 class WXDLLEXPORT wxCaret
;
113 class WXDLLEXPORT wxColour
;
114 class WXDLLEXPORT wxDC
;
115 class WXDLLEXPORT wxFont
;
117 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
119 The wxLayout objects which make up the lines.
121 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
123 /** The base class defining the interface to each object which can be
124 part of the layout. Each object needs to draw itself and calculate
133 /** This structure can be used to contain data associated with the
135 It is refcounted, so the caller has to do a DecRef() on it
140 UserData() { m_refcount
= 1; }
141 inline void IncRef() { m_refcount
++; }
142 inline void DecRef() { m_refcount
--; if(m_refcount
== 0) delete this;}
143 inline void SetLabel(const wxString
&l
) { m_label
= l
; }
144 inline const wxString
& GetLabel() const { return m_label
; }
149 virtual ~UserData() { wxASSERT(m_refcount
== 0); }
150 /// prevents gcc from generating stupid warnings
151 friend class dummy_UserData
;
154 /// return the type of this object
155 virtual wxLayoutObjectType
GetType() const { return WXLO_TYPE_INVALID
; }
156 /** Calculates the size of an object.
157 @param dc the wxDC to draw on
158 @param llist the wxLayoutList
160 virtual void Layout(wxDC
&dc
, wxLayoutList
*llist
) = 0;
163 @param dc the wxDC to draw on
164 @param coords where to draw the baseline of the object.
165 @param wxllist pointer to wxLayoutList
166 @param begin if !=-1, from which position on to highlight it
167 @param end if begin !=-1, how many positions to highlight it
169 virtual void Draw(wxDC
& /* dc */,
170 wxPoint
const & /* coords */,
171 wxLayoutList
*WXUNUSED(wxllist
),
172 CoordType
WXUNUSED(begin
) = -1,
173 CoordType
WXUNUSED(end
) = -1) { }
175 /** Calculates and returns the size of the object.
176 @param top where to store height above baseline
177 @param bottom where to store height below baseline
178 @return the size of the object's box in pixels
180 virtual wxPoint
GetSize(CoordType
* top
, CoordType
*bottom
) const
181 { *top
= 0; *bottom
= 0; return wxPoint(0,0); }
183 /// Return just the width of the object on the screen.
184 virtual CoordType
GetWidth() const { return 0; }
186 /// returns the number of cursor positions occupied by this object
187 virtual CoordType
GetLength() const { return 1; }
189 /** Returns the cursor offset relating to the screen x position
190 relative to begin of object.
191 @param dc the wxDC to use for calculations
192 @param xpos relative x position from head of object
193 @return cursor coordinate offset
195 virtual CoordType
GetOffsetScreen( wxDC
& WXUNUSED(dc
),
196 CoordType
WXUNUSED(xpos
) ) const
202 wxLayoutObject() { m_UserData
= NULL
; }
204 /// delete the user data
205 virtual ~wxLayoutObject() { if(m_UserData
) m_UserData
->DecRef(); }
207 #ifdef WXLAYOUT_DEBUG
208 virtual wxString
DebugDump() const;
211 /** Tells the object about some user data. This data is associated
212 with the object and will be deleted at destruction time.
213 It is reference counted.
215 void SetUserData(UserData
*data
)
218 m_UserData
->DecRef();
223 m_UserData
->IncRef();
226 /** Return the user data.
227 Increments the object's reference count. When no longer needed,
228 caller must call DecRef() on the pointer returned.
230 UserData
* GetUserData() const { if(m_UserData
) m_UserData
->IncRef(); return m_UserData
; }
232 /** Makes a copy of this object.
234 virtual wxLayoutObject
*Copy() = 0;
236 /** Clipboard support function. Read and write objects to
239 /// Writes the object to the string.
240 virtual void Write(wxString
&ostr
) = 0;
243 @param str stream to read from, will bee changed
244 @return true on success
246 static wxLayoutObject
*Read(wxString
&istr
);
249 /// returns true if the object is shown on the screen (i.e. not cmd object)
250 bool IsVisibleObject() const { return GetType() != WXLO_TYPE_CMD
; }
253 /// optional data for application's use
254 UserData
*m_UserData
;
255 #if defined (M_BASEDIR) && defined (DEBUG)
256 MOBJECT_NAME(wxLayoutObject
)
260 /// Define a list type of wxLayoutObject pointers.
261 KBLIST_DEFINE(wxLayoutObjectList
, wxLayoutObject
);
263 /// An illegal iterator to save typing.
264 #define NULLIT (wxLayoutObjectList::iterator(NULL))
266 /// The iterator type.
267 typedef wxLayoutObjectList::iterator wxLOiterator
;
269 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
273 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
274 /** This class implements a wxLayoutObject holding plain text.
276 class wxLayoutObjectText
: public wxLayoutObject
279 wxLayoutObjectText(const wxString
&txt
= wxEmptyString
);
281 virtual wxLayoutObjectType
GetType() const { return WXLO_TYPE_TEXT
; }
282 virtual void Layout(wxDC
&dc
, wxLayoutList
*llist
);
283 virtual void Draw(wxDC
&dc
, wxPoint
const &coords
,
284 wxLayoutList
*wxllist
,
285 CoordType begin
= -1,
288 /** Calculates and returns the size of the object.
289 @param top where to store height above baseline
290 @param bottom where to store height below baseline
291 @return the size of the object's box in pixels
293 virtual wxPoint
GetSize(CoordType
* top
, CoordType
*bottom
) const;
295 /// Return just the width of the object on the screen.
296 virtual CoordType
GetWidth() const { return m_Width
; }
298 /** Returns the cursor offset relating to the screen x position
299 relative to begin of object.
300 @param dc the wxDC to use for calculations
301 @param xpos relative x position from head of object
302 @return cursor coordinate offset
304 virtual CoordType
GetOffsetScreen(wxDC
&dc
, CoordType xpos
) const;
306 virtual void Write(wxString
&ostr
);
307 static wxLayoutObjectText
*Read(wxString
&istr
);
309 #ifdef WXLAYOUT_DEBUG
310 virtual wxString
DebugDump() const;
313 virtual CoordType
GetLength() const { return wxStrlen(m_Text
.c_str()); }
316 wxString
& GetText() { return m_Text
; }
318 void SetText(wxString
const &text
) { m_Text
= text
; }
319 /** Makes a copy of this object.
321 virtual wxLayoutObject
*Copy();
326 /// size of the box containing text
327 long m_Width
, m_Height
;
329 /// Height above baseline.
332 /// Height below baseline.
336 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
340 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
341 /** This class implements a wxLayoutObject holding a graphic.
343 class wxLayoutObjectIcon
: public wxLayoutObject
346 wxLayoutObjectIcon(wxBitmap
*icon
= NULL
);
347 wxLayoutObjectIcon(wxBitmap
const &icon
);
349 ~wxLayoutObjectIcon() { if(m_Icon
) delete m_Icon
; }
351 virtual wxLayoutObjectType
GetType() const { return WXLO_TYPE_ICON
; }
352 virtual void Layout(wxDC
&dc
, wxLayoutList
*llist
);
353 virtual void Draw(wxDC
&dc
, wxPoint
const &coords
,
354 wxLayoutList
*wxllist
,
355 CoordType begin
= -1,
358 /** Calculates and returns the size of the object.
359 @param top where to store height above baseline
360 @param bottom where to store height below baseline
361 @return the size of the object's box in pixels
363 virtual wxPoint
GetSize(CoordType
* top
, CoordType
*bottom
) const;
365 /// Return just the width of the object on the screen.
366 virtual CoordType
GetWidth() const { return m_Icon
->GetWidth(); }
368 // return a pointer to the icon
369 wxBitmap
*GetIcon() const { return m_Icon
; }
371 /** Makes a copy of this object.
373 virtual wxLayoutObject
*Copy();
374 virtual void Write(wxString
&ostr
);
375 static wxLayoutObjectIcon
*Read(wxString
&istr
);
381 /** This structure holds all formatting information.
383 struct wxLayoutStyleInfo
385 wxLayoutStyleInfo(int ifamily
= -1,
391 wxColour
*bg
= NULL
);
393 wxLayoutStyleInfo
& operator=(const wxLayoutStyleInfo
&right
);
395 wxColour
& GetBGColour() { return m_bg
; }
397 /// Font change parameters.
398 int size
, family
, style
, weight
, underline
;
402 int m_fg_valid
, m_bg_valid
; // bool, but must be int!
406 class wxFontCacheEntry
409 wxFontCacheEntry(int family
, int size
, int style
, int weight
,
412 m_Family
= family
; m_Size
= size
; m_Style
= style
;
413 m_Weight
= weight
; m_Underline
= underline
;
414 m_Font
= new wxFont(m_Size
, m_Family
,
415 m_Style
, m_Weight
, m_Underline
);
418 bool Matches(int family
, int size
, int style
, int weight
,
419 bool underline
) const
421 return size
== m_Size
&& family
== m_Family
422 && style
== m_Style
&& weight
== m_Weight
423 && underline
== m_Underline
;
426 wxFont
& GetFont() { return *m_Font
; }
435 // VZ: I wonder why it doesn't use wxLayoutStyleInfo instead of those?
436 int m_Family
, m_Size
, m_Style
, m_Weight
;
440 KBLIST_DEFINE(wxFCEList
, wxFontCacheEntry
);
445 wxFont
& GetFont(int family
, int size
, int style
, int weight
,
448 wxFont
& GetFont(wxLayoutStyleInfo
const &si
)
450 return GetFont(si
.family
, si
.size
, si
.style
, si
.weight
,
455 wxFCEList m_FontList
;
458 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
462 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
463 /** This class implements a wxLayoutObject holding style change commands.
465 class wxLayoutObjectCmd
: public wxLayoutObject
468 virtual wxLayoutObjectType
GetType() const { return WXLO_TYPE_CMD
; }
469 virtual void Layout(wxDC
&dc
, wxLayoutList
*llist
);
470 virtual void Draw(wxDC
&dc
, wxPoint
const &coords
,
471 wxLayoutList
*wxllist
,
472 CoordType begin
= -1,
475 wxLayoutObjectCmd(int family
= -1,
481 wxColour
*bg
= NULL
);
483 wxLayoutObjectCmd(const wxLayoutStyleInfo
&si
);
484 ~wxLayoutObjectCmd();
485 /** Stores the current style in the styleinfo structure */
486 wxLayoutStyleInfo
* GetStyle() const;
487 /** Makes a copy of this object.
489 virtual wxLayoutObject
*Copy();
490 virtual void Write(wxString
&ostr
);
491 static wxLayoutObjectCmd
*Read(wxString
&istr
);
494 wxLayoutStyleInfo
*m_StyleInfo
;
497 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
499 The wxLayoutLine object
501 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
503 /** This class represents a single line of objects to be displayed.
504 It knows its height and total size and whether it needs to be
506 It has pointers to its first and next line so it can automatically
507 update them as needed.
513 @param prev pointer to previous line or NULL
514 @param next pointer to following line or NULL
515 @param llist pointer to layout list
517 wxLayoutLine(wxLayoutLine
*prev
, wxLayoutList
*llist
);
518 /** This function inserts a new object at cursor position xpos.
519 @param xpos where to insert new object
520 @param obj the object to insert
521 @return true if that xpos existed and the object was inserted
523 bool Insert(CoordType xpos
, wxLayoutObject
*obj
);
525 /** This function inserts text at cursor position xpos.
526 @param xpos where to insert
527 @param text the text to insert
528 @return true if that xpos existed and the object was inserted
530 bool Insert(CoordType xpos
, const wxString
& text
);
532 /** This function appends an object to the line.
533 @param obj the object to insert
535 void Append(wxLayoutObject
* obj
)
538 m_ObjectList
.push_back(obj
);
539 m_Length
+= obj
->GetLength();
542 /** This function prepends an object to the line. */
543 void Prepend(wxLayoutObject
* obj
)
546 m_ObjectList
.push_front(obj
);
547 m_Length
+= obj
->GetLength();
550 /** This function appens the next line to this, i.e. joins the two
553 void MergeNextLine(wxLayoutList
*llist
);
555 /** This function deletes npos cursor positions from position xpos.
556 @param xpos where to delete
557 @param npos how many positions
558 @return number of positions still to be deleted
560 CoordType
Delete(CoordType xpos
, CoordType npos
);
562 /** This function breaks the line at a given cursor position.
563 @param xpos where to break it
564 @return pointer to the new line object replacing the old one
566 wxLayoutLine
*Break(CoordType xpos
, wxLayoutList
*llist
);
568 /** This function wraps the line: breaks it at a suitable point
569 and merges it with the next.
571 @return true if broken
573 bool Wrap(CoordType wrapmargin
, wxLayoutList
*llist
);
575 /** Deletes the next word from this position, including leading
577 This function does not delete over font changes, i.e. a word
578 with formatting instructions in the middle of it is treated as
579 two (three actually!) words. In fact, if the cursor is on a non-text object, that
580 one is treated as a word.
581 @param xpos from where to delete
582 @return true if a word was deleted
584 bool DeleteWord(CoordType npos
);
586 /** Finds a suitable position left to the given column to break the
588 @param column we want to break the line to the left of this
589 @return column for breaking line or -1 if no suitable location found
591 CoordType
GetWrapPosition(CoordType column
);
593 /** Finds the object which covers the cursor position xpos in this
595 @param xpos the column number
596 @param offset where to store the difference between xpos and
598 @return iterator to the object or NULLIT
600 wxLayoutObjectList::iterator
FindObject(CoordType xpos
, CoordType
603 /** Finds the object which covers the screen position xpos in this
605 @param dc the wxDC to use for calculations
606 @param llist the layout list to which this line belongs
607 @param xpos the screen x coordinate
608 @param offset where to store the difference between xpos and
610 @return iterator to the object or NULLIT
612 wxLayoutObjectList::iterator
FindObjectScreen(wxDC
&dc
,
616 bool *found
= NULL
) const ;
618 /** Finds text in this line.
619 @param needle the text to find
620 @param xpos the position where to start the search
621 @return the cursoor coord where it was found or -1
623 CoordType
FindText(const wxString
&needle
, CoordType xpos
= 0) const;
625 /** Get the first object in the list. This is used by the wxlparser
626 functions to export the list.
627 @return iterator to the first object
629 wxLayoutObjectList::iterator
GetFirstObject() const
631 return m_ObjectList
.begin();
634 /// Get the last object in the list.
635 wxLayoutObjectList::iterator
GetLastObject() const
637 return m_ObjectList
.tail();
640 /** Deletes this line, returns pointer to next line.
641 @param update If true, update all following lines.
643 wxLayoutLine
*DeleteLine(bool update
, wxLayoutList
*llist
);
645 /**@name Cursor Management */
647 /** Return the line number of this line.
648 @return the line number
650 inline CoordType
GetLineNumber() const { return m_LineNumber
; }
652 /** Return the length of the line.
653 @return line lenght in cursor positions
655 inline CoordType
GetLength() const { return m_Length
; }
658 /**@name Drawing and Layout */
660 /** Draws the line on a wxDC.
661 @param dc the wxDC to draw on
662 @param llist the wxLayoutList
663 @param offset an optional offset to shift printout
667 const wxPoint
&offset
= wxPoint(0,0)) const;
669 /** Recalculates the positions of objects and the height of the
671 @param dc the wxDC to draw on
672 @param llist th e wxLayoutList
673 @param cursorPos if not NULL, set cursor screen position in there
674 @param cursorSize if not cursorPos != NULL, set cursor size in there
675 @param cursorStyle if non NULL where to store styleinfo for cursor pos
676 @param cx if cursorPos != NULL, the cursor x position
677 @param suppressStyleUpdate FALSe normally, only to suppress updating of m_StyleInfo
679 void Layout(wxDC
&dc
,
681 wxPoint
*cursorPos
= NULL
,
682 wxPoint
*cursorSize
= NULL
,
683 wxLayoutStyleInfo
*cursorStyle
= NULL
,
685 bool suppressStyleUpdate
= false);
687 /** This function finds an object belonging to a given cursor
688 position. It assumes that Layout() has been called before.
689 @param dc the wxDC to use for calculations
690 @param xpos screen x position
691 @param found if non-NULL set to false if we return the last
692 object before the cursor, to true if we really have an object
694 @return pointer to the object
696 wxLayoutObject
* FindObjectScreen(wxDC
&dc
,
700 /** This sets the style info for the beginning of this line.
701 @param si styleinfo structure
703 void ApplyStyle(const wxLayoutStyleInfo
&si
)
704 { m_StyleInfo
= si
; }
708 /**@name List traversal */
710 /// Returns pointer to next line.
711 wxLayoutLine
*GetNextLine() const { return m_Next
; }
713 /// Returns pointer to previous line.
714 wxLayoutLine
*GetPreviousLine() const { return m_Previous
; }
716 /// Sets the link to the next line.
717 void SetNext(wxLayoutLine
*next
)
718 { m_Next
= next
; if(next
) next
->m_Previous
= this; }
720 /// Sets the link to the previous line.
721 void SetPrevious(wxLayoutLine
*previous
)
722 { m_Previous
= previous
; if(previous
) previous
->m_Next
= this; }
725 /// Returns the position of this line on the canvas.
726 wxPoint
GetPosition() const { return m_Position
; }
728 /// Returns the height of this line.
729 CoordType
GetHeight() const { return m_Height
; }
731 /// Returns the width of this line.
732 CoordType
GetWidth() const { return m_Width
; }
734 /// Recalculates the position of this line on the canvas.
735 wxPoint
RecalculatePosition(wxLayoutList
*llist
);
737 /** Copies the contents of this line to another wxLayoutList
738 @param llist the wxLayoutList destination
739 @param from x cursor coordinate where to start
740 @param to x cursor coordinate where to stop, -1 for end of line
742 void Copy(wxLayoutList
*llist
,
746 #ifdef WXLAYOUT_DEBUG
749 wxLayoutStyleInfo
const & GetStyleInfo() const { return m_StyleInfo
; }
751 /// Returns dirty state
752 bool IsDirty() const { return m_Dirty
; }
754 /** Marks this line as diry.
755 @param left xpos from where it is dirty or -1 for all
757 void MarkDirty(CoordType left
= -1)
761 if ( m_updateLeft
== -1 || left
< m_updateLeft
)
766 if(m_Next
) m_Next
->MarkDirty();
769 /// Reset the dirty flag
770 void MarkClean() { m_Dirty
= false; m_updateLeft
= -1; }
773 /// Destructor is private. Use DeleteLine() to remove it.
776 /**@name Functions to let the lines synchronise with each other. */
778 /** Sets the height of this line. Will mark following lines as
780 @param height new height
782 void SetHeight( CoordType height
, wxLayoutList
* WXUNUSED(llist
) )
784 m_Height
= height
; MarkDirty();
787 /** Updates the line numbers. */
793 CoordType m_LineNumber
;
795 /// The line length in cursor positions.
798 /// The total height of the line.
801 /// The total width of the line on screen.
804 /// The baseline for drawing objects
805 CoordType m_BaseLine
;
807 /// The position on the canvas.
810 /// The list of objects
811 wxLayoutObjectList m_ObjectList
;
813 /// Have we been changed since the last layout?
816 /// The coordinate of the left boundary of the update rectangle (if m_Dirty)
817 CoordType m_updateLeft
;
819 /// Pointer to previous line if it exists.
820 wxLayoutLine
*m_Previous
;
822 /// Pointer to next line if it exists.
823 wxLayoutLine
*m_Next
;
825 /// A StyleInfo structure, holding the current settings.
826 wxLayoutStyleInfo m_StyleInfo
;
828 /// Just to suppress gcc compiler warnings.
832 wxLayoutLine(const wxLayoutLine
&);
836 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
838 The wxLayoutList object
840 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
841 /** The wxLayoutList is a list of wxLayoutLine objects. It provides a
842 higher level of abstraction for the text and can generally be considered
843 as representing "the text".
854 #ifdef WXLAYOUT_USE_CARET
855 /// give us the pointer to the caret to use
856 void SetCaret(wxCaret
*caret
) { m_caret
= caret
; }
857 #endif // WXLAYOUT_USE_CARET
860 void Clear(int family
= wxROMAN
,
861 int size
=WXLO_DEFAULTFONTSIZE
,
868 /// Empty: clear the list but leave font settings.
871 /** Enable or disable auto-formatting. Normally, while editing this
872 should be enabled which is the default. While
873 inserting/deleting lots of text, it makes sense to temporarily
875 @param enable true to enable, false to disable
878 void SetAutoFormatting(bool enable
= true)
879 { m_AutoFormat
= enable
; }
881 /**@name Cursor Management */
883 /** Set new cursor position.
884 @param p new position
885 @return bool if it could be set
887 bool MoveCursorTo(wxPoint
const &p
);
889 /** Move cursor up or down.
891 @return bool if it could be moved
893 bool MoveCursorVertically(int n
);
895 /** Move cursor left or right.
896 @param n = number of positions to move
897 @return bool if it could be moved
899 bool MoveCursorHorizontally(int n
);
901 /** Move cursor to the left or right counting in words
902 @param n = number of positions in words
903 @param untilNext: puts the cursor at the start of the next word if true,
904 leaves it at the end of the current one otherwise
905 @return bool if it could be moved
907 bool MoveCursorWord(int n
, bool untilNext
= true);
909 /// Move cursor to end of line.
910 void MoveCursorToEndOfLine()
912 wxASSERT(m_CursorLine
);
913 MoveCursorHorizontally(m_CursorLine
->GetLength()-m_CursorPos
.x
);
916 /// Move cursor to the start of line.
917 void MoveCursorToBeginOfLine()
918 { MoveCursorHorizontally(-m_CursorPos
.x
); }
920 /// get the number of lines in the list
921 size_t GetNumLines() const { return m_numLines
; }
923 /// Returns current cursor position.
924 const wxPoint
&GetCursorPos(wxDC
& WXUNUSED(dc
) ) const
925 { return m_CursorPos
; }
926 const wxPoint
&GetCursorPos() const { return m_CursorPos
; }
927 wxLayoutLine
* GetCursorLine() { return m_CursorLine
; }
929 /// move cursor to the end of text
930 void MoveCursorToEnd()
932 MoveCursorTo(wxPoint(0, GetNumLines() - 1));
933 MoveCursorToEndOfLine();
938 /**@name Editing functions.
939 All of these functions return true on success and false on
942 /// Insert text at current cursor position.
943 bool Insert(wxString
const &text
);
945 /// Insert some other object at current cursor position.
946 bool Insert(wxLayoutObject
*obj
);
948 /// Inserts objects at current cursor positions
949 bool Insert(wxLayoutList
*llist
);
951 /// Inserts a linebreak at current cursor position.
953 /** Wraps the current line. Searches to the left of the cursor to
954 break the line. Does nothing if the cursor position is before
955 the break position parameter.
956 @param column the break position for the line, maximum length
957 @return true if line got broken
959 bool WrapLine(CoordType column
);
961 /** Wraps the complete buffer.
962 @param column the break position for the line, maximum length
963 @return true if line got broken
965 bool WrapAll(CoordType column
);
966 /** This function deletes npos cursor positions.
967 @param npos how many positions
968 @return true if everything got deleted
970 bool Delete(CoordType npos
);
972 /** Delete the next n lines.
973 @param n how many lines to delete
974 @return how many it could not delete
976 int DeleteLines(int n
);
978 /// Delete to end of line.
979 void DeleteToEndOfLine()
981 wxASSERT(m_CursorLine
);
982 Delete(m_CursorLine
->GetLength()-m_CursorPos
.x
);
985 /// Delete to begin of line.
986 void DeleteToBeginOfLine()
988 wxASSERT(m_CursorLine
);
989 CoordType n
= m_CursorPos
.x
;
990 #ifdef WXLAYOUT_DEBUG
991 wxASSERT(MoveCursorHorizontally(-n
));
993 MoveCursorHorizontally(-n
);
998 /** Delete the next word.
1002 wxASSERT(m_CursorLine
);
1003 m_CursorLine
->DeleteWord(m_CursorPos
.x
);
1008 /** Finds text in this list.
1009 @param needle the text to find
1010 @param cpos the position where to start the search
1011 @return the cursor coord where it was found or (-1,-1)
1013 wxPoint
FindText(const wxString
&needle
, const wxPoint
&cpos
= wxPoint(0,0)) const;
1015 /**@name Formatting options */
1017 /// sets font parameters
1018 void SetFont(int family
, int size
, int style
,
1019 int weight
, int underline
,
1023 /// sets font parameters, colours by name
1024 void SetFont(int family
=-1, int size
= -1, int style
=-1,
1025 int weight
=-1, int underline
= -1,
1026 wxChar
const *fg
= NULL
,
1027 wxChar
const *bg
= NULL
);
1029 /// changes to the next larger font size
1030 inline void SetFontLarger()
1031 { SetFont(-1,(12*m_CurrentStyleInfo
.size
)/10); }
1033 /// changes to the next smaller font size
1034 inline void SetFontSmaller()
1035 { SetFont(-1,(10*m_CurrentStyleInfo
.size
)/12); }
1038 inline void SetFontFamily(int family
) { SetFont(family
); }
1041 inline void SetFontSize(int size
) { SetFont(-1,size
); }
1044 inline void SetFontStyle(int style
) { SetFont(-1,-1,style
); }
1047 inline void SetFontWeight(int weight
) { SetFont(-1,-1,-1,weight
); }
1049 /// toggle underline flag
1050 inline void SetFontUnderline(bool ul
) { SetFont(-1,-1,-1,-1,(int)ul
); }
1052 /// set font colours by name
1053 inline void SetFontColour(wxChar
const *fg
, wxChar
const *bg
= NULL
)
1054 { SetFont(-1,-1,-1,-1,-1,fg
,bg
); }
1056 /// set font colours by colour
1057 inline void SetFontColour(wxColour
*fg
, wxColour
*bg
= NULL
)
1058 { SetFont(-1,-1,-1,-1,-1,fg
,bg
); }
1061 Returns a pointer to the default settings.
1062 This is only valid temporarily and should not be stored
1064 @return the default settings of the list
1066 wxLayoutStyleInfo
&GetDefaultStyleInfo() { return m_DefaultStyleInfo
; }
1067 wxLayoutStyleInfo
&GetStyleInfo() { return m_CurrentStyleInfo
; }
1068 const wxLayoutStyleInfo
&GetStyleInfo() const { return m_CurrentStyleInfo
; }
1069 const wxLayoutStyleInfo
&GetCursorStyleInfo() const { return m_CursorStyleInfo
; }
1071 /// is the current font underlined?
1072 bool IsFontUnderlined() const { return GetCursorStyleInfo().underline
!= 0; }
1074 /// is the current font bold?
1075 bool IsFontBold() const { return GetCursorStyleInfo().weight
== wxBOLD
; }
1077 /// is the current font italic?
1078 bool IsFontItalic() const { return GetCursorStyleInfo().style
== wxITALIC
; }
1080 /// set underline if it was off, turn it off if it was on
1081 void ToggleFontUnderline()
1082 { SetFontUnderline(!IsFontUnderlined()); }
1084 /// make font bold if it was normal or make it normal if it was bold
1085 void ToggleFontWeight()
1086 { SetFontWeight(IsFontBold() ? wxNORMAL
: wxBOLD
); }
1088 /// make font italic if it was normal or make it normal if it was italic
1089 void ToggleFontItalics()
1090 { SetFontStyle(IsFontItalic() ? wxNORMAL
: wxITALIC
); }
1096 /** Draws the complete list on a wxDC.
1097 @param dc the wxDC to draw on
1098 @param offset an optional offset to shift printout
1099 @param top optional y coordinate where to start drawing
1100 @param bottom optional y coordinate where to stop drawing
1101 @param clipStrictly if set, do not draw objects which reach
1102 beyond "bottom". Set this when printing.
1105 const wxPoint
&offset
= wxPoint(0,0),
1106 CoordType top
= -1, CoordType bottom
= -1,
1107 bool clipStrictly
= false);
1109 /** Calculates new layout for the list, like Draw() but does not
1111 @param dc the wxDC to draw on
1112 @param bottom optional y coordinate where to stop calculating
1113 @param forceAll force re-layout of all lines
1114 @param cpos Can hold a cursorposition, and will be overwritten
1115 with the corresponding DC position.
1116 @param csize Will hold the cursor size relating to cpos.
1118 void Layout(wxDC
&dc
, CoordType bottom
= -1, bool forceAll
= false,
1119 wxPoint
*cpos
= NULL
,
1120 wxPoint
*csize
= NULL
);
1122 /** Ensure that the whole list will be recalculate on the next call
1123 to Layout() or Draw().
1124 @param redrawAll true or false to reset it
1126 void ForceTotalLayout(bool redrawAll
= true)
1127 { m_ReLayoutAll
= redrawAll
; }
1129 /** Returns the screen coordinates relating to a given cursor
1130 position and the size of the cursor at that position.
1131 @param dc for which to calculate it
1132 @param cpos Cursor position to look for.
1133 @param csize If non-NULL, will be set to the cursor size.
1134 @return The cursor position on the DC.
1136 wxPoint
GetScreenPos(wxDC
&dc
, const wxPoint
&cpos
, wxPoint
*csize
= NULL
);
1138 /** Calculates new sizes for everything in the list, like Layout()
1139 but this is needed after the list got changed.
1140 @param dc the wxDC to draw on
1141 @param bottom optional y coordinate where to stop calculating
1143 void Recalculate(wxDC
&dc
, CoordType bottom
= -1);
1145 /** Returns the size of the list in screen coordinates.
1146 The return value only makes sense after the list has been
1148 @return a wxPoint holding the maximal x/y coordinates used for
1151 wxPoint
GetSize() const;
1153 /** Returns the cursor position on the screen.
1155 wxPoint
GetCursorScreenPos() const;
1157 /** Draws the cursor.
1158 @param active If true, draw a bold cursor to mark window as
1160 @param translate optional translation of cursor coords on screen
1162 void DrawCursor(wxDC
&dc
,
1164 const wxPoint
& translate
= wxPoint(0,0));
1166 /** This function finds an object belonging to a given screen
1167 position. It assumes that Layout() has been called before.
1168 @param pos screen position
1169 @param cursorPos if non NULL, store cursor position in there
1170 @param found if used, set this to true if we really found an
1171 object, to false if we had to take the object near to it
1172 @return pointer to the object
1174 wxLayoutObject
* FindObjectScreen(wxDC
&dc
,
1176 wxPoint
*cursorPos
= NULL
,
1177 bool *found
= NULL
);
1179 /** Called by the objects to update the update rectangle.
1180 @param x horizontal coordinate to include in rectangle
1181 @param y vertical coordinate to include in rectangle
1183 void SetUpdateRect(CoordType x
, CoordType y
);
1185 /** Called by the objects to update the update rectangle.
1186 @param p a point to include in it
1188 void SetUpdateRect(const wxPoint
&p
)
1189 { SetUpdateRect(p
.x
,p
.y
); }
1191 /// adds the cursor position to the update rectangle
1192 void AddCursorPosToUpdateRect()
1194 #ifndef WXLAYOUT_USE_CARET
1195 SetUpdateRect(m_CursorScreenPos
);
1196 SetUpdateRect(m_CursorScreenPos
+m_CursorSize
);
1197 //#else - the caret will take care of refreshing itself
1198 #endif // !WXLAYOUT_USE_CARET
1201 /// Invalidates the update rectangle.
1202 void InvalidateUpdateRect() { m_UpdateRectValid
= false; }
1204 /// Returns the update rectangle.
1205 const wxRect
*GetUpdateRect() const { return &m_UpdateRect
; }
1208 /// get the current cursor size
1209 const wxPoint
& GetCursorSize() const { return m_CursorSize
; }
1211 /**@name For exporting one object after another. */
1213 /** Returns a pointer to the first line in the list. */
1214 wxLayoutLine
*GetFirstLine()
1216 wxASSERT(m_FirstLine
);
1221 /// Begin selecting text
1222 void StartSelection(const wxPoint
& cpos
= wxPoint(-1,-1),
1223 const wxPoint
& spos
= wxPoint(-1,-1));
1225 // Continue selecting text
1226 void ContinueSelection(const wxPoint
& cpos
= wxPoint(-1,-1),
1227 const wxPoint
& spos
= wxPoint(-1,-1));
1229 /// End selecting text.
1230 void EndSelection(const wxPoint
& cpos
= wxPoint(-1,-1),
1231 const wxPoint
& spos
= wxPoint(-1,-1));
1233 /// Discard the current selection
1234 void DiscardSelection();
1236 /// Are we still selecting text?
1237 bool IsSelecting() const;
1239 /// Is the given point (text coords) selected?
1240 bool IsSelected(const wxPoint
&cursor
) const;
1242 /// Do we have a non null selection?
1243 bool HasSelection() const
1244 { return m_Selection
.m_valid
|| m_Selection
.m_selecting
; }
1246 /** Return the selection as a wxLayoutList.
1247 @param invalidate if true, the selection will be invalidated after this and can no longer be used.
1248 @return Another layout list object holding the selection, must be freed by caller
1250 wxLayoutList
*GetSelection(class wxLayoutDataObject
*wxldo
= NULL
, bool invalidate
= true);
1252 /// Delete selected bit
1253 void DeleteSelection();
1255 wxLayoutList
*Copy(const wxPoint
&from
= wxPoint(0,0),
1256 const wxPoint
&to
= wxPoint(-1,-1));
1258 /// starts highlighting of text for selections
1259 void StartHighlighting(wxDC
&dc
);
1261 /// ends highlighting of text for selections
1262 void EndHighlighting(wxDC
&dc
);
1264 /** Tests whether this layout line is selected and needs
1266 @param line to test for
1267 @param from set to first cursorpos to be highlighted (for returncode == -1)
1268 @param to set to last cursorpos to be highlighted (for returncode == -1)
1269 @return 0 = not selected, 1 = fully selected, -1 = partially
1272 int IsSelected(const wxLayoutLine
*line
, CoordType
*from
, CoordType
*to
);
1274 void ApplyStyle(wxLayoutStyleInfo
const &si
, wxDC
&dc
);
1275 #ifdef WXLAYOUT_DEBUG
1279 // for wxLayoutLine usage only
1280 void IncNumLines() { m_numLines
++; }
1281 void DecNumLines() { m_numLines
--; }
1283 /// get the line by number
1284 wxLayoutLine
*GetLine(CoordType index
) const;
1286 /** Reads objects from a string and inserts them. Returns NULL if
1287 string is empty or a linebreak was found.
1288 @param istr stream to read from, will bee changed
1290 void Read(wxString
&istr
);
1294 void InternalClear();
1296 /// The list of lines.
1297 wxLayoutLine
*m_FirstLine
;
1299 /// The number of lines in the list (store instead recalculating for speed)
1302 /// The update rectangle which needs to be refreshed:
1303 wxRect m_UpdateRect
;
1305 /// Is the update rectangle valid?
1306 bool m_UpdateRectValid
;
1308 /// Shall we auto-format?
1311 /// Shall we re-layout everything?
1314 /**@name Cursor Management */
1316 /// Where the text cursor (column,line) is.
1317 wxPoint m_CursorPos
;
1319 /// Where the cursor should be drawn.
1320 wxPoint m_CursorScreenPos
;
1322 /// The line where the cursor is.
1323 wxLayoutLine
*m_CursorLine
;
1325 /// The size of the cursor.
1326 wxPoint m_CursorSize
;
1328 /// Has the cursor moved (is m_CursorScreenPos up to date)?
1331 #ifdef WXLAYOUT_USE_CARET
1334 #endif // WXLAYOUT_USE_CARET
1337 /// selection.state and begin/end coordinates
1340 Selection() { m_valid
= m_selecting
= m_discarded
= false; }
1344 bool m_discarded
; // may be true only until the next redraw
1346 // returns true if we already have the screen coordinates of the
1347 // selection start and end
1348 bool HasValidScreenCoords() const
1349 { return m_ScreenA
.x
!= -1 && m_ScreenB
.x
!= -1; }
1351 // the start and end of the selection coordinates in pixels
1352 wxPoint m_ScreenA
, m_ScreenB
;
1354 // these coordinates are in text positions, not in pixels
1355 wxPoint m_CursorA
, m_CursorB
;
1357 /** @name Font parameters. */
1359 /// this object manages the fonts for us
1360 wxFontCache m_FontCache
;
1362 /// the default setting:
1363 wxLayoutStyleInfo m_DefaultStyleInfo
;
1365 /// the current setting:
1366 wxLayoutStyleInfo m_CurrentStyleInfo
;
1368 /// the current setting:
1369 wxLayoutStyleInfo m_CursorStyleInfo
;
1373 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1375 The wxLayoutDataObject for exporting data to the clipboard in our
1378 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1379 class wxLayoutDataObject
: public wxCustomDataObject
1382 wxLayoutDataObject()
1384 SetFormat(wxT("application/wxlayoutlist"));
1387 // type safe wrappers
1388 void SetLayoutData(const wxString
& text
)
1389 { SetData(text
.length() + 1, text
.c_str()); }
1391 const wxChar
*GetLayoutData() const { return (const wxChar
*)GetData(); }
1394 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1396 The wxLayoutPrintout object for printing within the wxWindows print
1399 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1400 /** This class implements a wxPrintout for printing a wxLayoutList within
1401 the wxWindows printing framework.
1403 class wxLayoutPrintout
: public wxPrintout
1407 @param llist pointer to the wxLayoutList to be printed
1408 @param title title for PS file or windows
1410 wxLayoutPrintout(wxLayoutList
*llist
,
1411 wxString
const & title
=
1412 _T("wxLayout Printout"));
1415 ~wxLayoutPrintout();
1417 /** Function which prints the n-th page.
1418 @param page the page number to print
1419 @return bool true if we are not at end of document yet
1421 bool OnPrintPage(int page
);
1422 /** Checks whether page exists in document.
1423 @param page number of page
1424 @return true if page exists
1426 bool HasPage(int page
);
1428 /** Gets called from wxWindows to find out which pages are existing.
1429 I'm not totally sure about the parameters though.
1430 @param minPage the first page in the document
1431 @param maxPage the last page in the document
1432 @param selPageFrom the first page to be printed
1433 @param selPageTo the last page to be printed
1435 void GetPageInfo(int *minPage
, int *maxPage
,
1436 int *selPageFrom
, int *selPageTo
);
1438 /** This little function scales the DC so that the printout has
1439 roughly the same size as the output on screen.
1440 @param dc the wxDC to scale
1441 @return the scale that was applied
1443 float ScaleDC(wxDC
*dc
);
1446 virtual void DrawHeader(wxDC &dc, wxPoint topleft, wxPoint bottomright, int pageno);
1450 /// The list to print.
1451 wxLayoutList
*m_llist
;
1453 /// Title for PS file or window.
1456 /// The real paper size.
1457 int m_PageHeight
, m_PageWidth
;
1459 /// How much we actually print per page.
1460 int m_PrintoutHeight
;
1462 /// How many pages we need to print.
1465 /// Top left corner where we start printing.