]> git.saurik.com Git - wxWidgets.git/blob - samples/richedit/wxllist.h
39fe17864628ad2613af736940a3866e15939ddd
[wxWidgets.git] / samples / richedit / wxllist.h
1 /*-*- c++ -*-********************************************************
2 * wxLayoutList.h - a formatted text rendering engine for wxWindows *
3 * *
4 * (C) 1999 by Karsten Ballüder (ballueder@gmx.net) *
5 * *
6 * $Id$
7 *******************************************************************/
8
9
10 #ifndef WXLLIST_H
11 #define WXLLIST_H
12
13 #ifdef __GNUG__
14 # pragma interface "wxllist.h"
15 #endif
16
17 #include "kbList.h"
18
19 #include <wx/wx.h>
20 #include <wx/print.h>
21 #include <wx/printdlg.h>
22 #include <wx/generic/printps.h>
23 #include <wx/generic/prntdlgg.h>
24 #include <wx/dataobj.h>
25
26 // skip the following defines if embedded in M application
27 #ifndef M_BASEDIR
28 # define WXMENU_LAYOUT_LCLICK 1111
29 # define WXMENU_LAYOUT_RCLICK 1112
30 # define WXMENU_LAYOUT_DBLCLICK 1113
31 #else // for Mahogany only:
32 # include "MObject.h"
33 #endif
34
35 // use the wxWindows caret class instead of home grown cursor whenever possible
36 #ifdef __WXMSW__
37 # undef WXLAYOUT_USE_CARET
38 # define WXLAYOUT_USE_CARET 1
39 #endif // __WXMSW__
40
41 // do not enable debug mode within Mahogany
42 #if defined(__WXDEBUG__) && ! defined(M_BASEDIR)
43 # define WXLAYOUT_DEBUG
44 #endif
45
46 #ifdef WXLAYOUT_DEBUG
47 # define WXLO_TRACE(x) wxLogDebug(x)
48 #else
49 # define WXLO_TRACE(x)
50 #endif
51
52 #define WXLO_DEBUG_URECT 0
53
54 #ifndef WXLO_DEFAULTFONTSIZE
55 # define WXLO_DEFAULTFONTSIZE 12
56 #endif
57
58 #ifdef __WXMSW__
59 # define WXLO_BITMAP_FORMAT wxBITMAP_TYPE_BMP
60 #else
61 # define WXLO_BITMAP_FORMAT wxBITMAP_TYPE_PNG
62 #endif
63
64 /// Types of currently supported layout objects.
65 enum wxLayoutObjectType
66 {
67 /// illegal object type, should never appear
68 WXLO_TYPE_INVALID = 0,
69 /// text object, containing normal text
70 WXLO_TYPE_TEXT,
71 /// command object, containing font or colour changes
72 WXLO_TYPE_CMD,
73 /// icon object, any kind of image
74 WXLO_TYPE_ICON
75 };
76
77 /// Type used for coordinates in drawing. Must be signed.
78 typedef long CoordType;
79
80 // Forward declarations.
81 class wxLayoutList;
82 class wxLayoutLine;
83 class wxLayoutObject;
84
85 class WXDLLEXPORT wxCaret;
86 class WXDLLEXPORT wxColour;
87 class WXDLLEXPORT wxDC;
88 class WXDLLEXPORT wxFont;
89
90 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
91
92 The wxLayout objects which make up the lines.
93
94 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
95
96 /** The base class defining the interface to each object which can be
97 part of the layout. Each object needs to draw itself and calculate
98 its size.
99 */
100 class wxLayoutObject
101 #ifdef M_BASEDIR
102 : public MObject
103 #endif
104 {
105 public:
106 /** This structure can be used to contain data associated with the
107 object.
108 It is refcounted, so the caller has to do a DecRef() on it
109 instead of a delete.
110 */
111 struct UserData
112 {
113 UserData() { m_refcount = 1; }
114 inline void IncRef(void) { m_refcount++; }
115 inline void DecRef(void) { m_refcount--; if(m_refcount == 0) delete this;}
116 inline void SetLabel(const wxString &l) { m_label = l; }
117 inline const wxString & GetLabel(void) const { return m_label; }
118 private:
119 int m_refcount;
120 wxString m_label;
121 protected:
122 virtual ~UserData() { wxASSERT(m_refcount == 0); }
123 /// prevents gcc from generating stupid warnings
124 friend class dummy_UserData;
125 };
126
127 /// return the type of this object
128 virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_INVALID; }
129 /** Calculates the size of an object.
130 @param dc the wxDC to draw on
131 @param llist the wxLayoutList
132 */
133 virtual void Layout(wxDC &dc, wxLayoutList *llist) = 0;
134
135 /** Draws an object.
136 @param dc the wxDC to draw on
137 @param coords where to draw the baseline of the object.
138 @param wxllist pointer to wxLayoutList
139 @param begin if !=-1, from which position on to highlight it
140 @param end if begin !=-1, how many positions to highlight it
141 */
142 virtual void Draw(wxDC & /* dc */,
143 wxPoint const & /* coords */,
144 wxLayoutList *wxllist,
145 CoordType begin = -1,
146 CoordType end = -1) { }
147
148 /** Calculates and returns the size of the object.
149 @param top where to store height above baseline
150 @param bottom where to store height below baseline
151 @return the size of the object's box in pixels
152 */
153 virtual wxPoint GetSize(CoordType * top, CoordType *bottom) const
154 { *top = 0; *bottom = 0; return wxPoint(0,0); }
155
156 /// Return just the width of the object on the screen.
157 virtual CoordType GetWidth(void) const { return 0; }
158 /// returns the number of cursor positions occupied by this object
159 virtual CoordType GetLength(void) const { return 1; }
160 /** Returns the cursor offset relating to the screen x position
161 relative to begin of object.
162 @param dc the wxDC to use for calculations
163 @param xpos relative x position from head of object
164 @return cursor coordinate offset
165 */
166 virtual CoordType GetOffsetScreen(wxDC &dc, CoordType xpos) const { return 0; }
167
168 /// constructor
169 wxLayoutObject() { m_UserData = NULL; }
170 /// delete the user data
171 virtual ~wxLayoutObject() { if(m_UserData) m_UserData->DecRef(); }
172
173 #ifdef WXLAYOUT_DEBUG
174 virtual void Debug(void);
175 #endif
176
177 /** Tells the object about some user data. This data is associated
178 with the object and will be deleted at destruction time.
179 It is reference counted.
180 */
181 void SetUserData(UserData *data)
182 {
183 if(m_UserData)
184 m_UserData->DecRef();
185 m_UserData = data;
186 if(m_UserData)
187 m_UserData->IncRef();
188 }
189
190 /** Return the user data.
191 Increments the object's reference count. When no longer needed,
192 caller must call DecRef() on the pointer returned.
193 */
194 UserData * GetUserData(void) const { if(m_UserData) m_UserData->IncRef(); return m_UserData; }
195
196 /** Makes a copy of this object.
197 */
198 virtual wxLayoutObject *Copy(void) = 0;
199
200 /** Clipboard support function. Read and write objects to
201 strings. */
202 //@{
203 /// Writes the object to the string.
204 virtual void Write(wxString &ostr) = 0;
205 /** Reads an object.
206 @param str stream to read from, will bee changed
207 @return true on success
208 */
209 static wxLayoutObject *Read(wxString &istr);
210 //@}
211
212 /// returns TRUE if the object is shown on the screen (i.e. not cmd object)
213 bool IsVisibleObject() const { return GetType() != WXLO_TYPE_CMD; }
214
215 protected:
216 /// optional data for application's use
217 UserData *m_UserData;
218 #if defined (M_BASEDIR) && defined (DEBUG)
219 MOBJECT_NAME(wxLayoutObject)
220 #endif
221 };
222
223 /// Define a list type of wxLayoutObject pointers.
224 KBLIST_DEFINE(wxLayoutObjectList, wxLayoutObject);
225
226 /// An illegal iterator to save typing.
227 #define NULLIT (wxLayoutObjectList::iterator(NULL))
228 /// The iterator type.
229 typedef wxLayoutObjectList::iterator wxLOiterator;
230
231 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
232
233 wxLayoutObjectText
234
235 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
236 /** This class implements a wxLayoutObject holding plain text.
237 */
238 class wxLayoutObjectText : public wxLayoutObject
239 {
240 public:
241 wxLayoutObjectText(const wxString &txt = "");
242
243 virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_TEXT; }
244 virtual void Layout(wxDC &dc, wxLayoutList *llist);
245 virtual void Draw(wxDC &dc, wxPoint const &coords,
246 wxLayoutList *wxllist,
247 CoordType begin = -1,
248 CoordType end = -1);
249 /** Calculates and returns the size of the object.
250 @param top where to store height above baseline
251 @param bottom where to store height below baseline
252 @return the size of the object's box in pixels
253 */
254 virtual wxPoint GetSize(CoordType * top, CoordType *bottom) const;
255 /// Return just the width of the object on the screen.
256 virtual CoordType GetWidth(void) const { return m_Width; }
257 /** Returns the cursor offset relating to the screen x position
258 relative to begin of object.
259 @param dc the wxDC to use for calculations
260 @param xpos relative x position from head of object
261 @return cursor coordinate offset
262 */
263 virtual CoordType GetOffsetScreen(wxDC &dc, CoordType xpos) const;
264
265 virtual void Write(wxString &ostr);
266 static wxLayoutObjectText *Read(wxString &istr);
267
268 #ifdef WXLAYOUT_DEBUG
269 virtual void Debug(void);
270 #endif
271
272 virtual CoordType GetLength(void) const { return strlen(m_Text.c_str()); }
273
274 // for editing:
275 wxString & GetText(void) { return m_Text; }
276 void SetText(wxString const &text) { m_Text = text; }
277 /** Makes a copy of this object.
278 */
279 virtual wxLayoutObject *Copy(void);
280 private:
281 wxString m_Text;
282 /// size of the box containing text
283 long m_Width, m_Height;
284 /// Height above baseline.
285 long m_Top;
286 /// Height below baseline.
287 long m_Bottom;
288 };
289
290 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
291
292 wxLayoutObjectIcon
293
294 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
295 /** This class implements a wxLayoutObject holding a graphic.
296 */
297 class wxLayoutObjectIcon : public wxLayoutObject
298 {
299 public:
300 wxLayoutObjectIcon(wxBitmap *icon = NULL);
301 wxLayoutObjectIcon(wxBitmap const &icon);
302
303 ~wxLayoutObjectIcon() { if(m_Icon) delete m_Icon; }
304
305 virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_ICON; }
306 virtual void Layout(wxDC &dc, wxLayoutList *llist);
307 virtual void Draw(wxDC &dc, wxPoint const &coords,
308 wxLayoutList *wxllist,
309 CoordType begin = -1,
310 CoordType end = -1);
311
312 /** Calculates and returns the size of the object.
313 @param top where to store height above baseline
314 @param bottom where to store height below baseline
315 @return the size of the object's box in pixels
316 */
317 virtual wxPoint GetSize(CoordType * top, CoordType *bottom) const;
318 /// Return just the width of the object on the screen.
319 virtual CoordType GetWidth(void) const { return m_Icon->GetWidth(); }
320 // return a pointer to the icon
321 wxBitmap *GetIcon(void) const { return m_Icon; }
322 /** Makes a copy of this object.
323 */
324 virtual wxLayoutObject *Copy(void);
325 virtual void Write(wxString &ostr);
326 static wxLayoutObjectIcon *Read(wxString &istr);
327 private:
328 wxBitmap *m_Icon;
329 };
330
331 /** This structure holds all formatting information.
332 */
333 struct wxLayoutStyleInfo
334 {
335 wxLayoutStyleInfo(int ifamily = -1,
336 int isize = -1,
337 int istyle = -1,
338 int iweight = -1,
339 int iul = -1,
340 wxColour *fg = NULL,
341 wxColour *bg = NULL);
342 wxLayoutStyleInfo & operator=(const wxLayoutStyleInfo &right);
343
344 wxColour & GetBGColour() { return m_bg; }
345
346 /// Font change parameters.
347 int size, family, style, weight, underline;
348 /// Colours
349 wxColour m_bg, m_fg;
350 int m_fg_valid, m_bg_valid; // bool, but must be int!
351 };
352
353 /// a cached font
354 class wxFontCacheEntry
355 {
356 public:
357 wxFontCacheEntry(int family, int size, int style, int weight,
358 bool underline)
359 {
360 m_Family = family; m_Size = size; m_Style = style;
361 m_Weight = weight; m_Underline = underline;
362 m_Font = new wxFont(m_Size, m_Family,
363 m_Style, m_Weight, m_Underline);
364 }
365 bool Matches(int family, int size, int style, int weight,
366 bool underline) const
367 {
368 return size == m_Size && family == m_Family
369 && style == m_Style && weight == m_Weight
370 && underline == m_Underline;
371 }
372 wxFont & GetFont(void) { return *m_Font; }
373 ~wxFontCacheEntry()
374 {
375 delete m_Font;
376 }
377 private:
378 wxFont *m_Font;
379
380 // VZ: I wonder why it doesn't use wxLayoutStyleInfo instead of those?
381 int m_Family, m_Size, m_Style, m_Weight;
382 bool m_Underline;
383 };
384
385 KBLIST_DEFINE(wxFCEList, wxFontCacheEntry);
386
387 class wxFontCache
388 {
389 public:
390 wxFont & GetFont(int family, int size, int style, int weight,
391 bool underline);
392 wxFont & GetFont(wxLayoutStyleInfo const &si)
393 {
394 return GetFont(si.family, si.size, si.style, si.weight,
395 si.underline != 0);
396 }
397 private:
398 wxFCEList m_FontList;
399 };
400
401 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
402
403 wxLayoutObjectCmd
404
405 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
406 /** This class implements a wxLayoutObject holding style change commands.
407 */
408 class wxLayoutObjectCmd : public wxLayoutObject
409 {
410 public:
411 virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_CMD; }
412 virtual void Layout(wxDC &dc, wxLayoutList *llist);
413 virtual void Draw(wxDC &dc, wxPoint const &coords,
414 wxLayoutList *wxllist,
415 CoordType begin = -1,
416 CoordType end = -1);
417 wxLayoutObjectCmd(int family = -1,
418 int size = -1,
419 int style = -1,
420 int weight = -1,
421 int underline = -1,
422 wxColour *fg = NULL,
423 wxColour *bg = NULL);
424 ~wxLayoutObjectCmd();
425 /** Stores the current style in the styleinfo structure */
426 wxLayoutStyleInfo * GetStyle(void) const;
427 /** Makes a copy of this object.
428 */
429 virtual wxLayoutObject *Copy(void);
430 virtual void Write(wxString &ostr);
431 static wxLayoutObjectCmd *Read(wxString &istr);
432 private:
433 wxLayoutStyleInfo *m_StyleInfo;
434 };
435
436 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
437
438 The wxLayoutLine object
439
440 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
441
442 /** This class represents a single line of objects to be displayed.
443 It knows its height and total size and whether it needs to be
444 redrawn or not.
445 It has pointers to its first and next line so it can automatically
446 update them as needed.
447 */
448 class wxLayoutLine
449 {
450 public:
451 /** Constructor.
452 @param prev pointer to previous line or NULL
453 @param next pointer to following line or NULL
454 @param llist pointer to layout list
455 */
456 wxLayoutLine(wxLayoutLine *prev, wxLayoutList *llist);
457 /** This function inserts a new object at cursor position xpos.
458 @param xpos where to insert new object
459 @param obj the object to insert
460 @return true if that xpos existed and the object was inserted
461 */
462 bool Insert(CoordType xpos, wxLayoutObject *obj);
463
464 /** This function inserts text at cursor position xpos.
465 @param xpos where to insert
466 @param text the text to insert
467 @return true if that xpos existed and the object was inserted
468 */
469 bool Insert(CoordType xpos, const wxString& text);
470
471 /** This function appends an object to the line.
472 @param obj the object to insert
473 */
474 void Append(wxLayoutObject * obj)
475 {
476 wxASSERT(obj);
477
478 m_ObjectList.push_back(obj);
479 m_Length += obj->GetLength();
480 }
481
482 /** This function appens the next line to this, i.e. joins the two
483 lines into one.
484 */
485 void MergeNextLine(wxLayoutList *llist);
486
487 /** This function deletes npos cursor positions from position xpos.
488 @param xpos where to delete
489 @param npos how many positions
490 @return number of positions still to be deleted
491 */
492 CoordType Delete(CoordType xpos, CoordType npos);
493
494 /** This function breaks the line at a given cursor position.
495 @param xpos where to break it
496 @return pointer to the new line object replacing the old one
497 */
498 wxLayoutLine *Break(CoordType xpos, wxLayoutList *llist);
499
500 /** Deletes the next word from this position, including leading
501 whitespace.
502 This function does not delete over font changes, i.e. a word
503 with formatting instructions in the middle of it is treated as
504 two (three actually!) words. In fact, if the cursor is on a non-text object, that
505 one is treated as a word.
506 @param xpos from where to delete
507 @return true if a word was deleted
508 */
509 bool DeleteWord(CoordType npos);
510
511 /** Finds a suitable position left to the given column to break the
512 line.
513 @param column we want to break the line to the left of this
514 @return column for breaking line or -1 if no suitable location found
515 */
516 CoordType GetWrapPosition(CoordType column);
517
518 /** Finds the object which covers the cursor position xpos in this
519 line.
520 @param xpos the column number
521 @param offset where to store the difference between xpos and
522 the object's head
523 @return iterator to the object or NULLIT
524 */
525 wxLayoutObjectList::iterator FindObject(CoordType xpos, CoordType
526 *offset) const ;
527
528 /** Finds the object which covers the screen position xpos in this
529 line.
530 @param dc the wxDC to use for calculations
531 @param llist the layout list to which this line belongs
532 @param xpos the screen x coordinate
533 @param offset where to store the difference between xpos and
534 the object's head
535 @return iterator to the object or NULLIT
536 */
537 wxLayoutObjectList::iterator FindObjectScreen(wxDC &dc,
538 wxLayoutList *llist,
539 CoordType xpos,
540 CoordType *offset,
541 bool *found = NULL) const ;
542
543 /** Finds text in this line.
544 @param needle the text to find
545 @param xpos the position where to start the search
546 @return the cursoor coord where it was found or -1
547 */
548 CoordType FindText(const wxString &needle, CoordType xpos = 0) const;
549
550 /** Get the first object in the list. This is used by the wxlparser
551 functions to export the list.
552 @return iterator to the first object
553 */
554 wxLayoutObjectList::iterator GetFirstObject(void) const
555 {
556 return m_ObjectList.begin();
557 }
558
559 /** Get the last object in the list.
560 */
561 wxLayoutObjectList::iterator GetLastObject(void) const
562 {
563 return m_ObjectList.tail();
564 }
565
566 /** Deletes this line, returns pointer to next line.
567 @param update If true, update all following lines.
568 */
569 wxLayoutLine *DeleteLine(bool update, wxLayoutList *llist);
570
571 /**@name Cursor Management */
572 //@{
573 /** Return the line number of this line.
574 @return the line number
575 */
576 inline CoordType GetLineNumber(void) const { return m_LineNumber; }
577 /** Return the length of the line.
578 @return line lenght in cursor positions
579 */
580 inline CoordType GetLength(void) const { return m_Length; }
581 //@}
582
583 /**@name Drawing and Layout */
584 //@{
585 /** Draws the line on a wxDC.
586 @param dc the wxDC to draw on
587 @param llist the wxLayoutList
588 @param offset an optional offset to shift printout
589 */
590 void Draw(wxDC &dc,
591 wxLayoutList *llist,
592 const wxPoint &offset = wxPoint(0,0)) const;
593
594 /** Recalculates the positions of objects and the height of the
595 line.
596 @param dc the wxDC to draw on
597 @param llist th e wxLayoutList
598 @param cursorPos if not NULL, set cursor screen position in there
599 @param cursorSize if not cursorPos != NULL, set cursor size in there
600 @param cursorStyle if non NULL where to store styleinfo for cursor pos
601 @param cx if cursorPos != NULL, the cursor x position
602 @param suppressStyleUpdate FALSe normally, only to suppress updating of m_StyleInfo
603 */
604 void Layout(wxDC &dc,
605 wxLayoutList *llist,
606 wxPoint *cursorPos = NULL,
607 wxPoint *cursorSize = NULL,
608 wxLayoutStyleInfo *cursorStyle = NULL,
609 int cx = 0,
610 bool suppressStyleUpdate = FALSE);
611 /** This function finds an object belonging to a given cursor
612 position. It assumes that Layout() has been called before.
613 @param dc the wxDC to use for calculations
614 @param xpos screen x position
615 @param found if non-NULL set to false if we return the last
616 object before the cursor, to true if we really have an object
617 for that position
618 @return pointer to the object
619 */
620 wxLayoutObject * FindObjectScreen(wxDC &dc,
621 CoordType xpos,
622 bool *found = NULL);
623 /** This sets the style info for the beginning of this line.
624 @param si styleinfo structure
625 */
626 void ApplyStyle(const wxLayoutStyleInfo &si)
627 { m_StyleInfo = si; }
628
629 //@}
630
631 /**@name List traversal */
632 //@{
633 /// Returns pointer to next line.
634 wxLayoutLine *GetNextLine(void) const { return m_Next; }
635 /// Returns pointer to previous line.
636 wxLayoutLine *GetPreviousLine(void) const { return m_Previous; }
637 /// Sets the link to the next line.
638 void SetNext(wxLayoutLine *next)
639 { m_Next = next; if(next) next->m_Previous = this; }
640 /// Sets the link to the previous line.
641 void SetPrevious(wxLayoutLine *previous)
642 { m_Previous = previous; if(previous) previous->m_Next = this; }
643 //@}
644
645 /// Returns the position of this line on the canvas.
646 wxPoint GetPosition(void) const { return m_Position; }
647 /// Returns the height of this line.
648 CoordType GetHeight(void) const { return m_Height; }
649 /// Returns the width of this line.
650 CoordType GetWidth(void) const { return m_Width; }
651 /// Recalculates the position of this line on the canvas.
652 wxPoint RecalculatePosition(wxLayoutList *llist);
653
654 /** Copies the contents of this line to another wxLayoutList
655 @param llist the wxLayoutList destination
656 @param from x cursor coordinate where to start
657 @param to x cursor coordinate where to stop, -1 for end of line
658 */
659 void Copy(wxLayoutList *llist,
660 CoordType from = 0,
661 CoordType to = -1);
662
663 #ifdef WXLAYOUT_DEBUG
664 void Debug(void);
665 #endif
666 wxLayoutStyleInfo const & GetStyleInfo() const { return m_StyleInfo; }
667
668 /// Returns dirty state
669 bool IsDirty(void) const { return m_Dirty; }
670 /** Marks this line as diry.
671 @param left xpos from where it is dirty or -1 for all
672 */
673 void MarkDirty(CoordType left = -1)
674 {
675 if ( left != -1 )
676 {
677 if ( m_updateLeft == -1 || left < m_updateLeft )
678 m_updateLeft = left;
679 }
680
681 m_Dirty = true;
682 }
683 /// Reset the dirty flag
684 void MarkClean() { m_Dirty = false; m_updateLeft = -1; }
685
686 private:
687 /// Destructor is private. Use DeleteLine() to remove it.
688 ~wxLayoutLine();
689
690 /**@name Functions to let the lines synchronise with each other. */
691 //@{
692 /** Sets the height of this line. Will mark following lines as
693 dirty.
694 @param height new height
695 */
696 void SetHeight(CoordType height, wxLayoutList *llist)
697 { m_Height = height; MarkDirty(); }
698
699 /** Updates the line numbers. */
700 void ReNumber(void);
701 //@}
702 private:
703 /// The line number.
704 CoordType m_LineNumber;
705 /// The line length in cursor positions.
706 CoordType m_Length;
707 /// The total height of the line.
708 CoordType m_Height;
709 /// The total width of the line on screen.
710 CoordType m_Width;
711 /// The baseline for drawing objects
712 CoordType m_BaseLine;
713 /// The position on the canvas.
714 wxPoint m_Position;
715 /// The list of objects
716 wxLayoutObjectList m_ObjectList;
717 /// Have we been changed since the last layout?
718 bool m_Dirty;
719 /// The coordinate of the left boundary of the update rectangle (if m_Dirty)
720 CoordType m_updateLeft;
721 /// Pointer to previous line if it exists.
722 wxLayoutLine *m_Previous;
723 /// Pointer to next line if it exists.
724 wxLayoutLine *m_Next;
725 /// A StyleInfo structure, holding the current settings.
726 wxLayoutStyleInfo m_StyleInfo;
727 /// Just to suppress gcc compiler warnings.
728 friend class dummy;
729 private:
730 wxLayoutLine(const wxLayoutLine &);
731 };
732
733
734 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
735
736 The wxLayoutList object
737
738 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
739 /** The wxLayoutList is a list of wxLayoutLine objects. It provides a
740 higher level of abstraction for the text and can generally be considered
741 as representing "the text".
742 */
743 class wxLayoutList
744 {
745 public:
746 /// Constructor.
747 wxLayoutList();
748 /// Destructor.
749 ~wxLayoutList();
750
751 #ifdef WXLAYOUT_USE_CARET
752 /// give us the pointer to the caret to use
753 void SetCaret(wxCaret *caret) { m_caret = caret; }
754 #endif // WXLAYOUT_USE_CARET
755
756 /// Clear the list.
757 void Clear(int family = wxROMAN,
758 int size=WXLO_DEFAULTFONTSIZE,
759 int style=wxNORMAL,
760 int weight=wxNORMAL,
761 int underline=0,
762 wxColour *fg=NULL,
763 wxColour *bg=NULL);
764 /// Empty: clear the list but leave font settings.
765 void Empty(void);
766
767 /** Enable or disable auto-formatting. Normally, while editing this
768 should be enabled which is the default. While
769 inserting/deleting lots of text, it makes sense to temporarily
770 disable this.
771 @param enable TRUE to enable, FALSE to disable
772 */
773 void SetAutoFormatting(bool enable = TRUE)
774 { m_AutoFormat = enable; }
775 /**@name Cursor Management */
776 //@{
777 /** Set new cursor position.
778 @param p new position
779 @return bool if it could be set
780 */
781 bool MoveCursorTo(wxPoint const &p);
782 /** Move cursor up or down.
783 @param n
784 @return bool if it could be moved
785 */
786 bool MoveCursorVertically(int n);
787 /** Move cursor left or right.
788 @param n = number of positions to move
789 @return bool if it could be moved
790 */
791 bool MoveCursorHorizontally(int n);
792 /** Move cursor to the left or right counting in words
793 @param n = number of positions in words
794 @param untilNext: puts the cursor at the start of the next word if true,
795 leaves it at the end of the current one otherwise
796 @return bool if it could be moved
797 */
798 bool MoveCursorWord(int n, bool untilNext = true);
799
800 /// Move cursor to end of line.
801 void MoveCursorToEndOfLine(void)
802 {
803 wxASSERT(m_CursorLine);
804 MoveCursorHorizontally(m_CursorLine->GetLength()-m_CursorPos.x);
805 }
806
807 /// Move cursor to the start of line.
808 void MoveCursorToBeginOfLine(void)
809 { MoveCursorHorizontally(-m_CursorPos.x); }
810
811 /// get the number of lines in the list
812 size_t GetNumLines() const { return m_numLines; }
813
814 /// Returns current cursor position.
815 const wxPoint &GetCursorPos(wxDC &dc) const { return m_CursorPos; }
816 const wxPoint &GetCursorPos() const { return m_CursorPos; }
817
818 /// move cursor to the end of text
819 void MoveCursorToEnd(void)
820 {
821 MoveCursorTo(wxPoint(0, GetNumLines() - 1));
822 MoveCursorToEndOfLine();
823 }
824
825 //@}
826
827 /**@name Editing functions.
828 All of these functions return true on success and false on
829 failure. */
830 //@{
831 /// Insert text at current cursor position.
832 bool Insert(wxString const &text);
833 /// Insert some other object at current cursor position.
834 bool Insert(wxLayoutObject *obj);
835 /// Inserts objects at current cursor positions
836 bool Insert(wxLayoutList *llist);
837
838 /// Inserts a linebreak at current cursor position.
839 bool LineBreak(void);
840 /** Wraps the current line. Searches to the left of the cursor to
841 break the line. Does nothing if the cursor position is before
842 the break position parameter.
843 @param column the break position for the line, maximum length
844 @return true if line got broken
845 */
846 bool WrapLine(CoordType column);
847 /** This function deletes npos cursor positions.
848 @param npos how many positions
849 @return true if everything got deleted
850 */
851 bool Delete(CoordType npos);
852
853 /** Delete the next n lines.
854 @param n how many lines to delete
855 @return how many it could not delete
856 */
857 int DeleteLines(int n);
858
859 /// Delete to end of line.
860 void DeleteToEndOfLine(void)
861 {
862 wxASSERT(m_CursorLine);
863 Delete(m_CursorLine->GetLength()-m_CursorPos.x);
864 }
865 /// Delete to begin of line.
866 void DeleteToBeginOfLine(void)
867 {
868 wxASSERT(m_CursorLine);
869 CoordType n = m_CursorPos.x;
870 #ifdef WXLAYOUT_DEBUG
871 wxASSERT(MoveCursorHorizontally(-n));
872 #else
873 MoveCursorHorizontally(-n);
874 #endif
875 Delete(n);
876 }
877
878 /** Delete the next word.
879 */
880 void DeleteWord(void)
881 {
882 wxASSERT(m_CursorLine);
883 m_CursorLine->DeleteWord(m_CursorPos.x);
884 }
885
886 //@}
887
888 /** Finds text in this list.
889 @param needle the text to find
890 @param cpos the position where to start the search
891 @return the cursor coord where it was found or (-1,-1)
892 */
893 wxPoint FindText(const wxString &needle, const wxPoint &cpos = wxPoint(0,0)) const;
894
895 /**@name Formatting options */
896 //@{
897 /// sets font parameters
898 void SetFont(int family, int size, int style,
899 int weight, int underline,
900 wxColour *fg,
901 wxColour *bg);
902 /// sets font parameters, colours by name
903 void SetFont(int family=-1, int size = -1, int style=-1,
904 int weight=-1, int underline = -1,
905 char const *fg = NULL,
906 char const *bg = NULL);
907 /// changes to the next larger font size
908 inline void SetFontLarger(void)
909 { SetFont(-1,(12*m_CurrentStyleInfo.size)/10); }
910 /// changes to the next smaller font size
911 inline void SetFontSmaller(void)
912 { SetFont(-1,(10*m_CurrentStyleInfo.size)/12); }
913
914 /// set font family
915 inline void SetFontFamily(int family) { SetFont(family); }
916 /// set font size
917 inline void SetFontSize(int size) { SetFont(-1,size); }
918 /// set font style
919 inline void SetFontStyle(int style) { SetFont(-1,-1,style); }
920 /// set font weight
921 inline void SetFontWeight(int weight) { SetFont(-1,-1,-1,weight); }
922 /// toggle underline flag
923 inline void SetFontUnderline(bool ul) { SetFont(-1,-1,-1,-1,(int)ul); }
924 /// set font colours by name
925 inline void SetFontColour(char const *fg, char const *bg = NULL)
926 { SetFont(-1,-1,-1,-1,-1,fg,bg); }
927 /// set font colours by colour
928 inline void SetFontColour(wxColour *fg, wxColour *bg = NULL)
929 { SetFont(-1,-1,-1,-1,-1,fg,bg); }
930
931 /**
932 Returns a pointer to the default settings.
933 This is only valid temporarily and should not be stored
934 anywhere.
935 @return the default settings of the list
936 */
937 wxLayoutStyleInfo &GetDefaultStyleInfo(void) { return m_DefaultStyleInfo ; }
938 wxLayoutStyleInfo &GetStyleInfo(void) { return m_CurrentStyleInfo ; }
939 const wxLayoutStyleInfo &GetStyleInfo(void) const { return m_CurrentStyleInfo ; }
940 const wxLayoutStyleInfo &GetCursorStyleInfo(void) const { return m_CursorStyleInfo ; }
941
942 /// is the current font underlined?
943 bool IsFontUnderlined() const { return GetCursorStyleInfo().underline != 0; }
944 /// is the current font bold?
945 bool IsFontBold() const { return GetCursorStyleInfo().weight == wxBOLD; }
946 /// is the current font italic?
947 bool IsFontItalic() const { return GetCursorStyleInfo().style == wxITALIC; }
948
949 /// set underline if it was off, turn it off if it was on
950 void ToggleFontUnderline()
951 { SetFontUnderline(!IsFontUnderlined()); }
952
953 /// make font bold if it was normal or make it normal if it was bold
954 void ToggleFontWeight()
955 { SetFontWeight(IsFontBold() ? wxNORMAL : wxBOLD); }
956
957 /// make font italic if it was normal or make it normal if it was italic
958 void ToggleFontItalics()
959 { SetFontStyle(IsFontItalic() ? wxNORMAL : wxITALIC); }
960
961 //@}
962
963 /**@name Drawing */
964 //@{
965 /** Draws the complete list on a wxDC.
966 @param dc the wxDC to draw on
967 @param offset an optional offset to shift printout
968 @param top optional y coordinate where to start drawing
969 @param bottom optional y coordinate where to stop drawing
970 @param clipStrictly if set, do not draw objects which reach
971 beyond "bottom". Set this when printing.
972 */
973 void Draw(wxDC &dc,
974 const wxPoint &offset = wxPoint(0,0),
975 CoordType top = -1, CoordType bottom = -1,
976 bool clipStrictly = false);
977
978 /** Calculates new layout for the list, like Draw() but does not
979 actually draw it.
980 @param dc the wxDC to draw on
981 @param bottom optional y coordinate where to stop calculating
982 @param forceAll force re-layout of all lines
983 @param cpos Can hold a cursorposition, and will be overwritten
984 with the corresponding DC position.
985 @param csize Will hold the cursor size relating to cpos.
986 */
987 void Layout(wxDC &dc, CoordType bottom = -1, bool forceAll = false,
988 wxPoint *cpos = NULL,
989 wxPoint *csize = NULL);
990
991 /** Ensure that the whole list will be recalculate on the next call
992 to Layout() or Draw().
993 @param redrawAll TRUE or FALSE to reset it
994 */
995 void ForceTotalLayout(bool redrawAll = TRUE)
996 { m_ReLayoutAll = redrawAll; }
997
998 /** Returns the screen coordinates relating to a given cursor
999 position and the size of the cursor at that position.
1000 @param dc for which to calculate it
1001 @param cpos Cursor position to look for.
1002 @param csize If non-NULL, will be set to the cursor size.
1003 @return The cursor position on the DC.
1004 */
1005 wxPoint GetScreenPos(wxDC &dc, const wxPoint &cpos, wxPoint *csize = NULL);
1006
1007 /** Calculates new sizes for everything in the list, like Layout()
1008 but this is needed after the list got changed.
1009 @param dc the wxDC to draw on
1010 @param bottom optional y coordinate where to stop calculating
1011 */
1012 void Recalculate(wxDC &dc, CoordType bottom = -1);
1013
1014 /** Returns the size of the list in screen coordinates.
1015 The return value only makes sense after the list has been
1016 drawn.
1017 @return a wxPoint holding the maximal x/y coordinates used for
1018 drawing
1019 */
1020 wxPoint GetSize(void) const;
1021
1022 /** Returns the cursor position on the screen.
1023 */
1024 wxPoint GetCursorScreenPos(void) const;
1025
1026 /** Draws the cursor.
1027 @param active If true, draw a bold cursor to mark window as
1028 active.
1029 @param translate optional translation of cursor coords on screen
1030 */
1031 void DrawCursor(wxDC &dc,
1032 bool active = true,
1033 const wxPoint & translate = wxPoint(0,0));
1034
1035 /** This function finds an object belonging to a given screen
1036 position. It assumes that Layout() has been called before.
1037 @param pos screen position
1038 @param cursorPos if non NULL, store cursor position in there
1039 @param found if used, set this to true if we really found an
1040 object, to false if we had to take the object near to it
1041 @return pointer to the object
1042 */
1043 wxLayoutObject * FindObjectScreen(wxDC &dc,
1044 wxPoint const pos,
1045 wxPoint *cursorPos = NULL,
1046 bool *found = NULL);
1047
1048 /** Called by the objects to update the update rectangle.
1049 @param x horizontal coordinate to include in rectangle
1050 @param y vertical coordinate to include in rectangle
1051 */
1052 void SetUpdateRect(CoordType x, CoordType y);
1053 /** Called by the objects to update the update rectangle.
1054 @param p a point to include in it
1055 */
1056 void SetUpdateRect(const wxPoint &p)
1057 { SetUpdateRect(p.x,p.y); }
1058 /// adds the cursor position to the update rectangle
1059 void AddCursorPosToUpdateRect()
1060 {
1061 #ifndef WXLAYOUT_USE_CARET
1062 SetUpdateRect(m_CursorScreenPos);
1063 SetUpdateRect(m_CursorScreenPos+m_CursorSize);
1064 //#else - the caret will take care of refreshing itself
1065 #endif // !WXLAYOUT_USE_CARET
1066 }
1067 /// Invalidates the update rectangle.
1068 void InvalidateUpdateRect(void) { m_UpdateRectValid = false; }
1069 /// Returns the update rectangle.
1070 const wxRect *GetUpdateRect(void) const { return &m_UpdateRect; }
1071 //@}
1072
1073 /// get the current cursor size
1074 const wxPoint& GetCursorSize() const { return m_CursorSize; }
1075
1076 /**@name For exporting one object after another. */
1077 //@{
1078 /** Returns a pointer to the first line in the list. */
1079 wxLayoutLine *GetFirstLine(void)
1080 {
1081 wxASSERT(m_FirstLine);
1082 return m_FirstLine;
1083 }
1084 //@}
1085
1086 /// Begin selecting text
1087 void StartSelection(const wxPoint& cpos = wxPoint(-1,-1),
1088 const wxPoint& spos = wxPoint(-1,-1));
1089 // Continue selecting text
1090 void ContinueSelection(const wxPoint& cpos = wxPoint(-1,-1),
1091 const wxPoint& spos = wxPoint(-1,-1));
1092 /// End selecting text.
1093 void EndSelection(const wxPoint& cpos = wxPoint(-1,-1),
1094 const wxPoint& spos = wxPoint(-1,-1));
1095 /// Discard the current selection
1096 void DiscardSelection();
1097 /// Are we still selecting text?
1098 bool IsSelecting(void) const;
1099 /// Is the given point (text coords) selected?
1100 bool IsSelected(const wxPoint &cursor) const;
1101 /// Do we have a non null selection?
1102 bool HasSelection() const
1103 { return m_Selection.m_valid || m_Selection.m_selecting; }
1104
1105 /** Return the selection as a wxLayoutList.
1106 @param invalidate if true, the selection will be invalidated after this and can no longer be used.
1107 @return Another layout list object holding the selection, must be freed by caller
1108 */
1109 wxLayoutList *GetSelection(class wxLayoutDataObject *wxldo = NULL, bool invalidate = TRUE);
1110 /// Delete selected bit
1111 void DeleteSelection(void);
1112
1113 wxLayoutList *Copy(const wxPoint &from = wxPoint(0,0),
1114 const wxPoint &to = wxPoint(-1,-1));
1115
1116 /// starts highlighting of text for selections
1117 void StartHighlighting(wxDC &dc);
1118 /// ends highlighting of text for selections
1119 void EndHighlighting(wxDC &dc);
1120
1121 /** Tests whether this layout line is selected and needs
1122 highlighting.
1123 @param line to test for
1124 @param from set to first cursorpos to be highlighted (for returncode == -1)
1125 @param to set to last cursorpos to be highlighted (for returncode == -1)
1126 @return 0 = not selected, 1 = fully selected, -1 = partially
1127 selected
1128
1129 */
1130 int IsSelected(const wxLayoutLine *line, CoordType *from, CoordType *to);
1131
1132 void ApplyStyle(wxLayoutStyleInfo const &si, wxDC &dc);
1133 #ifdef WXLAYOUT_DEBUG
1134 void Debug(void);
1135 #endif
1136
1137 // for wxLayoutLine usage only
1138 void IncNumLines() { m_numLines++; }
1139 void DecNumLines() { m_numLines--; }
1140
1141 /// get the line by number
1142 wxLayoutLine *GetLine(CoordType index) const;
1143 private:
1144 /// Clear the list.
1145 void InternalClear(void);
1146
1147 /// The list of lines.
1148 wxLayoutLine *m_FirstLine;
1149 /// The number of lines in the list (store instead recalculating for speed)
1150 size_t m_numLines;
1151
1152 /// The update rectangle which needs to be refreshed:
1153 wxRect m_UpdateRect;
1154 /// Is the update rectangle valid?
1155 bool m_UpdateRectValid;
1156
1157 /// Shall we auto-format?
1158 bool m_AutoFormat;
1159 /// Shall we re-layout everything?
1160 bool m_ReLayoutAll;
1161 /**@name Cursor Management */
1162 //@{
1163 /// Where the text cursor (column,line) is.
1164 wxPoint m_CursorPos;
1165 /// Where the cursor should be drawn.
1166 wxPoint m_CursorScreenPos;
1167 /// The line where the cursor is.
1168 wxLayoutLine *m_CursorLine;
1169 /// The size of the cursor.
1170 wxPoint m_CursorSize;
1171 /// Has the cursor moved (is m_CursorScreenPos up to date)?
1172 bool m_movedCursor;
1173 #ifdef WXLAYOUT_USE_CARET
1174 /// the caret
1175 wxCaret *m_caret;
1176 #endif // WXLAYOUT_USE_CARET
1177 //@}
1178
1179 /// selection.state and begin/end coordinates
1180 struct Selection
1181 {
1182 Selection() { m_valid = m_selecting = m_discarded = false; }
1183
1184 bool m_valid;
1185 bool m_selecting;
1186 bool m_discarded; // may be TRUE only until the next redraw
1187
1188 // returns true if we already have the screen coordinates of the
1189 // selection start and end
1190 bool HasValidScreenCoords() const
1191 { return m_ScreenA.x != -1 && m_ScreenB.x != -1; }
1192
1193 // the start and end of the selection coordinates in pixels
1194 wxPoint m_ScreenA, m_ScreenB;
1195
1196 // these coordinates are in text positions, not in pixels
1197 wxPoint m_CursorA, m_CursorB;
1198 } m_Selection;
1199 /** @name Font parameters. */
1200 //@{
1201 /// this object manages the fonts for us
1202 wxFontCache m_FontCache;
1203 /// the default setting:
1204 wxLayoutStyleInfo m_DefaultStyleInfo;
1205 /// the current setting:
1206 wxLayoutStyleInfo m_CurrentStyleInfo;
1207 /// the current setting:
1208 wxLayoutStyleInfo m_CursorStyleInfo;
1209 //@}
1210 };
1211
1212 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1213
1214 The wxLayoutDataObject for exporting data to the clipboard in our
1215 own format.
1216
1217 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1218 class wxLayoutDataObject : public wxCustomDataObject
1219 {
1220 public:
1221 wxLayoutDataObject(void)
1222 {
1223 #if 0 // TODO: No longer exists, what should we do instead?
1224 SetId("application/wxlayoutlist");
1225 #endif
1226 //m_format.SetAtom((GdkAtom) 222222);
1227 }
1228 };
1229
1230 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1231
1232 The wxLayoutPrintout object for printing within the wxWindows print
1233 framework.
1234
1235 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1236 /** This class implements a wxPrintout for printing a wxLayoutList within
1237 the wxWindows printing framework.
1238 */
1239 class wxLayoutPrintout: public wxPrintout
1240 {
1241 public:
1242 /** Constructor.
1243 @param llist pointer to the wxLayoutList to be printed
1244 @param title title for PS file or windows
1245 */
1246 wxLayoutPrintout(wxLayoutList *llist,
1247 wxString const & title =
1248 "wxLayout Printout");
1249 /// Destructor.
1250 ~wxLayoutPrintout();
1251
1252 /** Function which prints the n-th page.
1253 @param page the page number to print
1254 @return bool true if we are not at end of document yet
1255 */
1256 bool OnPrintPage(int page);
1257 /** Checks whether page exists in document.
1258 @param page number of page
1259 @return true if page exists
1260 */
1261 bool HasPage(int page);
1262
1263 /** Gets called from wxWindows to find out which pages are existing.
1264 I'm not totally sure about the parameters though.
1265 @param minPage the first page in the document
1266 @param maxPage the last page in the document
1267 @param selPageFrom the first page to be printed
1268 @param selPageTo the last page to be printed
1269 */
1270 void GetPageInfo(int *minPage, int *maxPage,
1271 int *selPageFrom, int *selPageTo);
1272 protected:
1273 /** This little function scales the DC so that the printout has
1274 roughly the same size as the output on screen.
1275 @param dc the wxDC to scale
1276 @return the scale that was applied
1277 */
1278 float ScaleDC(wxDC *dc);
1279
1280 /* no longer used
1281 virtual void DrawHeader(wxDC &dc, wxPoint topleft, wxPoint bottomright, int pageno);
1282 */
1283 private:
1284 /// The list to print.
1285 wxLayoutList *m_llist;
1286 /// Title for PS file or window.
1287 wxString m_title;
1288 /// The real paper size.
1289 int m_PageHeight, m_PageWidth;
1290 /// How much we actually print per page.
1291 int m_PrintoutHeight;
1292 /// How many pages we need to print.
1293 int m_NumOfPages;
1294 /// Top left corner where we start printing.
1295 wxPoint m_Offset;
1296 };
1297
1298
1299 #endif // WXLLIST_H