1 /*-*- c++ -*-********************************************************
2 * wxLayoutList.h - a formatted text rendering engine for wxWindows *
4 * (C) 1998 by Karsten Ballüder (Ballueder@usa.net) *
7 *******************************************************************/
14 # pragma interface "wxllist.h"
21 #include "wx/printdlg.h"
22 #include "wx/generic/printps.h"
23 #include "wx/generic/prntdlgg.h"
25 // skip the following defines if embedded in M application
28 # define WXLAYOUT_DEBUG
32 # define WXLAYOUT_DEBUG
33 // The wxLayout classes can be compiled with std::string instead of wxString
34 //# define USE_STD_STRING
35 # define WXMENU_LAYOUT_LCLICK 1111
36 # define WXMENU_LAYOUT_RCLICK 1112
37 # define WXMENU_LAYOUT_DBLCLICK 1113
42 typedef std::string String
;
43 # define Str(str)(str.c_str())
45 typedef wxString String
;
49 #define WXLO_DEFAULTFONTSIZE 12
51 /// Types of currently supported layout objects.
52 enum wxLayoutObjectType
53 { WXLO_TYPE_INVALID
= 0, WXLO_TYPE_TEXT
, WXLO_TYPE_CMD
, WXLO_TYPE_ICON
, WXLO_TYPE_LINEBREAK
};
55 /// Type used for coordinates in drawing.
56 typedef long CoordType
;
59 class wxLayoutObjectBase
;
65 /** The base class defining the interface to each object which can be
66 part of the layout. Each object needs to draw itself and calculate
69 class wxLayoutObjectBase
74 virtual ~UserData() { }
77 /// return the type of this object
78 virtual wxLayoutObjectType
GetType(void) const { return WXLO_TYPE_INVALID
; } ;
79 /** Calculates the position etc of an object.
80 @param dc the wxDC to draw on
81 @param position where to draw the top left corner
82 @param baseLine the baseline for alignment, from top of box
84 virtual void Layout(wxDC
& dc
,
87 { m_Position
= position
; }
90 @param dc the wxDC to draw on
91 @param translation to be added to coordinates
93 virtual void Draw(wxDC
& dc
, wxPoint
const &translate
) {}
95 /** Calculates and returns the size of the object.
96 @param baseLine pointer where to store the baseline position of
97 this object (i.e. the height from the top of the box to the
99 @return the size of the object's box in pixels
101 virtual wxPoint
GetSize(CoordType
* baseLine
= NULL
) const
102 { return wxPoint(0,0); }
104 /** Calculates and returns the position of the object.
105 @return the size of the object's box in pixels
107 virtual wxPoint
GetPosition(void) const { return m_Position
; }
109 /// returns the number of cursor positions occupied by this object
110 virtual CoordType
CountPositions(void) const { return 1; }
113 wxLayoutObjectBase() { m_UserData
= NULL
; }
114 /// delete the user data
115 virtual ~wxLayoutObjectBase() { if(m_UserData
) delete m_UserData
; }
117 #ifdef WXLAYOUT_DEBUG
118 virtual void Debug(void);
121 /// query whether coordinates have changed since last drawing
122 virtual bool IsDirty(void) const { return true; }
124 /** Tells the object about some user data. This data is associated
125 with the object and will be deleted at destruction time.
127 void SetUserData(UserData
*data
) { m_UserData
= data
; }
128 /** Return the user data. */
129 void * GetUserData(void) const { return m_UserData
; }
132 /// optional data for application's use
133 UserData
*m_UserData
;
138 /// Define a list type of wxLayoutObjectBase pointers.
139 KBLIST_DEFINE(wxLayoutObjectList
, wxLayoutObjectBase
);
142 /// object for text block
143 class wxLayoutObjectText
: public wxLayoutObjectBase
146 wxLayoutObjectText(const String
&txt
);
148 virtual wxLayoutObjectType
GetType(void) const { return WXLO_TYPE_TEXT
; }
149 virtual void Layout(wxDC
&dc
, wxPoint position
, CoordType
152 virtual void Draw(wxDC
&dc
, wxPoint
const &translate
);
153 /** This returns the height and in baseLine the position of the
154 text's baseline within it's box. This is needed to properly
157 virtual wxPoint
GetSize(CoordType
*baseLine
= NULL
) const;
159 #ifdef WXLAYOUT_DEBUG
160 virtual void Debug(void);
163 virtual CoordType
CountPositions(void) const { return strlen(m_Text
.c_str()); }
164 virtual bool IsDirty(void) const { return m_IsDirty
; }
167 String
& GetText(void) { return m_Text
; }
168 void SetText(String
const &text
) { m_Text
= text
; }
172 /// size of the box containing text
173 long m_Width
, m_Height
;
174 /// the position of the baseline counted from the top of the box
176 /// coordinates have changed
181 class wxLayoutObjectIcon
: public wxLayoutObjectBase
184 wxLayoutObjectIcon(wxIcon
*icon
);
185 wxLayoutObjectIcon(wxIcon
const &icon
);
187 ~wxLayoutObjectIcon() { delete m_Icon
; }
189 virtual wxLayoutObjectType
GetType(void) const { return WXLO_TYPE_ICON
; }
190 virtual void Layout(wxDC
&dc
, wxPoint position
, CoordType baseLine
);
191 virtual void Draw(wxDC
&dc
, wxPoint
const &translate
);
193 virtual wxPoint
GetSize(CoordType
*baseLine
= NULL
) const;
194 virtual bool IsDirty(void) const { return m_IsDirty
; }
198 /// coordinates have changed
202 /// for export to html:
203 struct wxLayoutStyleInfo
205 int size
, family
, style
, weight
;
207 unsigned fg_red
, fg_green
, fg_blue
;
208 unsigned bg_red
, bg_green
, bg_blue
;
211 /// pseudo-object executing a formatting command in Draw()
212 class wxLayoutObjectCmd
: public wxLayoutObjectBase
215 virtual wxLayoutObjectType
GetType(void) const { return WXLO_TYPE_CMD
; }
216 virtual void Draw(wxDC
&dc
, wxPoint
const &translate
);
217 virtual void Layout(wxDC
&dc
, wxPoint position
, CoordType baseLine
);
218 wxLayoutObjectCmd(int size
, int family
, int style
, int weight
,
220 wxColour
const *fg
, wxColour
const *bg
);
221 ~wxLayoutObjectCmd();
222 /// caller must free pointer:
223 wxLayoutStyleInfo
*GetStyle(void) const ;
224 /// return the background colour for setting colour of window
225 wxColour
const *GetBGColour(void) const { return m_ColourBG
; }
229 /// foreground colour
230 wxColour
const *m_ColourFG
;
231 /// background colour
232 wxColour
const *m_ColourBG
;
235 /// this object doesn't do anything at all
236 class wxLayoutObjectLineBreak
: public wxLayoutObjectBase
239 virtual wxLayoutObjectType
GetType(void) const { return WXLO_TYPE_LINEBREAK
; }
243 class wxLayoutPrintout
;
245 class wxLayoutMargins
248 wxLayoutMargins() { top
= left
= 0; bottom
= right
= -1; }
256 This class provides a high level abstraction to the wxFText
258 It handles most of the character events with its own callback
259 functions, providing an editing ability. All events which cannot be
260 handled get passed to the parent window's handlers.
262 class wxLayoutList
: public wxLayoutObjectList
271 void AddObject(wxLayoutObjectBase
*obj
);
272 /// adds a text object
273 void AddText(String
const &txt
);
274 /// adds a line break
275 void LineBreak(void);
276 /// sets font parameters
277 void SetFont(int family
, int size
, int style
,
278 int weight
, int underline
,
281 /// sets font parameters, colours by name
282 void SetFont(int family
=-1, int size
= -1, int style
=-1,
283 int weight
=-1, int underline
= -1,
284 char const *fg
= NULL
,
285 char const *bg
= NULL
);
286 /// changes to the next larger font size
287 inline void SetFontLarger(void)
288 { SetFont(-1,(12*m_FontPtSize
)/10); }
289 /// changes to the next smaller font size
290 inline void SetFontSmaller(void)
291 { SetFont(-1,(10*m_FontPtSize
)/12); }
294 inline void SetFontFamily(int family
) { SetFont(family
); }
296 inline void SetFontSize(int size
) { SetFont(-1,size
); }
298 inline void SetFontStyle(int style
) { SetFont(-1,-1,style
); }
300 inline void SetFontWeight(int weight
) { SetFont(-1,-1,-1,weight
); }
301 /// toggle underline flag
302 inline void SetFontUnderline(bool ul
) { SetFont(-1,-1,-1,-1,(int)ul
); }
303 /// set font colours by name
304 inline void SetFontColour(char const *fg
, char const *bg
= NULL
) { SetFont(-1,-1,-1,-1,-1,fg
,bg
); }
306 /** Sets the wrap margin in cursor positions.
307 @param n the wrap margin, -1 to disable auto wrap
309 void SetWrapMargin(long n
= -1);
311 /// Wraps the current line if word wrap is enabled.
314 /** Re-layouts the list on a DC.
315 @param dc the dc to layout for
316 @param margins if not NULL, use these top and left margins
318 void Layout(wxDC
&dc
, wxLayoutMargins
*margins
= NULL
);
320 /** Draw the list on a given DC.
321 @param dc the dc to layout for
322 @param fromLine the first graphics line from where to draw
323 @param toLine the last line at which to draw
324 @param start if != iterator(NULL) start drawing from here
327 CoordType fromLine
= -1,
328 CoordType toLine
= -1,
329 iterator start
= iterator(NULL
),
330 wxPoint
const &translate
= wxPoint(0,0));
332 /** Deletes at least to the end of line and redraws */
333 void EraseAndDraw(wxDC
&dc
, iterator start
= iterator(NULL
),
334 wxPoint
const &translate
= wxPoint(0,0));
336 /** Finds the object occupying a certain screen position.
337 @return pointer to wxLayoutObjectBase or NULL if not found
339 wxLayoutObjectBase
*Find(wxPoint coords
) const;
341 #ifdef WXLAYOUT_DEBUG
343 void ShowCurrentObject();
347 bool IsDirty() const { return m_bModified
; }
348 bool CursorMoved(void) const { return m_CursorMoved
; }
350 /// called after the contents is saved, for example
351 void ResetDirty() { m_bModified
= FALSE
; }
353 /// for access by wxLayoutWindow:
354 void GetSize(CoordType
*max_x
, CoordType
*max_y
,
355 CoordType
*lineHeight
);
358 /**@name Functionality for editing */
360 /// set list editable or read only
361 void SetEditable(bool editable
= true) { m_Editable
= editable
; }
362 /// return true if list is editable
363 bool IsEditable(void) const { return m_Editable
; }
364 /// move cursor, returns true if it could move to the desired position
365 bool MoveCursor(int dx
= 0, int dy
= 0);
366 void SetCursor(wxPoint
const &p
);
367 void DrawCursor(wxDC
&dc
, bool erase
= false,wxPoint
const &translate
= wxPoint(0,0));
368 /// Get current cursor position cursor coords
369 wxPoint
GetCursor(void) const { return m_CursorPos
; }
370 /// Gets graphical coordinates of cursor
371 wxPoint
GetCursorCoords(void) const { return m_CursorCoords
; }
373 /// delete one or more cursor positions
374 void Delete(CoordType count
= 1);
375 void Insert(String
const &text
);
376 void Insert(wxLayoutObjectBase
*obj
);
377 void Clear(int family
= wxROMAN
, int size
=WXLO_DEFAULTFONTSIZE
, int style
=wxNORMAL
, int weight
=wxNORMAL
,
378 int underline
=0, char const *fg
="black", char const *bg
="white");
380 /// return a pointer to the default settings (dangerous, why?) FIXME:
381 wxLayoutObjectCmd
const *GetDefaults(void) const { return m_DefaultSetting
; }
383 /// returns the iterator for the object under the cursor
384 wxLayoutObjectList::iterator
GetCurrentObject(CoordType
*offset
=
386 { if(offset
) *offset
= m_CursorOffset
; return m_CursorObject
; }
388 // get the length of the line with the object pointed to by i, offs
389 // only used to decide whether we are before or after linebreak
390 CoordType
GetLineLength(wxLayoutObjectList::iterator i
,
392 wxLayoutPrintout
*MakePrintout(wxString
const &name
);
394 /// Return maximum X,Y coordinates
395 wxPoint
GetSize(void) const { return wxPoint(m_MaxX
, m_MaxY
); }
397 /// calculates current cursor coordinates, called in Layout()
398 void CalculateCursor(wxDC
&dc
);
400 /// toggle normal/bold cursor
401 void SetBoldCursor(bool bold
= true)
402 { m_boldCursor
= bold
; m_CursorMoved
= true;}
406 int m_FontFamily
, m_FontStyle
, m_FontWeight
;
408 bool m_FontUnderline
;
410 wxColour
const * m_ColourFG
;
411 wxColour
const * m_ColourBG
;
412 /// the default setting:
413 wxLayoutObjectCmd
*m_DefaultSetting
;
415 /// needs recalculation?
420 /// needs saving (i.e., was modified?)
423 // the currently updated line:
424 /// where do we draw next:
426 /// the height of the current line:
427 CoordType m_LineHeight
;
428 /// maximum drawn x position so far
430 /// maximum drawn y position:
433 //---- this is needed for editing:
434 /// where is the text cursor (column,line):
436 /// where to draw the cursor
437 wxPoint m_CursorCoords
;
438 /// how large to draw it
439 wxPoint m_CursorSize
;
440 /// object iterator for current cursor position:
441 iterator m_CursorObject
;
442 /// position of cursor within m_CursorObject:
443 CoordType m_CursorOffset
;
445 /// to store content overwritten by cursor
446 wxMemoryDC m_CursorMemDC
;
448 /// which is the last line
452 /// find the object to the cursor position and returns the offset
454 wxLayoutObjectList::iterator
FindObjectCursor(wxPoint
*cpos
, CoordType
*offset
= NULL
);
455 /// get the wrap margin
456 inline long GetWrapMargin(void) const { return m_WrapMargin
; }
457 /// do we do wrapping?
458 inline bool DoWordWrap(void) const { return m_WrapMargin
!= -1; }
460 /// Resets the font settings etc to default values
461 void ResetSettings(wxDC
&dc
);
462 /// remembers the last cursor position for which FindObjectCursor was called
463 wxPoint m_FoundCursor
;
464 /// remembers the iterator to the object related to m_FoundCursor
465 wxLayoutObjectList::iterator m_FoundIterator
;
468 /// draw a bold cursor?
472 class wxLayoutPrintout
: public wxPrintout
475 wxLayoutPrintout(wxLayoutList
&llist
, wxString
const & title
=
476 "wxLayout Printout");
477 bool OnPrintPage(int page
);
478 bool HasPage(int page
);
479 bool OnBeginDocument(int startPage
, int endPage
);
480 void GetPageInfo(int *minPage
, int *maxPage
, int *selPageFrom
, int
482 void OnPreparePrinting(void);
484 virtual void DrawHeader(wxDC
&dc
, wxPoint topleft
, wxPoint bottomright
, int pageno
);
487 wxLayoutList
*m_llist
;
489 int m_PageHeight
, m_PageWidth
;
490 // how much we actually print per page
491 int m_PrintoutHeight
;
492 wxLayoutMargins m_Margins
;