1 /*-*- c++ -*-********************************************************
2 * wxLayoutList.h - a formatted text rendering engine for wxWindows *
4 * (C) 1999 by Karsten Ballüder (Ballueder@usa.net) *
7 *******************************************************************/
14 # pragma interface "wxllist.h"
21 #include "wx/printdlg.h"
22 #include "wx/generic/printps.h"
23 #include "wx/generic/prntdlgg.h"
25 // skip the following defines if embedded in M application
27 # define WXMENU_LAYOUT_LCLICK 1111
28 # define WXMENU_LAYOUT_RCLICK 1112
29 # define WXMENU_LAYOUT_DBLCLICK 1113
33 # define WXLAYOUT_DEBUG
36 #ifndef WXLO_DEFAULTFONTSIZE
37 # define WXLO_DEFAULTFONTSIZE 12
40 /// Types of currently supported layout objects.
41 enum wxLayoutObjectType
43 /// illegal object type, should never appear
44 WXLO_TYPE_INVALID
= 0,
45 /// text object, containing normal text
47 /// command object, containing font or colour changes
49 /// icon object, any kind of image
53 /// Type used for coordinates in drawing. Must be signed.
54 typedef long CoordType
;
56 // Forward declarations.
64 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
66 The wxLayout objects which make up the lines.
68 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
70 /** The base class defining the interface to each object which can be
71 part of the layout. Each object needs to draw itself and calculate
77 /// This structure can be used to contain data associated with the object.
80 virtual ~UserData() { }
83 /// return the type of this object
84 virtual wxLayoutObjectType
GetType(void) const { return WXLO_TYPE_INVALID
; }
85 /** Calculates the size of an object.
86 @param dc the wxDC to draw on
88 virtual void Layout(wxDC
&) = 0;
91 @param dc the wxDC to draw on
92 @param coords where to draw the baseline of the object.
94 virtual void Draw(wxDC
& /* dc */, wxPoint
const & /* coords */) { }
96 /** Calculates and returns the size of the object.
97 @param top where to store height above baseline
98 @param bottom where to store height below baseline
99 @return the size of the object's box in pixels
101 virtual wxPoint
GetSize(CoordType
* top
, CoordType
*bottom
) const
102 { *top
= 0; *bottom
= 0; return wxPoint(0,0); }
104 /// Return just the width of the object on the screen.
105 virtual CoordType
GetWidth(void) const { return 0; }
106 /// returns the number of cursor positions occupied by this object
107 virtual CoordType
GetLength(void) const { return 1; }
110 wxLayoutObject() { m_UserData
= NULL
; }
111 /// delete the user data
112 virtual ~wxLayoutObject() { if(m_UserData
) delete m_UserData
; }
114 #ifdef WXLAYOUT_DEBUG
115 virtual void Debug(void);
118 /** Tells the object about some user data. This data is associated
119 with the object and will be deleted at destruction time.
121 void SetUserData(UserData
*data
) { m_UserData
= data
; }
122 /** Return the user data. */
123 void * GetUserData(void) const { return m_UserData
; }
126 /// optional data for application's use
127 UserData
*m_UserData
;
130 /// Define a list type of wxLayoutObject pointers.
131 KBLIST_DEFINE(wxLayoutObjectList
, wxLayoutObject
);
133 /// An illegal iterator to save typing.
134 #define NULLIT (wxLayoutObjectList::iterator(NULL))
135 /// The iterator type.
136 #define wxLOiterator wxLayoutObjectList::iterator
138 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
142 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
143 /** This class implements a wxLayoutObject holding plain text.
145 class wxLayoutObjectText
: public wxLayoutObject
148 wxLayoutObjectText(const wxString
&txt
);
150 virtual wxLayoutObjectType
GetType(void) const { return WXLO_TYPE_TEXT
; }
151 virtual void Layout(wxDC
&dc
);
152 virtual void Draw(wxDC
&dc
, wxPoint
const &coords
);
153 /** Calculates and returns the size of the object.
154 @param top where to store height above baseline
155 @param bottom where to store height below baseline
156 @return the size of the object's box in pixels
158 virtual wxPoint
GetSize(CoordType
* top
, CoordType
*bottom
) const;
159 /// Return just the width of the object on the screen.
160 virtual CoordType
GetWidth(void) const { return m_Width
; }
162 #ifdef WXLAYOUT_DEBUG
163 virtual void Debug(void);
166 virtual CoordType
GetLength(void) const { return strlen(m_Text
.c_str()); }
169 wxString
& GetText(void) { return m_Text
; }
170 void SetText(wxString
const &text
) { m_Text
= text
; }
174 /// size of the box containing text
175 long m_Width
, m_Height
;
176 /// Height above baseline.
178 /// Height below baseline.
182 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
186 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
187 /** This class implements a wxLayoutObject holding a graphic.
189 class wxLayoutObjectIcon
: public wxLayoutObject
192 wxLayoutObjectIcon(wxBitmap
*icon
);
193 wxLayoutObjectIcon(wxBitmap
const &icon
);
195 ~wxLayoutObjectIcon() { delete m_Icon
; }
197 virtual wxLayoutObjectType
GetType(void) const { return WXLO_TYPE_ICON
; }
198 virtual void Layout(wxDC
&dc
);
199 virtual void Draw(wxDC
&dc
, wxPoint
const &coords
);
201 /** Calculates and returns the size of the object.
202 @param top where to store height above baseline
203 @param bottom where to store height below baseline
204 @return the size of the object's box in pixels
206 virtual wxPoint
GetSize(CoordType
* top
, CoordType
*bottom
) const;
207 /// Return just the width of the object on the screen.
208 virtual CoordType
GetWidth(void) const { return m_Icon
->GetWidth(); }
214 /// for export to html:
215 struct wxLayoutStyleInfo
219 family
= -1; // this marks the styleinfo as uninitialised
221 int size
, family
, style
, weight
;
223 unsigned fg_red
, fg_green
, fg_blue
;
224 unsigned bg_red
, bg_green
, bg_blue
;
227 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
231 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
232 /** This class implements a wxLayoutObject holding style change commands.
234 class wxLayoutObjectCmd
: public wxLayoutObject
237 virtual wxLayoutObjectType
GetType(void) const { return WXLO_TYPE_CMD
; }
238 virtual void Layout(wxDC
&dc
);
239 virtual void Draw(wxDC
&dc
, wxPoint
const &coords
);
240 wxLayoutObjectCmd(int size
, int family
, int style
, int weight
,
242 wxColour
const *fg
, wxColour
const *bg
);
243 ~wxLayoutObjectCmd();
244 /** Stores the current style in the styleinfo structure */
245 void GetStyle(wxLayoutStyleInfo
*si
) const;
246 /// return the background colour for setting colour of window
247 wxColour
const *GetBGColour(void) const { return m_ColourBG
; }
251 /// foreground colour
252 wxColour
const *m_ColourFG
;
253 /// background colour
254 wxColour
const *m_ColourBG
;
257 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
259 The wxLayoutLine object
261 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
263 /** This class represents a single line of objects to be displayed.
264 It knows its height and total size and whether it needs to be
266 It has pointers to its first and next line so it can automatically
267 update them as needed.
273 @param prev pointer to previous line or NULL
274 @param next pointer to following line or NULL
276 wxLayoutLine(wxLayoutLine
*prev
);
277 /** This function inserts a new object at cursor position xpos.
278 @param xpos where to insert new object
279 @param obj the object to insert
280 @return true if that xpos existed and the object was inserted
282 bool Insert(CoordType xpos
, wxLayoutObject
*obj
);
284 /** This function inserts text at cursor position xpos.
285 @param xpos where to insert
286 @param text the text to insert
287 @return true if that xpos existed and the object was inserted
289 bool Insert(CoordType xpos
, wxString text
);
291 /** This function appends an object to the line.
292 @param obj the object to insert
294 void Append(wxLayoutObject
* obj
)
297 m_ObjectList
.push_back(obj
);
298 m_Length
+= obj
->GetLength();
301 /** This function appens the next line to this, i.e. joins the two
304 void MergeNextLine(void);
306 /** This function deletes npos cursor positions from position xpos.
307 @param xpos where to delete
308 @param npos how many positions
309 @return number of positions still to be deleted
311 CoordType
Delete(CoordType xpos
, CoordType npos
);
313 /** This function breaks the line at a given cursor position.
314 @param xpos where to break it
315 @return pointer to the new line object replacing the old one
317 wxLayoutLine
*Break(CoordType xpos
);
319 /** Deletes the next word from this position, including leading
321 This function does not delete over font changes, i.e. a word
322 with formatting instructions in the middle of it is treated as
323 two (three actually!) words. In fact, if the cursor is on a non-text object, that
324 one is treated as a word.
325 @param xpos from where to delete
326 @return true if a word was deleted
328 bool DeleteWord(CoordType npos
);
330 /** Finds the object which covers the cursor position xpos in this
332 @param xpos the column number
333 @param offset where to store the difference between xpos and
335 @return iterator to the object or NULLIT
337 wxLayoutObjectList::iterator
FindObject(CoordType xpos
, CoordType
340 /** Get the first object in the list. This is used by the wxlparser
341 functions to export the list.
342 @return iterator to the first object
344 wxLayoutObjectList::iterator
GetFirstObject(void)
346 return m_ObjectList
.begin();
349 /** Deletes this line, returns pointer to next line.
350 @param update If true, update all following lines.
352 wxLayoutLine
*DeleteLine(bool update
);
354 /**@name Cursor Management */
356 /** Return the line number of this line.
357 @return the line number
359 CoordType
GetLineNumber(void) const { return m_LineNumber
; }
360 /** Return the length of the line.
361 @return line lenght in cursor positions
363 CoordType
GetLength(void) const { return m_Length
; }
366 /**@name Drawing and Layout */
368 /** Draws the line on a wxDC.
369 @param dc the wxDC to draw on
370 @param offset an optional offset to shift printout
372 void Draw(wxDC
&dc
, const wxPoint
&offset
= wxPoint(0,0)) const;
374 /** Recalculates the positions of objects and the height of the
376 @param dc the wxDC to draw on
377 @param cursorPos if not NULL, set cursor screen position in there
378 @param cursorSize if not cursorPos != NULL, set cursor size in there
379 @param cx if cursorPos != NULL, the cursor x position
381 void Layout(wxDC
&dc
,
382 wxPoint
*cursorPos
= NULL
,
383 wxPoint
*cursorSize
= NULL
,
385 /** This function finds an object belonging to a given cursor
386 position. It assumes that Layout() has been called before.
387 @param xpos screen x position
388 @return pointer to the object
390 wxLayoutObject
* FindObject(CoordType xpos
);
393 /**@name List traversal */
395 /// Returns pointer to next line.
396 wxLayoutLine
*GetNextLine(void) const { return m_Next
; }
397 /// Returns pointer to previous line.
398 wxLayoutLine
*GetPreviousLine(void) const { return m_Previous
; }
399 /// Sets the link to the next line.
400 void SetNext(wxLayoutLine
*next
)
401 { m_Next
= next
; if(next
) next
->m_Previous
= this; }
402 /// Sets the link to the previous line.
403 void SetPrevious(wxLayoutLine
*previous
)
404 { m_Previous
= previous
; if(previous
) previous
->m_Next
= this; }
407 /// Returns the position of this line on the canvas.
408 wxPoint
GetPosition(void) const { return m_Position
; }
409 /// Returns the height of this line.
410 CoordType
GetHeight(void) const { return m_Height
; }
411 /// Returns the width of this line.
412 CoordType
GetWidth(void) const { return m_Width
; }
413 /** This will recalculate the position and size of this line.
414 If called recursively it will abort if the position of an
415 object is unchanged, assuming that none of the following
416 objects need to move.
417 @param recurse if greater 0 then it will be used as the
418 minimum(!) recursion level, continue with all lines till the end of
419 the list or until the coordinates no longer changed.
421 void RecalculatePositions(int recurse
= 0);
423 /// Destructor is private. Use DeleteLine() to remove it.
426 /**@name Functions to let the lines synchronise with each other. */
428 /** Sets the height of this line. Will mark following lines as
430 @param height new height
432 void SetHeight(CoordType height
)
433 { m_Height
= height
; RecalculatePositions(true); }
434 /// Recalculates the position of this line on the canvas.
435 wxPoint
RecalculatePosition(void);
437 /** Moves the linenumbers one on, because a line has been inserted
439 @param delta either +1 or -1
441 void MoveLines(int delta
)
443 m_LineNumber
+= delta
;
444 if(m_Next
) m_Next
->MoveLines(delta
);
449 CoordType m_LineNumber
;
450 /// The line length in cursor positions.
452 /// The total height of the line.
454 /// The total width of the line on screen.
456 /// The baseline for drawing objects
457 CoordType m_BaseLine
;
458 /// The position on the canvas.
460 /// The list of objects
461 wxLayoutObjectList m_ObjectList
;
462 /// Have we been changed since the last layout?
464 /// Pointer to previous line if it exists.
465 wxLayoutLine
*m_Previous
;
466 /// Pointer to next line if it exists.
467 wxLayoutLine
*m_Next
;
468 /// Just to suppress gcc compiler warnings.
473 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
475 The wxLayoutList object
477 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
478 /** The wxLayoutList is a list of wxLayoutLine objects. It provides a
479 higher level of abstraction for the text and can generally be considered
480 as representing "the text".
491 void Clear(int family
= wxROMAN
,
492 int size
=WXLO_DEFAULTFONTSIZE
,
496 char const *fg
="black",
497 char const *bg
="white");
499 /**@name Cursor Management */
501 /** Set new cursor position.
502 @param p new position
503 @return bool if it could be set
505 bool MoveCursorTo(wxPoint
const &p
);
506 /** Move cursor up or down.
508 @return bool if it could be moved
510 bool MoveCursorVertically(int n
);
511 /** Move cursor left or right.
513 @return bool if it could be moved
515 bool MoveCursorHorizontally(int n
);
517 /// Move cursor to end of line.
518 void MoveCursorToEndOfLine(void)
520 wxASSERT(m_CursorLine
);
521 MoveCursorHorizontally(m_CursorLine
->GetLength()-m_CursorPos
.x
);
524 /// Move cursor to begin of line.
525 void MoveCursorToBeginOfLine(void)
526 { MoveCursorHorizontally(-m_CursorPos
.x
); }
528 /// Returns current cursor position.
529 wxPoint
GetCursorPos(void) const { return m_CursorPos
; }
532 /**@name Editing functions.
533 All of these functions return true on success and false on
536 /// Insert text at current cursor position.
537 bool Insert(wxString
const &text
);
538 /// Insert some other object at current cursor position.
539 bool Insert(wxLayoutObject
*obj
);
540 /// Inserts a linebreak at current cursor position.
541 bool LineBreak(void);
542 /** This function deletes npos cursor positions.
543 @param npos how many positions
544 @return true if everything got deleted
546 bool Delete(CoordType npos
);
548 /** Delete the next n lines.
549 @param n how many lines to delete
550 @return how many it could not delete
552 int DeleteLines(int n
);
554 /// Delete to end of line.
555 void DeleteToEndOfLine(void)
557 wxASSERT(m_CursorLine
);
558 Delete(m_CursorLine
->GetLength()-m_CursorPos
.x
);
560 /// Delete to begin of line.
561 void DeleteToBeginOfLine(void)
563 wxASSERT(m_CursorLine
);
564 CoordType n
= m_CursorPos
.x
;
565 #ifdef WXLAYOUT_DEBUG
566 wxASSERT(MoveCursorHorizontally(-n
));
568 MoveCursorHorizontally(-n
);
573 /** Delete the next word.
575 void DeleteWord(void)
577 wxASSERT(m_CursorLine
);
578 m_CursorLine
->DeleteWord(m_CursorPos
.x
);
583 /**@name Formatting options */
585 /// sets font parameters
586 void SetFont(int family
, int size
, int style
,
587 int weight
, int underline
,
590 /// sets font parameters, colours by name
591 void SetFont(int family
=-1, int size
= -1, int style
=-1,
592 int weight
=-1, int underline
= -1,
593 char const *fg
= NULL
,
594 char const *bg
= NULL
);
595 /// changes to the next larger font size
596 inline void SetFontLarger(void)
597 { SetFont(-1,(12*m_FontPtSize
)/10); }
598 /// changes to the next smaller font size
599 inline void SetFontSmaller(void)
600 { SetFont(-1,(10*m_FontPtSize
)/12); }
603 inline void SetFontFamily(int family
) { SetFont(family
); }
605 inline void SetFontSize(int size
) { SetFont(-1,size
); }
607 inline void SetFontStyle(int style
) { SetFont(-1,-1,style
); }
609 inline void SetFontWeight(int weight
) { SetFont(-1,-1,-1,weight
); }
610 /// toggle underline flag
611 inline void SetFontUnderline(bool ul
) { SetFont(-1,-1,-1,-1,(int)ul
); }
612 /// set font colours by name
613 inline void SetFontColour(char const *fg
, char const *bg
= NULL
) { SetFont(-1,-1,-1,-1,-1,fg
,bg
); }
615 Returns a pointer to the default settings.
616 This is only valid temporarily and should not be stored
618 @return the default settings of the list
620 wxLayoutObjectCmd
const *GetDefaults(void) const { return m_DefaultSetting
; }
625 /** Draws the complete list on a wxDC.
626 @param dc the wxDC to draw on
627 @param offset an optional offset to shift printout
628 @param top optional y coordinate where to start drawing
629 @param bottom optional y coordinate where to stop drawing
631 void Draw(wxDC
&dc
, const wxPoint
&offset
= wxPoint(0,0),
632 CoordType top
= -1, CoordType bottom
= -1) const;
634 /** Calculates new layout for the list, like Draw() but does not
636 @param dc the wxDC to draw on
637 @param bottom optional y coordinate where to stop calculating
639 void Layout(wxDC
&dc
, CoordType bottom
= -1) const;
640 /** Returns the size of the list in screen coordinates.
641 The return value only makes sense after the list has been
643 @return a wxPoint holding the maximal x/y coordinates used for
646 wxPoint
GetSize(void) const;
648 /** Returns the cursor position on the screen.
649 @return cursor position in pixels
651 wxPoint
GetCursorScreenPos(void) const
652 { return m_CursorScreenPos
; }
654 /** Draws the cursor.
655 @param active If true, draw a bold cursor to mark window as
657 @param translate optional translation of cursor coords on screen
659 void DrawCursor(wxDC
&dc
,
661 const wxPoint
& translate
= wxPoint(0,0));
663 /** This function finds an object belonging to a given cursor
664 position. It assumes that Layout() has been called before.
665 @param pos screen position
666 @return pointer to the object
668 wxLayoutObject
* FindObject(wxPoint
const pos
);
672 /**@name For exporting one object after another. */
674 /** Returns a pointer to the first line in the list. */
675 wxLayoutLine
*GetFirstLine(void)
677 wxASSERT(m_FirstLine
);
683 void InternalClear(void);
685 /// The list of lines.
686 wxLayoutLine
*m_FirstLine
;
687 /**@name Cursor Management */
689 /// Where the text cursor (column,line) is.
691 /// The size of the cursor.
692 wxPoint m_CursorSize
;
693 /// Where the cursor should be drawn.
694 wxPoint m_CursorScreenPos
;
695 /// The line where the cursor is.
696 wxLayoutLine
*m_CursorLine
;
699 /** @name Font parameters. */
701 int m_FontFamily
, m_FontStyle
, m_FontWeight
;
703 bool m_FontUnderline
;
705 wxColour
const * m_ColourFG
;
706 wxColour
const * m_ColourBG
;
707 /// the default setting:
708 wxLayoutObjectCmd
*m_DefaultSetting
;
715 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
717 The wxLayoutPrintout object for printing within the wxWindows print
720 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
721 /** This class implements a wxPrintout for printing a wxLayoutList within
722 the wxWindows printing framework.
724 class wxLayoutPrintout
: public wxPrintout
728 @param llist pointer to the wxLayoutList to be printed
729 @param title title for PS file or windows
731 wxLayoutPrintout(wxLayoutList
*llist
,
732 wxString
const & title
=
733 "wxLayout Printout");
734 /** Function which prints the n-th page.
735 @param page the page number to print
736 @return bool true if we are not at end of document yet
738 bool OnPrintPage(int page
);
739 /** Checks whether page exists in document.
740 @param page number of page
741 @return true if page exists
743 bool HasPage(int page
);
745 /** Gets called from wxWindows to find out which pages are existing.
746 I'm not totally sure about the parameters though.
747 @param minPage the first page in the document
748 @param maxPage the last page in the document
749 @param selPageFrom the first page to be printed
750 @param selPageTo the last page to be printed
752 void GetPageInfo(int *minPage
, int *maxPage
,
753 int *selPageFrom
, int *selPageTo
);
755 /** This little function scales the DC so that the printout has
756 roughly the same size as the output on screen.
757 @param dc the wxDC to scale
758 @return the scale that was applied
760 float ScaleDC(wxDC
*dc
);
763 virtual void DrawHeader(wxDC &dc, wxPoint topleft, wxPoint bottomright, int pageno);
766 /// The list to print.
767 wxLayoutList
*m_llist
;
768 /// Title for PS file or window.
770 /// The real paper size.
771 int m_PageHeight
, m_PageWidth
;
772 /// How much we actually print per page.
773 int m_PrintoutHeight
;
774 /// How many pages we need to print.
776 /// Top left corner where we start printing.