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