]> git.saurik.com Git - wxWidgets.git/blob - samples/richedit/wxllist.h
Fixed resize behaviour under certain circumstances.
[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(const wxLayoutStyleInfo &si);
425 ~wxLayoutObjectCmd();
426 /** Stores the current style in the styleinfo structure */
427 wxLayoutStyleInfo * GetStyle(void) const;
428 /** Makes a copy of this object.
429 */
430 virtual wxLayoutObject *Copy(void);
431 virtual void Write(wxString &ostr);
432 static wxLayoutObjectCmd *Read(wxString &istr);
433 private:
434 wxLayoutStyleInfo *m_StyleInfo;
435 };
436
437 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
438
439 The wxLayoutLine object
440
441 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
442
443 /** This class represents a single line of objects to be displayed.
444 It knows its height and total size and whether it needs to be
445 redrawn or not.
446 It has pointers to its first and next line so it can automatically
447 update them as needed.
448 */
449 class wxLayoutLine
450 {
451 public:
452 /** Constructor.
453 @param prev pointer to previous line or NULL
454 @param next pointer to following line or NULL
455 @param llist pointer to layout list
456 */
457 wxLayoutLine(wxLayoutLine *prev, wxLayoutList *llist);
458 /** This function inserts a new object at cursor position xpos.
459 @param xpos where to insert new object
460 @param obj the object to insert
461 @return true if that xpos existed and the object was inserted
462 */
463 bool Insert(CoordType xpos, wxLayoutObject *obj);
464
465 /** This function inserts text at cursor position xpos.
466 @param xpos where to insert
467 @param text the text to insert
468 @return true if that xpos existed and the object was inserted
469 */
470 bool Insert(CoordType xpos, const wxString& text);
471
472 /** This function appends an object to the line.
473 @param obj the object to insert
474 */
475 void Append(wxLayoutObject * obj)
476 {
477 wxASSERT(obj);
478
479 m_ObjectList.push_back(obj);
480 m_Length += obj->GetLength();
481 }
482
483 /** This function appens the next line to this, i.e. joins the two
484 lines into one.
485 */
486 void MergeNextLine(wxLayoutList *llist);
487
488 /** This function deletes npos cursor positions from position xpos.
489 @param xpos where to delete
490 @param npos how many positions
491 @return number of positions still to be deleted
492 */
493 CoordType Delete(CoordType xpos, CoordType npos);
494
495 /** This function breaks the line at a given cursor position.
496 @param xpos where to break it
497 @return pointer to the new line object replacing the old one
498 */
499 wxLayoutLine *Break(CoordType xpos, wxLayoutList *llist);
500
501 /** Deletes the next word from this position, including leading
502 whitespace.
503 This function does not delete over font changes, i.e. a word
504 with formatting instructions in the middle of it is treated as
505 two (three actually!) words. In fact, if the cursor is on a non-text object, that
506 one is treated as a word.
507 @param xpos from where to delete
508 @return true if a word was deleted
509 */
510 bool DeleteWord(CoordType npos);
511
512 /** Finds a suitable position left to the given column to break the
513 line.
514 @param column we want to break the line to the left of this
515 @return column for breaking line or -1 if no suitable location found
516 */
517 CoordType GetWrapPosition(CoordType column);
518
519 /** Finds the object which covers the cursor position xpos in this
520 line.
521 @param xpos the column number
522 @param offset where to store the difference between xpos and
523 the object's head
524 @return iterator to the object or NULLIT
525 */
526 wxLayoutObjectList::iterator FindObject(CoordType xpos, CoordType
527 *offset) const ;
528
529 /** Finds the object which covers the screen position xpos in this
530 line.
531 @param dc the wxDC to use for calculations
532 @param llist the layout list to which this line belongs
533 @param xpos the screen x coordinate
534 @param offset where to store the difference between xpos and
535 the object's head
536 @return iterator to the object or NULLIT
537 */
538 wxLayoutObjectList::iterator FindObjectScreen(wxDC &dc,
539 wxLayoutList *llist,
540 CoordType xpos,
541 CoordType *offset,
542 bool *found = NULL) const ;
543
544 /** Finds text in this line.
545 @param needle the text to find
546 @param xpos the position where to start the search
547 @return the cursoor coord where it was found or -1
548 */
549 CoordType FindText(const wxString &needle, CoordType xpos = 0) const;
550
551 /** Get the first object in the list. This is used by the wxlparser
552 functions to export the list.
553 @return iterator to the first object
554 */
555 wxLayoutObjectList::iterator GetFirstObject(void) const
556 {
557 return m_ObjectList.begin();
558 }
559
560 /** Get the last object in the list.
561 */
562 wxLayoutObjectList::iterator GetLastObject(void) const
563 {
564 return m_ObjectList.tail();
565 }
566
567 /** Deletes this line, returns pointer to next line.
568 @param update If true, update all following lines.
569 */
570 wxLayoutLine *DeleteLine(bool update, wxLayoutList *llist);
571
572 /**@name Cursor Management */
573 //@{
574 /** Return the line number of this line.
575 @return the line number
576 */
577 inline CoordType GetLineNumber(void) const { return m_LineNumber; }
578 /** Return the length of the line.
579 @return line lenght in cursor positions
580 */
581 inline CoordType GetLength(void) const { return m_Length; }
582 //@}
583
584 /**@name Drawing and Layout */
585 //@{
586 /** Draws the line on a wxDC.
587 @param dc the wxDC to draw on
588 @param llist the wxLayoutList
589 @param offset an optional offset to shift printout
590 */
591 void Draw(wxDC &dc,
592 wxLayoutList *llist,
593 const wxPoint &offset = wxPoint(0,0)) const;
594
595 /** Recalculates the positions of objects and the height of the
596 line.
597 @param dc the wxDC to draw on
598 @param llist th e wxLayoutList
599 @param cursorPos if not NULL, set cursor screen position in there
600 @param cursorSize if not cursorPos != NULL, set cursor size in there
601 @param cursorStyle if non NULL where to store styleinfo for cursor pos
602 @param cx if cursorPos != NULL, the cursor x position
603 @param suppressStyleUpdate FALSe normally, only to suppress updating of m_StyleInfo
604 */
605 void Layout(wxDC &dc,
606 wxLayoutList *llist,
607 wxPoint *cursorPos = NULL,
608 wxPoint *cursorSize = NULL,
609 wxLayoutStyleInfo *cursorStyle = NULL,
610 int cx = 0,
611 bool suppressStyleUpdate = FALSE);
612 /** This function finds an object belonging to a given cursor
613 position. It assumes that Layout() has been called before.
614 @param dc the wxDC to use for calculations
615 @param xpos screen x position
616 @param found if non-NULL set to false if we return the last
617 object before the cursor, to true if we really have an object
618 for that position
619 @return pointer to the object
620 */
621 wxLayoutObject * FindObjectScreen(wxDC &dc,
622 CoordType xpos,
623 bool *found = NULL);
624 /** This sets the style info for the beginning of this line.
625 @param si styleinfo structure
626 */
627 void ApplyStyle(const wxLayoutStyleInfo &si)
628 { m_StyleInfo = si; }
629
630 //@}
631
632 /**@name List traversal */
633 //@{
634 /// Returns pointer to next line.
635 wxLayoutLine *GetNextLine(void) const { return m_Next; }
636 /// Returns pointer to previous line.
637 wxLayoutLine *GetPreviousLine(void) const { return m_Previous; }
638 /// Sets the link to the next line.
639 void SetNext(wxLayoutLine *next)
640 { m_Next = next; if(next) next->m_Previous = this; }
641 /// Sets the link to the previous line.
642 void SetPrevious(wxLayoutLine *previous)
643 { m_Previous = previous; if(previous) previous->m_Next = this; }
644 //@}
645
646 /// Returns the position of this line on the canvas.
647 wxPoint GetPosition(void) const { return m_Position; }
648 /// Returns the height of this line.
649 CoordType GetHeight(void) const { return m_Height; }
650 /// Returns the width of this line.
651 CoordType GetWidth(void) const { return m_Width; }
652 /// Recalculates the position of this line on the canvas.
653 wxPoint RecalculatePosition(wxLayoutList *llist);
654
655 /** Copies the contents of this line to another wxLayoutList
656 @param llist the wxLayoutList destination
657 @param from x cursor coordinate where to start
658 @param to x cursor coordinate where to stop, -1 for end of line
659 */
660 void Copy(wxLayoutList *llist,
661 CoordType from = 0,
662 CoordType to = -1);
663
664 #ifdef WXLAYOUT_DEBUG
665 void Debug(void);
666 #endif
667 wxLayoutStyleInfo const & GetStyleInfo() const { return m_StyleInfo; }
668
669 /// Returns dirty state
670 bool IsDirty(void) const { return m_Dirty; }
671 /** Marks this line as diry.
672 @param left xpos from where it is dirty or -1 for all
673 */
674 void MarkDirty(CoordType left = -1)
675 {
676 if ( left != -1 )
677 {
678 if ( m_updateLeft == -1 || left < m_updateLeft )
679 m_updateLeft = left;
680 }
681
682 m_Dirty = true;
683 }
684 /// Reset the dirty flag
685 void MarkClean() { m_Dirty = false; m_updateLeft = -1; }
686
687 private:
688 /// Destructor is private. Use DeleteLine() to remove it.
689 ~wxLayoutLine();
690
691 /**@name Functions to let the lines synchronise with each other. */
692 //@{
693 /** Sets the height of this line. Will mark following lines as
694 dirty.
695 @param height new height
696 */
697 void SetHeight(CoordType height, wxLayoutList *llist)
698 { m_Height = height; MarkDirty(); }
699
700 /** Updates the line numbers. */
701 void ReNumber(void);
702 //@}
703 private:
704 /// The line number.
705 CoordType m_LineNumber;
706 /// The line length in cursor positions.
707 CoordType m_Length;
708 /// The total height of the line.
709 CoordType m_Height;
710 /// The total width of the line on screen.
711 CoordType m_Width;
712 /// The baseline for drawing objects
713 CoordType m_BaseLine;
714 /// The position on the canvas.
715 wxPoint m_Position;
716 /// The list of objects
717 wxLayoutObjectList m_ObjectList;
718 /// Have we been changed since the last layout?
719 bool m_Dirty;
720 /// The coordinate of the left boundary of the update rectangle (if m_Dirty)
721 CoordType m_updateLeft;
722 /// Pointer to previous line if it exists.
723 wxLayoutLine *m_Previous;
724 /// Pointer to next line if it exists.
725 wxLayoutLine *m_Next;
726 /// A StyleInfo structure, holding the current settings.
727 wxLayoutStyleInfo m_StyleInfo;
728 /// Just to suppress gcc compiler warnings.
729 friend class dummy;
730 private:
731 wxLayoutLine(const wxLayoutLine &);
732 };
733
734
735 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
736
737 The wxLayoutList object
738
739 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
740 /** The wxLayoutList is a list of wxLayoutLine objects. It provides a
741 higher level of abstraction for the text and can generally be considered
742 as representing "the text".
743 */
744 class wxLayoutList
745 {
746 public:
747 /// Constructor.
748 wxLayoutList();
749 /// Destructor.
750 ~wxLayoutList();
751
752 #ifdef WXLAYOUT_USE_CARET
753 /// give us the pointer to the caret to use
754 void SetCaret(wxCaret *caret) { m_caret = caret; }
755 #endif // WXLAYOUT_USE_CARET
756
757 /// Clear the list.
758 void Clear(int family = wxROMAN,
759 int size=WXLO_DEFAULTFONTSIZE,
760 int style=wxNORMAL,
761 int weight=wxNORMAL,
762 int underline=0,
763 wxColour *fg=NULL,
764 wxColour *bg=NULL);
765 /// Empty: clear the list but leave font settings.
766 void Empty(void);
767
768 /** Enable or disable auto-formatting. Normally, while editing this
769 should be enabled which is the default. While
770 inserting/deleting lots of text, it makes sense to temporarily
771 disable this.
772 @param enable TRUE to enable, FALSE to disable
773 */
774 void SetAutoFormatting(bool enable = TRUE)
775 { m_AutoFormat = enable; }
776 /**@name Cursor Management */
777 //@{
778 /** Set new cursor position.
779 @param p new position
780 @return bool if it could be set
781 */
782 bool MoveCursorTo(wxPoint const &p);
783 /** Move cursor up or down.
784 @param n
785 @return bool if it could be moved
786 */
787 bool MoveCursorVertically(int n);
788 /** Move cursor left or right.
789 @param n = number of positions to move
790 @return bool if it could be moved
791 */
792 bool MoveCursorHorizontally(int n);
793 /** Move cursor to the left or right counting in words
794 @param n = number of positions in words
795 @param untilNext: puts the cursor at the start of the next word if true,
796 leaves it at the end of the current one otherwise
797 @return bool if it could be moved
798 */
799 bool MoveCursorWord(int n, bool untilNext = true);
800
801 /// Move cursor to end of line.
802 void MoveCursorToEndOfLine(void)
803 {
804 wxASSERT(m_CursorLine);
805 MoveCursorHorizontally(m_CursorLine->GetLength()-m_CursorPos.x);
806 }
807
808 /// Move cursor to the start of line.
809 void MoveCursorToBeginOfLine(void)
810 { MoveCursorHorizontally(-m_CursorPos.x); }
811
812 /// get the number of lines in the list
813 size_t GetNumLines() const { return m_numLines; }
814
815 /// Returns current cursor position.
816 const wxPoint &GetCursorPos(wxDC &dc) const { return m_CursorPos; }
817 const wxPoint &GetCursorPos() const { return m_CursorPos; }
818
819 /// move cursor to the end of text
820 void MoveCursorToEnd(void)
821 {
822 MoveCursorTo(wxPoint(0, GetNumLines() - 1));
823 MoveCursorToEndOfLine();
824 }
825
826 //@}
827
828 /**@name Editing functions.
829 All of these functions return true on success and false on
830 failure. */
831 //@{
832 /// Insert text at current cursor position.
833 bool Insert(wxString const &text);
834 /// Insert some other object at current cursor position.
835 bool Insert(wxLayoutObject *obj);
836 /// Inserts objects at current cursor positions
837 bool Insert(wxLayoutList *llist);
838
839 /// Inserts a linebreak at current cursor position.
840 bool LineBreak(void);
841 /** Wraps the current line. Searches to the left of the cursor to
842 break the line. Does nothing if the cursor position is before
843 the break position parameter.
844 @param column the break position for the line, maximum length
845 @return true if line got broken
846 */
847 bool WrapLine(CoordType column);
848 /** This function deletes npos cursor positions.
849 @param npos how many positions
850 @return true if everything got deleted
851 */
852 bool Delete(CoordType npos);
853
854 /** Delete the next n lines.
855 @param n how many lines to delete
856 @return how many it could not delete
857 */
858 int DeleteLines(int n);
859
860 /// Delete to end of line.
861 void DeleteToEndOfLine(void)
862 {
863 wxASSERT(m_CursorLine);
864 Delete(m_CursorLine->GetLength()-m_CursorPos.x);
865 }
866 /// Delete to begin of line.
867 void DeleteToBeginOfLine(void)
868 {
869 wxASSERT(m_CursorLine);
870 CoordType n = m_CursorPos.x;
871 #ifdef WXLAYOUT_DEBUG
872 wxASSERT(MoveCursorHorizontally(-n));
873 #else
874 MoveCursorHorizontally(-n);
875 #endif
876 Delete(n);
877 }
878
879 /** Delete the next word.
880 */
881 void DeleteWord(void)
882 {
883 wxASSERT(m_CursorLine);
884 m_CursorLine->DeleteWord(m_CursorPos.x);
885 }
886
887 //@}
888
889 /** Finds text in this list.
890 @param needle the text to find
891 @param cpos the position where to start the search
892 @return the cursor coord where it was found or (-1,-1)
893 */
894 wxPoint FindText(const wxString &needle, const wxPoint &cpos = wxPoint(0,0)) const;
895
896 /**@name Formatting options */
897 //@{
898 /// sets font parameters
899 void SetFont(int family, int size, int style,
900 int weight, int underline,
901 wxColour *fg,
902 wxColour *bg);
903 /// sets font parameters, colours by name
904 void SetFont(int family=-1, int size = -1, int style=-1,
905 int weight=-1, int underline = -1,
906 char const *fg = NULL,
907 char const *bg = NULL);
908 /// changes to the next larger font size
909 inline void SetFontLarger(void)
910 { SetFont(-1,(12*m_CurrentStyleInfo.size)/10); }
911 /// changes to the next smaller font size
912 inline void SetFontSmaller(void)
913 { SetFont(-1,(10*m_CurrentStyleInfo.size)/12); }
914
915 /// set font family
916 inline void SetFontFamily(int family) { SetFont(family); }
917 /// set font size
918 inline void SetFontSize(int size) { SetFont(-1,size); }
919 /// set font style
920 inline void SetFontStyle(int style) { SetFont(-1,-1,style); }
921 /// set font weight
922 inline void SetFontWeight(int weight) { SetFont(-1,-1,-1,weight); }
923 /// toggle underline flag
924 inline void SetFontUnderline(bool ul) { SetFont(-1,-1,-1,-1,(int)ul); }
925 /// set font colours by name
926 inline void SetFontColour(char const *fg, char const *bg = NULL)
927 { SetFont(-1,-1,-1,-1,-1,fg,bg); }
928 /// set font colours by colour
929 inline void SetFontColour(wxColour *fg, wxColour *bg = NULL)
930 { SetFont(-1,-1,-1,-1,-1,fg,bg); }
931
932 /**
933 Returns a pointer to the default settings.
934 This is only valid temporarily and should not be stored
935 anywhere.
936 @return the default settings of the list
937 */
938 wxLayoutStyleInfo &GetDefaultStyleInfo(void) { return m_DefaultStyleInfo ; }
939 wxLayoutStyleInfo &GetStyleInfo(void) { return m_CurrentStyleInfo ; }
940 const wxLayoutStyleInfo &GetStyleInfo(void) const { return m_CurrentStyleInfo ; }
941 const wxLayoutStyleInfo &GetCursorStyleInfo(void) const { return m_CursorStyleInfo ; }
942
943 /// is the current font underlined?
944 bool IsFontUnderlined() const { return GetCursorStyleInfo().underline != 0; }
945 /// is the current font bold?
946 bool IsFontBold() const { return GetCursorStyleInfo().weight == wxBOLD; }
947 /// is the current font italic?
948 bool IsFontItalic() const { return GetCursorStyleInfo().style == wxITALIC; }
949
950 /// set underline if it was off, turn it off if it was on
951 void ToggleFontUnderline()
952 { SetFontUnderline(!IsFontUnderlined()); }
953
954 /// make font bold if it was normal or make it normal if it was bold
955 void ToggleFontWeight()
956 { SetFontWeight(IsFontBold() ? wxNORMAL : wxBOLD); }
957
958 /// make font italic if it was normal or make it normal if it was italic
959 void ToggleFontItalics()
960 { SetFontStyle(IsFontItalic() ? wxNORMAL : wxITALIC); }
961
962 //@}
963
964 /**@name Drawing */
965 //@{
966 /** Draws the complete list on a wxDC.
967 @param dc the wxDC to draw on
968 @param offset an optional offset to shift printout
969 @param top optional y coordinate where to start drawing
970 @param bottom optional y coordinate where to stop drawing
971 @param clipStrictly if set, do not draw objects which reach
972 beyond "bottom". Set this when printing.
973 */
974 void Draw(wxDC &dc,
975 const wxPoint &offset = wxPoint(0,0),
976 CoordType top = -1, CoordType bottom = -1,
977 bool clipStrictly = false);
978
979 /** Calculates new layout for the list, like Draw() but does not
980 actually draw it.
981 @param dc the wxDC to draw on
982 @param bottom optional y coordinate where to stop calculating
983 @param forceAll force re-layout of all lines
984 @param cpos Can hold a cursorposition, and will be overwritten
985 with the corresponding DC position.
986 @param csize Will hold the cursor size relating to cpos.
987 */
988 void Layout(wxDC &dc, CoordType bottom = -1, bool forceAll = false,
989 wxPoint *cpos = NULL,
990 wxPoint *csize = NULL);
991
992 /** Ensure that the whole list will be recalculate on the next call
993 to Layout() or Draw().
994 @param redrawAll TRUE or FALSE to reset it
995 */
996 void ForceTotalLayout(bool redrawAll = TRUE)
997 { m_ReLayoutAll = redrawAll; }
998
999 /** Returns the screen coordinates relating to a given cursor
1000 position and the size of the cursor at that position.
1001 @param dc for which to calculate it
1002 @param cpos Cursor position to look for.
1003 @param csize If non-NULL, will be set to the cursor size.
1004 @return The cursor position on the DC.
1005 */
1006 wxPoint GetScreenPos(wxDC &dc, const wxPoint &cpos, wxPoint *csize = NULL);
1007
1008 /** Calculates new sizes for everything in the list, like Layout()
1009 but this is needed after the list got changed.
1010 @param dc the wxDC to draw on
1011 @param bottom optional y coordinate where to stop calculating
1012 */
1013 void Recalculate(wxDC &dc, CoordType bottom = -1);
1014
1015 /** Returns the size of the list in screen coordinates.
1016 The return value only makes sense after the list has been
1017 drawn.
1018 @return a wxPoint holding the maximal x/y coordinates used for
1019 drawing
1020 */
1021 wxPoint GetSize(void) const;
1022
1023 /** Returns the cursor position on the screen.
1024 */
1025 wxPoint GetCursorScreenPos(void) const;
1026
1027 /** Draws the cursor.
1028 @param active If true, draw a bold cursor to mark window as
1029 active.
1030 @param translate optional translation of cursor coords on screen
1031 */
1032 void DrawCursor(wxDC &dc,
1033 bool active = true,
1034 const wxPoint & translate = wxPoint(0,0));
1035
1036 /** This function finds an object belonging to a given screen
1037 position. It assumes that Layout() has been called before.
1038 @param pos screen position
1039 @param cursorPos if non NULL, store cursor position in there
1040 @param found if used, set this to true if we really found an
1041 object, to false if we had to take the object near to it
1042 @return pointer to the object
1043 */
1044 wxLayoutObject * FindObjectScreen(wxDC &dc,
1045 wxPoint const pos,
1046 wxPoint *cursorPos = NULL,
1047 bool *found = NULL);
1048
1049 /** Called by the objects to update the update rectangle.
1050 @param x horizontal coordinate to include in rectangle
1051 @param y vertical coordinate to include in rectangle
1052 */
1053 void SetUpdateRect(CoordType x, CoordType y);
1054 /** Called by the objects to update the update rectangle.
1055 @param p a point to include in it
1056 */
1057 void SetUpdateRect(const wxPoint &p)
1058 { SetUpdateRect(p.x,p.y); }
1059 /// adds the cursor position to the update rectangle
1060 void AddCursorPosToUpdateRect()
1061 {
1062 #ifndef WXLAYOUT_USE_CARET
1063 SetUpdateRect(m_CursorScreenPos);
1064 SetUpdateRect(m_CursorScreenPos+m_CursorSize);
1065 //#else - the caret will take care of refreshing itself
1066 #endif // !WXLAYOUT_USE_CARET
1067 }
1068 /// Invalidates the update rectangle.
1069 void InvalidateUpdateRect(void) { m_UpdateRectValid = false; }
1070 /// Returns the update rectangle.
1071 const wxRect *GetUpdateRect(void) const { return &m_UpdateRect; }
1072 //@}
1073
1074 /// get the current cursor size
1075 const wxPoint& GetCursorSize() const { return m_CursorSize; }
1076
1077 /**@name For exporting one object after another. */
1078 //@{
1079 /** Returns a pointer to the first line in the list. */
1080 wxLayoutLine *GetFirstLine(void)
1081 {
1082 wxASSERT(m_FirstLine);
1083 return m_FirstLine;
1084 }
1085 //@}
1086
1087 /// Begin selecting text
1088 void StartSelection(const wxPoint& cpos = wxPoint(-1,-1),
1089 const wxPoint& spos = wxPoint(-1,-1));
1090 // Continue selecting text
1091 void ContinueSelection(const wxPoint& cpos = wxPoint(-1,-1),
1092 const wxPoint& spos = wxPoint(-1,-1));
1093 /// End selecting text.
1094 void EndSelection(const wxPoint& cpos = wxPoint(-1,-1),
1095 const wxPoint& spos = wxPoint(-1,-1));
1096 /// Discard the current selection
1097 void DiscardSelection();
1098 /// Are we still selecting text?
1099 bool IsSelecting(void) const;
1100 /// Is the given point (text coords) selected?
1101 bool IsSelected(const wxPoint &cursor) const;
1102 /// Do we have a non null selection?
1103 bool HasSelection() const
1104 { return m_Selection.m_valid || m_Selection.m_selecting; }
1105
1106 /** Return the selection as a wxLayoutList.
1107 @param invalidate if true, the selection will be invalidated after this and can no longer be used.
1108 @return Another layout list object holding the selection, must be freed by caller
1109 */
1110 wxLayoutList *GetSelection(class wxLayoutDataObject *wxldo = NULL, bool invalidate = TRUE);
1111 /// Delete selected bit
1112 void DeleteSelection(void);
1113
1114 wxLayoutList *Copy(const wxPoint &from = wxPoint(0,0),
1115 const wxPoint &to = wxPoint(-1,-1));
1116
1117 /// starts highlighting of text for selections
1118 void StartHighlighting(wxDC &dc);
1119 /// ends highlighting of text for selections
1120 void EndHighlighting(wxDC &dc);
1121
1122 /** Tests whether this layout line is selected and needs
1123 highlighting.
1124 @param line to test for
1125 @param from set to first cursorpos to be highlighted (for returncode == -1)
1126 @param to set to last cursorpos to be highlighted (for returncode == -1)
1127 @return 0 = not selected, 1 = fully selected, -1 = partially
1128 selected
1129
1130 */
1131 int IsSelected(const wxLayoutLine *line, CoordType *from, CoordType *to);
1132
1133 void ApplyStyle(wxLayoutStyleInfo const &si, wxDC &dc);
1134 #ifdef WXLAYOUT_DEBUG
1135 void Debug(void);
1136 #endif
1137
1138 // for wxLayoutLine usage only
1139 void IncNumLines() { m_numLines++; }
1140 void DecNumLines() { m_numLines--; }
1141
1142 /// get the line by number
1143 wxLayoutLine *GetLine(CoordType index) const;
1144
1145 /** Reads objects from a string and inserts them.
1146 @param istr stream to read from, will bee changed
1147 */
1148 void Read(wxString &istr);
1149
1150 private:
1151 /// Clear the list.
1152 void InternalClear(void);
1153
1154 /// The list of lines.
1155 wxLayoutLine *m_FirstLine;
1156 /// The number of lines in the list (store instead recalculating for speed)
1157 size_t m_numLines;
1158
1159 /// The update rectangle which needs to be refreshed:
1160 wxRect m_UpdateRect;
1161 /// Is the update rectangle valid?
1162 bool m_UpdateRectValid;
1163
1164 /// Shall we auto-format?
1165 bool m_AutoFormat;
1166 /// Shall we re-layout everything?
1167 bool m_ReLayoutAll;
1168 /**@name Cursor Management */
1169 //@{
1170 /// Where the text cursor (column,line) is.
1171 wxPoint m_CursorPos;
1172 /// Where the cursor should be drawn.
1173 wxPoint m_CursorScreenPos;
1174 /// The line where the cursor is.
1175 wxLayoutLine *m_CursorLine;
1176 /// The size of the cursor.
1177 wxPoint m_CursorSize;
1178 /// Has the cursor moved (is m_CursorScreenPos up to date)?
1179 bool m_movedCursor;
1180 #ifdef WXLAYOUT_USE_CARET
1181 /// the caret
1182 wxCaret *m_caret;
1183 #endif // WXLAYOUT_USE_CARET
1184 //@}
1185
1186 /// selection.state and begin/end coordinates
1187 struct Selection
1188 {
1189 Selection() { m_valid = m_selecting = m_discarded = false; }
1190
1191 bool m_valid;
1192 bool m_selecting;
1193 bool m_discarded; // may be TRUE only until the next redraw
1194
1195 // returns true if we already have the screen coordinates of the
1196 // selection start and end
1197 bool HasValidScreenCoords() const
1198 { return m_ScreenA.x != -1 && m_ScreenB.x != -1; }
1199
1200 // the start and end of the selection coordinates in pixels
1201 wxPoint m_ScreenA, m_ScreenB;
1202
1203 // these coordinates are in text positions, not in pixels
1204 wxPoint m_CursorA, m_CursorB;
1205 } m_Selection;
1206 /** @name Font parameters. */
1207 //@{
1208 /// this object manages the fonts for us
1209 wxFontCache m_FontCache;
1210 /// the default setting:
1211 wxLayoutStyleInfo m_DefaultStyleInfo;
1212 /// the current setting:
1213 wxLayoutStyleInfo m_CurrentStyleInfo;
1214 /// the current setting:
1215 wxLayoutStyleInfo m_CursorStyleInfo;
1216 //@}
1217 };
1218
1219 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1220
1221 The wxLayoutDataObject for exporting data to the clipboard in our
1222 own format.
1223
1224 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1225 class wxLayoutDataObject : public wxCustomDataObject
1226 {
1227 public:
1228 wxLayoutDataObject()
1229 {
1230 SetFormat("application/wxlayoutlist");
1231 }
1232
1233 // type safe wrappers
1234 void SetLayoutData(const wxString& text)
1235 { SetData(text.length() + 1, text.c_str()); }
1236 const char *GetLayoutData() const { return (const char *)GetData(); }
1237 };
1238
1239 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1240
1241 The wxLayoutPrintout object for printing within the wxWindows print
1242 framework.
1243
1244 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1245 /** This class implements a wxPrintout for printing a wxLayoutList within
1246 the wxWindows printing framework.
1247 */
1248 class wxLayoutPrintout: public wxPrintout
1249 {
1250 public:
1251 /** Constructor.
1252 @param llist pointer to the wxLayoutList to be printed
1253 @param title title for PS file or windows
1254 */
1255 wxLayoutPrintout(wxLayoutList *llist,
1256 wxString const & title =
1257 "wxLayout Printout");
1258 /// Destructor.
1259 ~wxLayoutPrintout();
1260
1261 /** Function which prints the n-th page.
1262 @param page the page number to print
1263 @return bool true if we are not at end of document yet
1264 */
1265 bool OnPrintPage(int page);
1266 /** Checks whether page exists in document.
1267 @param page number of page
1268 @return true if page exists
1269 */
1270 bool HasPage(int page);
1271
1272 /** Gets called from wxWindows to find out which pages are existing.
1273 I'm not totally sure about the parameters though.
1274 @param minPage the first page in the document
1275 @param maxPage the last page in the document
1276 @param selPageFrom the first page to be printed
1277 @param selPageTo the last page to be printed
1278 */
1279 void GetPageInfo(int *minPage, int *maxPage,
1280 int *selPageFrom, int *selPageTo);
1281 protected:
1282 /** This little function scales the DC so that the printout has
1283 roughly the same size as the output on screen.
1284 @param dc the wxDC to scale
1285 @return the scale that was applied
1286 */
1287 float ScaleDC(wxDC *dc);
1288
1289 /* no longer used
1290 virtual void DrawHeader(wxDC &dc, wxPoint topleft, wxPoint bottomright, int pageno);
1291 */
1292 private:
1293 /// The list to print.
1294 wxLayoutList *m_llist;
1295 /// Title for PS file or window.
1296 wxString m_title;
1297 /// The real paper size.
1298 int m_PageHeight, m_PageWidth;
1299 /// How much we actually print per page.
1300 int m_PrintoutHeight;
1301 /// How many pages we need to print.
1302 int m_NumOfPages;
1303 /// Top left corner where we start printing.
1304 wxPoint m_Offset;
1305 };
1306
1307
1308 #endif // WXLLIST_H