/*-*- c++ -*-********************************************************
* wxLayoutList.h - a formatted text rendering engine for wxWindows *
* *
- * (C) 1998 by Karsten Ballüder (Ballueder@usa.net) *
+ * (C) 1999 by Karsten Ballüder (Ballueder@usa.net) *
* *
* $Id$
*******************************************************************/
+
+
#ifndef WXLLIST_H
#define WXLLIST_H
#include "kbList.h"
#include "wx/wx.h"
-#include "wx/print.h"
-#include "wx/printdlg.h"
-#include "wx/generic/printps.h"
-#include "wx/generic/prntdlgg.h"
+#include "wx/print.h"
+#include "wx/printdlg.h"
+#include "wx/generic/printps.h"
+#include "wx/generic/prntdlgg.h"
// skip the following defines if embedded in M application
-#ifdef M_BASEDIR
-# ifdef DEBUG
-//# define WXLAYOUT_DEBUG
-# endif
-#else
- // for testing only:
-# define WXLAYOUT_DEBUG
- // The wxLayout classes can be compiled with std::string instead of wxString
- //# define USE_STD_STRING
+#ifndef M_BASEDIR
+# define WXMENU_LAYOUT_LCLICK 1111
+# define WXMENU_LAYOUT_RCLICK 1112
+# define WXMENU_LAYOUT_DBLCLICK 1113
#endif
-#ifdef USE_STD_STRING
-# include <string>
- typedef std::string String;
-# define Str(str)(str.c_str())
+// do not enable debug mode within Mahogany
+#if defined(__WXDEBUG__) && ! defined(M_BASEDIR)
+# define WXLAYOUT_DEBUG
+#endif
+
+#ifdef WXLAYOUT_DEBUG
+# define WXLO_TRACE(x) wxLogDebug(x)
#else
- typedef wxString String;
-# define Str(str) str
+# define WXLO_TRACE(x)
+#endif
+
+#define WXLO_DEBUG_URECT 0
+
+#ifndef WXLO_DEFAULTFONTSIZE
+# define WXLO_DEFAULTFONTSIZE 12
#endif
+
/// Types of currently supported layout objects.
enum wxLayoutObjectType
-{ WXLO_TYPE_INVALID = 0, WXLO_TYPE_TEXT, WXLO_TYPE_CMD, WXLO_TYPE_ICON, WXLO_TYPE_LINEBREAK };
+{
+ /// illegal object type, should never appear
+ WXLO_TYPE_INVALID = 0,
+ /// text object, containing normal text
+ WXLO_TYPE_TEXT,
+ /// command object, containing font or colour changes
+ WXLO_TYPE_CMD,
+ /// icon object, any kind of image
+ WXLO_TYPE_ICON
+};
-/// Type used for coordinates in drawing.
+/// Type used for coordinates in drawing. Must be signed.
typedef long CoordType;
+// Forward declarations.
class wxLayoutList;
-class wxLayoutObjectBase;
-
+class wxLayoutObject;
class wxDC;
class wxColour;
class wxFont;
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ The wxLayout objects which make up the lines.
+
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
/** The base class defining the interface to each object which can be
part of the layout. Each object needs to draw itself and calculate
its size.
*/
-class wxLayoutObjectBase
+class wxLayoutObject
{
public:
+ /** This structure can be used to contain data associated with the
+ object.
+ It is refcounted, so the caller has to do a DecRef() on it
+ instead of a delete.
+ */
+ struct UserData
+ {
+ UserData() { m_refcount = 1; }
+ void IncRef(void) { m_refcount++; }
+ void DecRef(void) { m_refcount--; if(m_refcount == 0) delete this;}
+ private:
+ int m_refcount;
+ protected:
+ virtual ~UserData() { wxASSERT(m_refcount == 0); }
+ /// prevents gcc from generating stupid warnings
+ friend class dummy_UserData;
+ };
+
/// return the type of this object
- virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_INVALID; } ;
+ virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_INVALID; }
+ /** Calculates the size of an object.
+ @param dc the wxDC to draw on
+ @param llist the wxLayoutList
+ */
+ virtual void Layout(wxDC &dc, class wxLayoutList *llist) = 0;
+
/** Draws an object.
@param dc the wxDC to draw on
- @param position where to draw the top left corner
- @param baseLine the baseline for alignment, from top of box
- @draw if set to false, do not draw but just calculate sizes
- */
- virtual void Draw(wxDC &dc, wxPoint position, CoordType baseLine,
- bool draw = true) {};
-
- /** Calculates and returns the size of the object. May need to be
- called twice to work.
- @param baseLine pointer where to store the baseline position of
- this object (i.e. the height from the top of the box to the
- baseline)
+ @param coords where to draw the baseline of the object.
+ @param wxllist pointer to wxLayoutList
+ @param begin if !=-1, from which position on to highlight it
+ @param end if begin !=-1, how many positions to highlight it
+ */
+ virtual void Draw(wxDC & /* dc */,
+ wxPoint const & /* coords */,
+ class wxLayoutList *wxllist,
+ CoordType begin = -1,
+ CoordType end = -1) { }
+
+ /** Calculates and returns the size of the object.
+ @param top where to store height above baseline
+ @param bottom where to store height below baseline
@return the size of the object's box in pixels
*/
- virtual wxPoint GetSize(CoordType *baseLine) const { return
- wxPoint(0,0); };
+ virtual wxPoint GetSize(CoordType * top, CoordType *bottom) const
+ { *top = 0; *bottom = 0; return wxPoint(0,0); }
+
+ /// Return just the width of the object on the screen.
+ virtual CoordType GetWidth(void) const { return 0; }
/// returns the number of cursor positions occupied by this object
- virtual CoordType CountPositions(void) const { return 1; }
+ virtual CoordType GetLength(void) const { return 1; }
+ /** Returns the cursor offset relating to the screen x position
+ relative to begin of object.
+ @param dc the wxDC to use for calculations
+ @param xpos relative x position from head of object
+ @return cursor coordinate offset
+ */
+ virtual CoordType GetOffsetScreen(wxDC &dc, CoordType xpos) const { return 0; }
/// constructor
- wxLayoutObjectBase() { m_UserData = NULL; }
- /// note: any user data will be freed at the time the object is deleted
- virtual ~wxLayoutObjectBase() { if(m_UserData) delete m_UserData; }
+ wxLayoutObject() { m_UserData = NULL; }
+ /// delete the user data
+ virtual ~wxLayoutObject() { if(m_UserData) m_UserData->DecRef(); }
+
#ifdef WXLAYOUT_DEBUG
virtual void Debug(void);
#endif
/** Tells the object about some user data. This data is associated
with the object and will be deleted at destruction time.
*/
- void SetUserData(void *data) { m_UserData = data; }
+ void SetUserData(UserData *data)
+ {
+ if(m_UserData)
+ m_UserData->DecRef();
+ m_UserData = data;
+ m_UserData->IncRef();
+ }
+
/** Return the user data. */
- void * GetUserData(void) const { return m_UserData; }
-private:
+ void * GetUserData(void) const { if(m_UserData) m_UserData->IncRef(); return m_UserData; }
+
+ /** Makes a copy of this object.
+ */
+ virtual wxLayoutObject *Copy(void) = 0;
+protected:
/// optional data for application's use
- void * m_UserData;
+ UserData *m_UserData;
};
-/// Define a list type of wxLayoutObjectBase pointers.
-KBLIST_DEFINE(wxLayoutObjectList, wxLayoutObjectBase);
+/// Define a list type of wxLayoutObject pointers.
+KBLIST_DEFINE(wxLayoutObjectList, wxLayoutObject);
+
+/// An illegal iterator to save typing.
+#define NULLIT (wxLayoutObjectList::iterator(NULL))
+/// The iterator type.
+#define wxLOiterator wxLayoutObjectList::iterator
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-/// object for text block
-class wxLayoutObjectText : public wxLayoutObjectBase
+ wxLayoutObjectText
+
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/** This class implements a wxLayoutObject holding plain text.
+ */
+class wxLayoutObjectText : public wxLayoutObject
{
public:
+ wxLayoutObjectText(const wxString &txt);
+
virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_TEXT; }
- virtual void Draw(wxDC &dc, wxPoint position, CoordType baseLine,
- bool draw = true);
- /** This returns the height and in baseLine the position of the
- text's baseline within it's box. This is needed to properly
- align text objects.
+ virtual void Layout(wxDC &dc, class wxLayoutList *llist);
+ virtual void Draw(wxDC &dc, wxPoint const &coords,
+ class wxLayoutList *wxllist,
+ CoordType begin = -1,
+ CoordType end = -1);
+ /** Calculates and returns the size of the object.
+ @param top where to store height above baseline
+ @param bottom where to store height below baseline
+ @return the size of the object's box in pixels
*/
- virtual wxPoint GetSize(CoordType *baseLine) const;
+ virtual wxPoint GetSize(CoordType * top, CoordType *bottom) const;
+ /// Return just the width of the object on the screen.
+ virtual CoordType GetWidth(void) const { return m_Width; }
+ /** Returns the cursor offset relating to the screen x position
+ relative to begin of object.
+ @param dc the wxDC to use for calculations
+ @param xpos relative x position from head of object
+ @return cursor coordinate offset
+ */
+ virtual CoordType GetOffsetScreen(wxDC &dc, CoordType xpos) const;
+
+
#ifdef WXLAYOUT_DEBUG
virtual void Debug(void);
#endif
- wxLayoutObjectText(const String &txt);
- virtual CoordType CountPositions(void) const { return strlen(m_Text.c_str()); }
+ virtual CoordType GetLength(void) const { return strlen(m_Text.c_str()); }
// for editing:
- String & GetText(void) { return m_Text; }
- void SetText(String const &text) { m_Text = text; }
+ wxString & GetText(void) { return m_Text; }
+ void SetText(wxString const &text) { m_Text = text; }
+ /** Makes a copy of this object.
+ */
+ virtual wxLayoutObject *Copy(void);
private:
- String m_Text;
+ wxString m_Text;
/// size of the box containing text
long m_Width, m_Height;
- /// the position of the baseline counted from the top of the box
- long m_BaseLine;
+ /// Height above baseline.
+ long m_Top;
+ /// Height below baseline.
+ long m_Bottom;
};
-/// icon/pictures:
-class wxLayoutObjectIcon : public wxLayoutObjectBase
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ wxLayoutObjectIcon
+
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/** This class implements a wxLayoutObject holding a graphic.
+ */
+class wxLayoutObjectIcon : public wxLayoutObject
{
public:
+ wxLayoutObjectIcon(wxBitmap *icon);
+ wxLayoutObjectIcon(wxBitmap const &icon);
+
+ ~wxLayoutObjectIcon() { delete m_Icon; }
+
virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_ICON; }
- virtual void Draw(wxDC &dc, wxPoint position, CoordType baseLine,
- bool draw = true);
- virtual wxPoint GetSize(CoordType *baseLine) const;
- wxLayoutObjectIcon(wxIcon *icon);
+ virtual void Layout(wxDC &dc, class wxLayoutList *llist);
+ virtual void Draw(wxDC &dc, wxPoint const &coords,
+ class wxLayoutList *wxllist,
+ CoordType begin = -1,
+ CoordType end = -1);
+ /** Calculates and returns the size of the object.
+ @param top where to store height above baseline
+ @param bottom where to store height below baseline
+ @return the size of the object's box in pixels
+ */
+ virtual wxPoint GetSize(CoordType * top, CoordType *bottom) const;
+ /// Return just the width of the object on the screen.
+ virtual CoordType GetWidth(void) const { return m_Icon->GetWidth(); }
+ // return a pointer to the icon
+ wxBitmap *GetIcon(void) const { return m_Icon; }
+ /** Makes a copy of this object.
+ */
+ virtual wxLayoutObject *Copy(void);
private:
- wxIcon *m_Icon;
+ wxBitmap *m_Icon;
};
-/// for export to html:
+/** This structure holds all formatting information. Members which are
+ undefined (for a CmdObject this means: no change), are set to -1.
+*/
struct wxLayoutStyleInfo
{
- int size, family, style, weight;
- bool underline;
- unsigned fg_red, fg_green, fg_blue;
- unsigned bg_red, bg_green, bg_blue;
+ wxLayoutStyleInfo(int ifamily = -1,
+ int isize = -1,
+ int istyle = -1,
+ int iweight = -1,
+ int iul = -1,
+ wxColour *fg = NULL,
+ wxColour *bg = NULL);
+ wxColour & GetBGColour()
+ {
+ return m_bg;
+ }
+ wxLayoutStyleInfo & operator=(const wxLayoutStyleInfo &right);
+ /// Font change parameters.
+ int size, family, style, weight, underline;
+ /// Colours
+ wxColour m_bg, m_fg;
+ bool m_fg_valid, m_bg_valid;
};
-/// pseudo-object executing a formatting command in Draw()
-class wxLayoutObjectCmd : public wxLayoutObjectBase
+
+class wxFontCacheEntry
{
public:
- virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_CMD; }
- virtual void Draw(wxDC &dc, wxPoint position, CoordType baseLine,
- bool draw = true);
- wxLayoutObjectCmd(int size, int family, int style, int weight,
- bool underline,
- wxColour const *fg, wxColour const *bg);
- ~wxLayoutObjectCmd();
- /// caller must free pointer:
- wxLayoutStyleInfo *GetStyle(void) const ;
- /// return the background colour for setting colour of window
- wxColour const *GetBGColour(void) const { return m_ColourBG; }
+ wxFontCacheEntry(int family, int size, int style, int weight,
+ bool underline)
+ {
+ m_Family = family; m_Size = size; m_Style = style;
+ m_Weight = weight; m_Underline = underline;
+ m_Font = new wxFont(m_Size, m_Family,
+ m_Style, m_Weight, m_Underline);
+ }
+ bool Matches(int family, int size, int style, int weight,
+ bool underline) const
+ {
+ return size == m_Size && family == m_Family
+ && style == m_Style && weight == m_Weight
+ && underline == m_Underline;
+ }
+ wxFont & GetFont(void) { return *m_Font; }
+ ~wxFontCacheEntry()
+ {
+ delete m_Font;
+ }
private:
- /// the font to use
- wxFont *m_font;
- /// foreground colour
- wxColour const *m_ColourFG;
- /// background colour
- wxColour const *m_ColourBG;
+ wxFont *m_Font;
+ int m_Family, m_Size, m_Style, m_Weight;
+ bool m_Underline;
};
-/// this object doesn't do anything at all
-class wxLayoutObjectLineBreak : public wxLayoutObjectBase
+KBLIST_DEFINE(wxFCEList, wxFontCacheEntry);
+
+class wxFontCache
{
public:
- virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_LINEBREAK; }
+ wxFont & GetFont(int family, int size, int style, int weight,
+ bool underline);
+ wxFont & GetFont(wxLayoutStyleInfo const &si)
+ {
+ return GetFont(si.family, si.size, si.style, si.weight, si.underline);
+ }
+private:
+ wxFCEList m_FontList;
};
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-class wxLayoutPrintout;
+ wxLayoutObjectCmd
-/**
- This class provides a high level abstraction to the wxFText
- classes.
- It handles most of the character events with its own callback
- functions, providing an editing ability. All events which cannot be
- handled get passed to the parent window's handlers.
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/** This class implements a wxLayoutObject holding style change commands.
+ */
+class wxLayoutObjectCmd : public wxLayoutObject
+{
+public:
+ virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_CMD; }
+ virtual void Layout(wxDC &dc, class wxLayoutList *llist);
+ virtual void Draw(wxDC &dc, wxPoint const &coords,
+ class wxLayoutList *wxllist,
+ CoordType begin = -1,
+ CoordType end = -1);
+ wxLayoutObjectCmd(int family = -1,
+ int size = -1,
+ int style = -1,
+ int weight = -1,
+ int underline = -1,
+ wxColour *fg = NULL,
+ wxColour *bg = NULL);
+ ~wxLayoutObjectCmd();
+ /** Stores the current style in the styleinfo structure */
+ wxLayoutStyleInfo * GetStyle(void) const;
+ /** Makes a copy of this object.
+ */
+ virtual wxLayoutObject *Copy(void);
+private:
+ wxLayoutStyleInfo *m_StyleInfo;
+};
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ The wxLayoutLine object
+
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/// forward declaration
+class wxLayoutList;
+
+/** This class represents a single line of objects to be displayed.
+ It knows its height and total size and whether it needs to be
+ redrawn or not.
+ It has pointers to its first and next line so it can automatically
+ update them as needed.
*/
-class wxLayoutList : public wxLayoutObjectList
+class wxLayoutLine
{
public:
- wxLayoutList();
+ /** Constructor.
+ @param prev pointer to previous line or NULL
+ @param next pointer to following line or NULL
+ @param llist pointer to layout list
+ */
+ wxLayoutLine(wxLayoutLine *prev, wxLayoutList *llist);
+ /** This function inserts a new object at cursor position xpos.
+ @param xpos where to insert new object
+ @param obj the object to insert
+ @return true if that xpos existed and the object was inserted
+ */
+ bool Insert(CoordType xpos, wxLayoutObject *obj);
+
+ /** This function inserts text at cursor position xpos.
+ @param xpos where to insert
+ @param text the text to insert
+ @return true if that xpos existed and the object was inserted
+ */
+ bool Insert(CoordType xpos, wxString text);
+
+ /** This function appends an object to the line.
+ @param obj the object to insert
+ */
+ void Append(wxLayoutObject * obj)
+ {
+ wxASSERT(obj);
+ m_ObjectList.push_back(obj);
+ m_Length += obj->GetLength();
+ }
+
+ /** This function appens the next line to this, i.e. joins the two
+ lines into one.
+ */
+ void MergeNextLine(wxLayoutList *llist);
+
+ /** This function deletes npos cursor positions from position xpos.
+ @param xpos where to delete
+ @param npos how many positions
+ @return number of positions still to be deleted
+ */
+ CoordType Delete(CoordType xpos, CoordType npos);
+
+ /** This function breaks the line at a given cursor position.
+ @param xpos where to break it
+ @return pointer to the new line object replacing the old one
+ */
+ wxLayoutLine *Break(CoordType xpos, wxLayoutList *llist);
+
+ /** Deletes the next word from this position, including leading
+ whitespace.
+ This function does not delete over font changes, i.e. a word
+ with formatting instructions in the middle of it is treated as
+ two (three actually!) words. In fact, if the cursor is on a non-text object, that
+ one is treated as a word.
+ @param xpos from where to delete
+ @return true if a word was deleted
+ */
+ bool DeleteWord(CoordType npos);
+
+ /** Finds a suitable position left to the given column to break the
+ line.
+ @param column we want to break the line to the left of this
+ @return column for breaking line or -1 if no suitable location found
+ */
+ CoordType GetWrapPosition(CoordType column);
+
+ /** Finds the object which covers the cursor position xpos in this
+ line.
+ @param xpos the column number
+ @param offset where to store the difference between xpos and
+ the object's head
+ @return iterator to the object or NULLIT
+ */
+ wxLayoutObjectList::iterator FindObject(CoordType xpos, CoordType
+ *offset) const ;
+
+ /** Finds the object which covers the screen position xpos in this
+ line.
+ @param dc the wxDC to use for calculations
+ @param xpos the screen x coordinate
+ @param offset where to store the difference between xpos and
+ the object's head
+ @return iterator to the object or NULLIT
+ */
+ wxLayoutObjectList::iterator FindObjectScreen(wxDC &dc,
+ CoordType xpos,
+ CoordType *offset,
+ bool *found = NULL) const ;
+
+ /** Finds text in this line.
+ @param needle the text to find
+ @param xpos the position where to start the search
+ @return the cursoor coord where it was found or -1
+ */
+ CoordType FindText(const wxString &needle, CoordType xpos = 0) const;
+
+ /** Get the first object in the list. This is used by the wxlparser
+ functions to export the list.
+ @return iterator to the first object
+ */
+ wxLayoutObjectList::iterator GetFirstObject(void)
+ {
+ return m_ObjectList.begin();
+ }
+
+ /** Deletes this line, returns pointer to next line.
+ @param update If true, update all following lines.
+ */
+ wxLayoutLine *DeleteLine(bool update, wxLayoutList *llist);
+
+ /**@name Cursor Management */
+ //@{
+ /** Return the line number of this line.
+ @return the line number
+ */
+ inline CoordType GetLineNumber(void) const { return m_LineNumber; }
+ /** Return the length of the line.
+ @return line lenght in cursor positions
+ */
+ inline CoordType GetLength(void) const { return m_Length; }
+ //@}
+
+ /**@name Drawing and Layout */
+ //@{
+ /** Draws the line on a wxDC.
+ @param dc the wxDC to draw on
+ @param llist the wxLayoutList
+ @param offset an optional offset to shift printout
+ */
+ void Draw(wxDC &dc,
+ wxLayoutList *llist,
+ const wxPoint &offset = wxPoint(0,0)) const;
+
+ /** Recalculates the positions of objects and the height of the
+ line.
+ @param dc the wxDC to draw on
+ @param llist th e wxLayoutList
+ @param cursorPos if not NULL, set cursor screen position in there
+ @param cursorSize if not cursorPos != NULL, set cursor size in there
+ @param cx if cursorPos != NULL, the cursor x position
+ */
+ void Layout(wxDC &dc,
+ wxLayoutList *llist,
+ wxPoint *cursorPos = NULL,
+ wxPoint *cursorSize = NULL,
+ int cx = 0);
+ /** This function finds an object belonging to a given cursor
+ position. It assumes that Layout() has been called before.
+ @param dc the wxDC to use for calculations
+ @param xpos screen x position
+ @param found if non-NULL set to false if we return the last
+ object before the cursor, to true if we really have an object
+ for that position
+ @return pointer to the object
+ */
+ wxLayoutObject * FindObjectScreen(wxDC &dc, CoordType xpos, bool
+ *found = NULL);
+
+ //@}
+
+ /**@name List traversal */
+ //@{
+ /// Returns pointer to next line.
+ wxLayoutLine *GetNextLine(void) const { return m_Next; }
+ /// Returns pointer to previous line.
+ wxLayoutLine *GetPreviousLine(void) const { return m_Previous; }
+ /// Sets the link to the next line.
+ void SetNext(wxLayoutLine *next)
+ { m_Next = next; if(next) next->m_Previous = this; }
+ /// Sets the link to the previous line.
+ void SetPrevious(wxLayoutLine *previous)
+ { m_Previous = previous; if(previous) previous->m_Next = this; }
+ //@}
+
+ /// Returns the position of this line on the canvas.
+ wxPoint GetPosition(void) const { return m_Position; }
+ /// Returns the height of this line.
+ CoordType GetHeight(void) const { return m_Height; }
+ /// Returns the width of this line.
+ CoordType GetWidth(void) const { return m_Width; }
+ /** This will recalculate the position and size of this line.
+ If called recursively it will abort if the position of an
+ object is unchanged, assuming that none of the following
+ objects need to move.
+ @param recurse if greater 0 then it will be used as the
+ minimum(!) recursion level, continue with all lines till the end of
+ the list or until the coordinates no longer changed.
+ */
+ void RecalculatePositions(int recurse, wxLayoutList *llist);
+ /// Recalculates the position of this line on the canvas.
+ wxPoint RecalculatePosition(wxLayoutList *llist);
+
+ /** Copies the contents of this line to another wxLayoutList
+ @param llist the wxLayoutList destination
+ @param from x cursor coordinate where to start
+ @param to x cursor coordinate where to stop, -1 for end of line
+ */
+ void Copy(wxLayoutList *llist,
+ CoordType from = 0,
+ CoordType to = -1);
+#ifdef WXLAYOUT_DEBUG
+ void Debug(void);
+#endif
+ wxLayoutStyleInfo &GetStyleInfo() { return m_StyleInfo; }
+
+ /// Returns dirty state
+ bool IsDirty(void) const { return m_Dirty; }
+ /// Marks line as diry.
+ void MarkDirty(void) { m_Dirty = true; }
+private:
+ /// Destructor is private. Use DeleteLine() to remove it.
+ ~wxLayoutLine();
+
+ /**@name Functions to let the lines synchronise with each other. */
+ //@{
+ /** Sets the height of this line. Will mark following lines as
+ dirty.
+ @param height new height
+ */
+ void SetHeight(CoordType height, wxLayoutList *llist)
+ { m_Height = height; RecalculatePositions(true, llist); }
+
+ /** Moves the linenumbers one on, because a line has been inserted
+ or deleted.
+ @param delta either +1 or -1
+ */
+ void MoveLines(int delta)
+ {
+ m_LineNumber += delta;
+ if(m_Next) m_Next->MoveLines(delta);
+ }
+ //@}
+private:
+ /// The line number.
+ CoordType m_LineNumber;
+ /// The line length in cursor positions.
+ CoordType m_Length;
+ /// The total height of the line.
+ CoordType m_Height;
+ /// The total width of the line on screen.
+ CoordType m_Width;
+ /// The baseline for drawing objects
+ CoordType m_BaseLine;
+ /// The position on the canvas.
+ wxPoint m_Position;
+ /// The list of objects
+ wxLayoutObjectList m_ObjectList;
+ /// Have we been changed since the last layout?
+ bool m_Dirty;
+ /// Pointer to previous line if it exists.
+ wxLayoutLine *m_Previous;
+ /// Pointer to next line if it exists.
+ wxLayoutLine *m_Next;
+ /// A StyleInfo structure, holding the current settings.
+ wxLayoutStyleInfo m_StyleInfo;
+ /// Just to suppress gcc compiler warnings.
+ friend class dummy;
+private:
+ wxLayoutLine(const wxLayoutLine &);
+};
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ The wxLayoutList object
+
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/** The wxLayoutList is a list of wxLayoutLine objects. It provides a
+ higher level of abstraction for the text and can generally be considered
+ as representing "the text".
+ */
+class wxLayoutList
+{
+public:
+ /// Constructor.
+ wxLayoutList();
/// Destructor.
~wxLayoutList();
- /// adds an object:
- void AddObject(wxLayoutObjectBase *obj);
- void AddText(String const &txt);
+ /// Clear the list.
+ void Clear(int family = wxROMAN,
+ int size=WXLO_DEFAULTFONTSIZE,
+ int style=wxNORMAL,
+ int weight=wxNORMAL,
+ int underline=0,
+ wxColour *fg=NULL,
+ wxColour *bg=NULL);
+ /// Empty: clear the list but leave font settings.
+ void Empty(void);
+
+ /**@name Cursor Management */
+ //@{
+ /** Set new cursor position.
+ @param p new position
+ @return bool if it could be set
+ */
+ bool MoveCursorTo(wxPoint const &p);
+ /** Move cursor up or down.
+ @param n
+ @return bool if it could be moved
+ */
+ bool MoveCursorVertically(int n);
+ /** Move cursor left or right.
+ @param n
+ @return bool if it could be moved
+ */
+ bool MoveCursorHorizontally(int n);
- void LineBreak(void);
+ /// Move cursor to end of line.
+ void MoveCursorToEndOfLine(void)
+ {
+ wxASSERT(m_CursorLine);
+ MoveCursorHorizontally(m_CursorLine->GetLength()-m_CursorPos.x);
+ }
+
+ /// Move cursor to begin of line.
+ void MoveCursorToBeginOfLine(void)
+ { MoveCursorHorizontally(-m_CursorPos.x); }
+
+ /// Returns current cursor position.
+ wxPoint GetCursorPos(wxDC &dc) const { return m_CursorPos; }
+ wxPoint GetCursorPos() const { return m_CursorPos; }
+
+ //@}
+
+ /**@name Editing functions.
+ All of these functions return true on success and false on
+ failure. */
+ //@{
+ /// Insert text at current cursor position.
+ bool Insert(wxString const &text);
+ /// Insert some other object at current cursor position.
+ bool Insert(wxLayoutObject *obj);
+ /// Inserts a linebreak at current cursor position.
+ bool LineBreak(void);
+ /** Wraps the current line. Searches to the left of the cursor to
+ break the line. Does nothing if the cursor position is before
+ the break position parameter.
+ @param column the break position for the line, maximum length
+ @return true if line got broken
+ */
+ bool WrapLine(CoordType column);
+ /** This function deletes npos cursor positions.
+ @param npos how many positions
+ @return true if everything got deleted
+ */
+ bool Delete(CoordType npos);
+
+ /** Delete the next n lines.
+ @param n how many lines to delete
+ @return how many it could not delete
+ */
+ int DeleteLines(int n);
+
+ /// Delete to end of line.
+ void DeleteToEndOfLine(void)
+ {
+ wxASSERT(m_CursorLine);
+ Delete(m_CursorLine->GetLength()-m_CursorPos.x);
+ }
+ /// Delete to begin of line.
+ void DeleteToBeginOfLine(void)
+ {
+ wxASSERT(m_CursorLine);
+ CoordType n = m_CursorPos.x;
+#ifdef WXLAYOUT_DEBUG
+ wxASSERT(MoveCursorHorizontally(-n));
+#else
+ MoveCursorHorizontally(-n);
+#endif
+ Delete(n);
+ }
+
+ /** Delete the next word.
+ */
+ void DeleteWord(void)
+ {
+ wxASSERT(m_CursorLine);
+ m_CursorLine->DeleteWord(m_CursorPos.x);
+ }
+
+ //@}
+
+ /** Finds text in this list.
+ @param needle the text to find
+ @param cpos the position where to start the search
+ @return the cursoor coord where it was found or (-1,-1)
+ */
+ wxPoint FindText(const wxString &needle, const wxPoint &cpos = wxPoint(0,0)) const;
+
+ /**@name Formatting options */
+ //@{
+ /// sets font parameters
void SetFont(int family, int size, int style,
int weight, int underline,
- wxColour const *fg,
- wxColour const *bg);
+ wxColour *fg,
+ wxColour *bg);
+ /// sets font parameters, colours by name
void SetFont(int family=-1, int size = -1, int style=-1,
int weight=-1, int underline = -1,
char const *fg = NULL,
char const *bg = NULL);
+ /// changes to the next larger font size
+ inline void SetFontLarger(void)
+ { SetFont(-1,(12*m_CurrentSetting.size)/10); }
+ /// changes to the next smaller font size
+ inline void SetFontSmaller(void)
+ { SetFont(-1,(10*m_CurrentSetting.size)/12); }
+
+ /// set font family
inline void SetFontFamily(int family) { SetFont(family); }
+ /// set font size
inline void SetFontSize(int size) { SetFont(-1,size); }
+ /// set font style
inline void SetFontStyle(int style) { SetFont(-1,-1,style); }
+ /// set font weight
inline void SetFontWeight(int weight) { SetFont(-1,-1,-1,weight); }
+ /// toggle underline flag
inline void SetFontUnderline(bool ul) { SetFont(-1,-1,-1,-1,(int)ul); }
- inline void SetFontColour(char const *fg, char const *bg = NULL) { SetFont(-1,-1,-1,-1,-1,fg,bg); }
-
-
- /** Draw the list on a given DC.
- @param findObject if true, return the object occupying the
- position specified by coords
- @param coords position where to find the object
- @pageNo if > 0, print only that page of a document (for
- printing)
- @reallyDraw set this to false if you don't want to draw but just calculate the coordinates
- @return if findObject == true, the object or NULL
- */
- wxLayoutObjectBase *Draw(wxDC &dc, bool findObject = false,
- wxPoint const &coords = wxPoint(0,0),
- int pageNo = -1, bool reallyDraw = true);
+ /// set font colours by name
+ inline void SetFontColour(char const *fg, char const *bg = NULL)
+ { SetFont(-1,-1,-1,-1,-1,fg,bg); }
+ /// set font colours by colour
+ inline void SetFontColour(wxColour *fg, wxColour *bg = NULL)
+ { SetFont(-1,-1,-1,-1,-1,fg,bg); }
-#ifdef WXLAYOUT_DEBUG
- void Debug(void);
- void ShowCurrentObject();
-#endif
+ /**
+ Returns a pointer to the default settings.
+ This is only valid temporarily and should not be stored
+ anywhere.
+ @return the default settings of the list
+ */
+ wxLayoutStyleInfo *GetDefaults(void) { return &m_DefaultSetting ; }
+ wxLayoutStyleInfo *GetStyleInfo(void) { return &m_CurrentSetting ; }
+ //@}
+
+ /**@name Drawing */
+ //@{
+ /** Draws the complete list on a wxDC.
+ @param dc the wxDC to draw on
+ @param offset an optional offset to shift printout
+ @param top optional y coordinate where to start drawing
+ @param bottom optional y coordinate where to stop drawing
+ */
+ void Draw(wxDC &dc,
+ const wxPoint &offset = wxPoint(0,0),
+ CoordType top = -1, CoordType bottom = -1);
+
+ /** Calculates new layout for the list, like Draw() but does not
+ actually draw it.
+ @param dc the wxDC to draw on
+ @param bottom optional y coordinate where to stop calculating
+ @param forceAll force re-layout of all lines
+ */
+ void Layout(wxDC &dc, CoordType bottom = -1, bool forceAll = false);
+
+ /** Calculates new sizes for everything in the list, like Layout()
+ but this is needed after the list got changed.
+ @param dc the wxDC to draw on
+ @param bottom optional y coordinate where to stop calculating
+ */
+ void Recalculate(wxDC &dc, CoordType bottom = -1);
- /// for access by wxLayoutWindow:
- void GetSize(CoordType *max_x, CoordType *max_y,
- CoordType *lineHeight);
+ /** Returns the size of the list in screen coordinates.
+ The return value only makes sense after the list has been
+ drawn.
+ @return a wxPoint holding the maximal x/y coordinates used for
+ drawing
+ */
+ wxPoint GetSize(void) const;
+ /** Returns the cursor position on the screen.
+ @return cursor position in pixels
+ */
+ wxPoint GetCursorScreenPos(wxDC &dc);
- /**@name Functionality for editing */
+ /** Draws the cursor.
+ @param active If true, draw a bold cursor to mark window as
+ active.
+ @param translate optional translation of cursor coords on screen
+ */
+ void DrawCursor(wxDC &dc,
+ bool active = true,
+ const wxPoint & translate = wxPoint(0,0));
+
+ /** This function finds an object belonging to a given screen
+ position. It assumes that Layout() has been called before.
+ @param pos screen position
+ @param cursorPos if non NULL, store cursor position in there
+ @param found if used, set this to true if we really found an
+ object, to false if we had to take the object near to it
+ @return pointer to the object
+ */
+ wxLayoutObject * FindObjectScreen(wxDC &dc,
+ wxPoint const pos,
+ wxPoint *cursorPos = NULL,
+ bool *found = NULL);
+
+ /** Called by the objects to update the update rectangle.
+ @param x horizontal coordinate to include in rectangle
+ @param y vertical coordinate to include in rectangle
+ */
+ void SetUpdateRect(CoordType x, CoordType y);
+ /** Called by the objects to update the update rectangle.
+ @param p a point to include in it
+ */
+ inline void SetUpdateRect(const wxPoint &p)
+ { SetUpdateRect(p.x,p.y); }
+ /// Invalidates the update rectangle.
+ void InvalidateUpdateRect(void) { m_UpdateRectValid = false; }
+ /// Returns the update rectangle.
+ const wxRect *GetUpdateRect(void) const { return &m_UpdateRect; }
+ //@}
+
+ /**@name For exporting one object after another. */
//@{
- /// set list editable or read only
- void SetEditable(bool editable = true) { m_Editable = editable; }
- /// return true if list is editable
- bool IsEditable(void) const { return m_Editable; }
- /// move cursor, returns true if it could move to the desired position
- bool MoveCursor(int dx = 0, int dy = 0);
- void SetCursor(wxPoint const &p) { m_CursorPosition = p; }
- wxPoint GetCursor(void) const { return m_CursorPosition; }
- /// delete one or more cursor positions
- void Delete(CoordType count = 1);
- void Insert(String const &text);
- void Insert(wxLayoutObjectBase *obj);
- void Clear(int family = wxROMAN, int size=12, int style=wxNORMAL, int weight=wxNORMAL,
- int underline=0, char const *fg="black", char const *bg="white");
-
- /// return a pointer to the default settings:
- wxLayoutObjectCmd const *GetDefaults(void) const { return m_DefaultSetting ; }
-
- wxLayoutObjectList::iterator FindCurrentObject(CoordType *offset = NULL);
- // get the length of the line with the object pointed to by i, offs
- // only used to decide whether we are before or after linebreak
- CoordType GetLineLength(wxLayoutObjectList::iterator i,
- CoordType offs = 0);
- wxLayoutPrintout *MakePrintout(wxString const &name);
-
-//@}
-protected:
- /// font parameters:
- int m_FontFamily, m_FontStyle, m_FontWeight;
- int m_FontPtSize;
- bool m_FontUnderline;
- /// colours:
- wxColour const * m_ColourFG;
- wxColour const * m_ColourBG;
- /// the default setting:
- wxLayoutObjectCmd *m_DefaultSetting;
+ /** Returns a pointer to the first line in the list. */
+ wxLayoutLine *GetFirstLine(void)
+ {
+ wxASSERT(m_FirstLine);
+ return m_FirstLine;
+ }
+ //@}
+
+ /// Begin selecting text.
+ void StartSelection(void);
+ // Continue selecting text
+ void ContinueSelection(void);
+ /// End selecting text.
+ void EndSelection(void);
+ /// Are we still selecting text?
+ bool IsSelecting(void);
+ bool IsSelected(const wxPoint &cursor);
+
+ /// Return the selection as a wxLayoutList:
+ wxLayoutList *GetSelection(void);
+ /// Delete selected bit
+ void DeleteSelection(void);
+
+ wxLayoutList *Copy(const wxPoint &from = wxPoint(0,0),
+ const wxPoint &to = wxPoint(-1,-1));
- /// needs recalculation?
- bool m_dirty;
+ /// starts highlighting of text for selections
+ void StartHighlighting(wxDC &dc);
+ /// ends highlighting of text for selections
+ void EndHighlighting(wxDC &dc);
+
+ /** Tests whether this layout line is selected and needs
+ highlighting.
+ @param line to test for
+ @param from set to first cursorpos to be highlighted (for returncode == -1)
+ @param to set to last cursorpos to be highlighted (for returncode == -1)
+ @return 0 = not selected, 1 = fully selected, -1 = partially
+ selected
+
+ */
+ int IsSelected(const wxLayoutLine *line, CoordType *from, CoordType *to);
- // the currently updated line:
- /// where do we draw next:
- wxPoint m_Position;
- /// the height of the current line:
- CoordType m_LineHeight;
- /// maximum drawn x position so far
- CoordType m_MaxX;
- /// maximum drawn y position:
- CoordType m_MaxY;
-
- //---- this is needed for editing:
- /// where is the text cursor:
- wxPoint m_CursorPosition;
- /// which is the last line
- CoordType m_MaxLine;
- /// can we edit it?
- bool m_Editable;
- /// find the object to the cursor position and returns the offset
- /// in there
- wxLayoutObjectList::iterator FindObjectCursor(wxPoint *cpos, CoordType *offset = NULL);
+ void ApplyStyle(wxLayoutStyleInfo *si, wxDC &dc);
+#ifdef WXLAYOUT_DEBUG
+ void Debug(void);
+#endif
+private:
+ /// Clear the list.
+ void InternalClear(void);
+ /** Calculates the cursor position on the screen.
+ */
+ void UpdateCursorScreenPos(wxDC &dc);
+ /// The list of lines.
+ wxLayoutLine *m_FirstLine;
+ /// The update rectangle which needs to be refreshed:
+ wxRect m_UpdateRect;
+ /// Is the update rectangle valid?
+ bool m_UpdateRectValid;
+ /**@name Cursor Management */
+ //@{
+ /// Where the text cursor (column,line) is.
+ wxPoint m_CursorPos;
+ /// The size of the cursor.
+ wxPoint m_CursorSize;
+ /// Where the cursor should be drawn.
+ wxPoint m_CursorScreenPos;
+ /// The line where the cursor is.
+ wxLayoutLine *m_CursorLine;
+ //@}
+
+ /// A structure for the selection.
+ struct Selection
+ {
+ Selection() { m_valid = false; m_selecting = false; }
+ bool m_valid;
+ bool m_selecting;
+ wxPoint m_CursorA, m_CursorB;
+ } m_Selection;
+ /** @name Font parameters. */
+ //@{
+ /// this object manages the fonts for us
+ wxFontCache m_FontCache;
+ /// the default setting:
+ wxLayoutStyleInfo m_DefaultSetting;
+ /// the current setting:
+ wxLayoutStyleInfo m_CurrentSetting;
+ //@}
};
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ The wxLayoutPrintout object for printing within the wxWindows print
+ framework.
+
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/** This class implements a wxPrintout for printing a wxLayoutList within
+ the wxWindows printing framework.
+ */
class wxLayoutPrintout: public wxPrintout
{
- public:
- wxLayoutPrintout(wxLayoutList &llist, wxString const & title = "My printout"):wxPrintout(title)
- { m_llist = &llist; m_maxPage = 0; }
- bool OnPrintPage(int page);
- bool HasPage(int page);
- bool OnBeginDocument(int startPage, int endPage);
- void GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int
- *selPageTo);
+public:
+ /** Constructor.
+ @param llist pointer to the wxLayoutList to be printed
+ @param title title for PS file or windows
+ */
+ wxLayoutPrintout(wxLayoutList *llist,
+ wxString const & title =
+ "wxLayout Printout");
+ /// Destructor.
+ ~wxLayoutPrintout();
+
+ /** Function which prints the n-th page.
+ @param page the page number to print
+ @return bool true if we are not at end of document yet
+ */
+ bool OnPrintPage(int page);
+ /** Checks whether page exists in document.
+ @param page number of page
+ @return true if page exists
+ */
+ bool HasPage(int page);
+
+ /** Gets called from wxWindows to find out which pages are existing.
+ I'm not totally sure about the parameters though.
+ @param minPage the first page in the document
+ @param maxPage the last page in the document
+ @param selPageFrom the first page to be printed
+ @param selPageTo the last page to be printed
+ */
+ void GetPageInfo(int *minPage, int *maxPage,
+ int *selPageFrom, int *selPageTo);
+protected:
+ /** This little function scales the DC so that the printout has
+ roughly the same size as the output on screen.
+ @param dc the wxDC to scale
+ @return the scale that was applied
+ */
+ float ScaleDC(wxDC *dc);
+
+ /* no longer used
+ virtual void DrawHeader(wxDC &dc, wxPoint topleft, wxPoint bottomright, int pageno);
+ */
private:
+ /// The list to print.
wxLayoutList *m_llist;
- int m_maxPage;
+ /// Title for PS file or window.
+ wxString m_title;
+ /// The real paper size.
+ int m_PageHeight, m_PageWidth;
+ /// How much we actually print per page.
+ int m_PrintoutHeight;
+ /// How many pages we need to print.
+ int m_NumOfPages;
+ /// Top left corner where we start printing.
+ wxPoint m_Offset;
};
+
#endif // WXLLIST_H