1 /*-*- c++ -*-********************************************************
2 * wxFTCanvas: a canvas for editing formatted text *
4 * (C) 1998 by Karsten Ballüder (Ballueder@usa.net) *
7 *******************************************************************/
10 - each Object knows its size and how to draw itself
11 - the list is responsible for calculating positions
12 - the draw coordinates for each object are the top left corner
13 - coordinates only get calculated when things get redrawn
14 - during redraw each line gets iterated over twice, first just
15 calculating baselines and positions, second to actually draw it
16 - the cursor position is the position before an object, i.e. if the
17 buffer starts with a text-object, cursor 0,0 is just before the
22 #pragma implementation "wxllist.h"
25 // these two lines are for use in M:
27 //#include "gui/wxllist.h"
32 # include "iostream.h"
35 # include <wx/postscrp.h>
36 # include <wx/print.h>
40 #define BASELINESTRETCH 12
43 static const char *g_aTypeStrings
[] =
45 "invalid", "text", "cmd", "icon", "linebreak"
48 # define wxLayoutDebug wxLogDebug
49 # define WXL_VAR(x) cerr << #x " = " << x ;
50 # define WXL_DBG_POINT(p) wxLogDebug(#p ": (%d, %d)", p.x, p.y)
51 # define WXL_TRACE(f) wxLogDebug(#f ": ")
52 # define TypeString(t) g_aTypeStrings[t]
55 wxLayoutObjectBase::Debug(void)
58 wxLogDebug("%s: size = %dx%d, bl = %d",
59 TypeString(GetType()), GetSize(&bl
).x
, GetSize(&bl
).y
, bl
);
64 # define WXL_DBG_POINT(p)
66 # define ShowCurrentObject()
67 # define TypeString(t) ""
68 inline void wxLayoutDebug(const char *, ...) { }
72 //-------------------------- wxLayoutObjectText
74 wxLayoutObjectText::wxLayoutObjectText(const String
&txt
)
83 wxLayoutObjectText::GetSize(CoordType
*baseLine
) const
85 if(baseLine
) *baseLine
= m_BaseLine
;
86 return wxPoint(m_Width
, m_Height
);
90 wxLayoutObjectText::Draw(wxDC
&dc
, wxPoint position
, CoordType baseLine
,
94 dc
.GetTextExtent(Str(m_Text
),&m_Width
, &m_Height
, &descent
);
95 //FIXME: wxGTK does not set descent to a descent value yet.
97 descent
= (2*m_Height
)/10; // crude fix
98 m_BaseLine
= m_Height
- descent
;
99 position
.y
+= baseLine
-m_BaseLine
;
101 dc
.DrawText(Str(m_Text
),position
.x
,position
.y
);
102 // Don't remove this, important help for debugging layout.
103 # ifdef WXLAYOUT_DEBUG
104 // dc.DrawRectangle(position.x, position.y, m_Width, m_Height);
108 #ifdef WXLAYOUT_DEBUG
110 wxLayoutObjectText::Debug(void)
112 wxLayoutObjectBase::Debug();
113 wxLogDebug(" `%s`", m_Text
.c_str());
117 //-------------------------- wxLayoutObjectIcon
119 wxLayoutObjectIcon::wxLayoutObjectIcon(wxIcon
*icon
)
125 wxLayoutObjectIcon::Draw(wxDC
&dc
, wxPoint position
, CoordType baseLine
,
128 position
.y
+= baseLine
- m_Icon
->GetHeight();
130 dc
.DrawIcon(m_Icon
,position
.x
,position
.y
);
134 wxLayoutObjectIcon::GetSize(CoordType
*baseLine
) const
137 *baseLine
= m_Icon
->GetHeight();
138 return wxPoint(m_Icon
->GetWidth(), m_Icon
->GetHeight());
141 //-------------------------- wxLayoutObjectCmd
144 wxLayoutObjectCmd::wxLayoutObjectCmd(int size
, int family
, int style
, int
145 weight
, bool underline
,
146 wxColour
const *fg
, wxColour
const *bg
)
149 m_font
= new wxFont(size
,family
,style
,weight
,underline
);
154 wxLayoutObjectCmd::~wxLayoutObjectCmd()
160 wxLayoutObjectCmd::GetStyle(void) const
162 wxLayoutStyleInfo
*si
= new wxLayoutStyleInfo();
165 si
->size
= m_font
->GetPointSize();
166 si
->family
= m_font
->GetFamily();
167 si
->style
= m_font
->GetStyle();
168 si
->underline
= m_font
->GetUnderlined();
169 si
->weight
= m_font
->GetWeight();
171 si
->fg_red
= m_ColourFG
->Red();
172 si
->fg_green
= m_ColourFG
->Green();
173 si
->fg_blue
= m_ColourFG
->Blue();
174 si
->bg_red
= m_ColourBG
->Red();
175 si
->bg_green
= m_ColourBG
->Green();
176 si
->bg_blue
= m_ColourBG
->Blue();
182 wxLayoutObjectCmd::Draw(wxDC
&dc
, wxPoint position
, CoordType lineHeight
,
186 // this get called even when draw==false, so that recalculation
187 // uses right font sizes
190 dc
.SetTextForeground(*m_ColourFG
);
192 dc
.SetTextBackground(*m_ColourBG
);
195 //-------------------------- wxwxLayoutList
197 wxLayoutList::wxLayoutList()
199 m_DefaultSetting
= NULL
;
203 wxLayoutList::~wxLayoutList()
206 delete m_DefaultSetting
;
207 // no deletion of objects, they are owned by the list
211 wxLayoutList::LineBreak(void)
213 Insert(new wxLayoutObjectLineBreak
);
214 m_CursorPosition
.x
= 0; m_CursorPosition
.y
++;
218 wxLayoutList::SetFont(int family
, int size
, int style
, int weight
,
219 int underline
, wxColour
const *fg
,
222 if(family
!= -1) m_FontFamily
= family
;
223 if(size
!= -1) m_FontPtSize
= size
;
224 if(style
!= -1) m_FontStyle
= style
;
225 if(weight
!= -1) m_FontWeight
= weight
;
226 if(underline
!= -1) m_FontUnderline
= underline
!= 0;
228 if(fg
!= NULL
) m_ColourFG
= fg
;
229 if(bg
!= NULL
) m_ColourBG
= bg
;
232 new wxLayoutObjectCmd(m_FontPtSize
,m_FontFamily
,m_FontStyle
,m_FontWeight
,m_FontUnderline
,
233 m_ColourFG
, m_ColourBG
));
237 wxLayoutList::SetFont(int family
, int size
, int style
, int weight
,
238 int underline
, char const *fg
, char const *bg
)
246 cfg
= wxTheColourDatabase
->FindColour(fg
);
248 cbg
= wxTheColourDatabase
->FindColour(bg
);
250 SetFont(family
,size
,style
,weight
,underline
,cfg
,cbg
);
254 /// for access by wxLayoutWindow:
256 wxLayoutList::GetSize(CoordType
*max_x
, CoordType
*max_y
,
257 CoordType
*lineHeight
)
260 if(max_x
) *max_x
= m_MaxX
;
261 if(max_y
) *max_y
= m_MaxY
;
262 if(lineHeight
) *lineHeight
= m_LineHeight
;
266 wxLayoutList::Draw(wxDC
&dc
, bool findObject
, wxPoint
const
267 &findCoords
, int pageNo
, bool reallyDraw
)
269 wxLayoutObjectList::iterator i
;
271 // in case we need to look for an object
272 wxLayoutObjectBase
*foundObject
= NULL
;
274 // first object in current line
275 wxLayoutObjectList::iterator headOfLine
;
277 // do we need to recalculate current line?
278 bool recalculate
= false;
280 // do we calculate or draw? Either true or false.
282 // drawing parameters:
283 wxPoint position
= wxPoint(0,0);
284 wxPoint position_HeadOfLine
;
285 CoordType baseLine
= m_FontPtSize
;
286 CoordType baseLineSkip
= (BASELINESTRETCH
* baseLine
)/10;
288 // where to draw the cursor
290 cursorPosition
= wxPoint(0,0),
291 cursorSize
= wxPoint(1,baseLineSkip
);
293 // the cursor position inside the object
294 CoordType cursorOffset
= 0;
295 // object under cursor
296 wxLayoutObjectList::iterator cursorObject
= FindCurrentObject(&cursorOffset
);
298 // queried from each object:
299 wxPoint size
= wxPoint(0,0);
300 CoordType objBaseLine
= baseLine
;
301 wxLayoutObjectType type
;
304 wxLayoutObjectText
*tobj
= NULL
;
307 // this is needed for printing to a printer:
308 // only interesting for printer/PS output
309 int pageWidth
, pageHeight
; //GetSize() still needs int at the moment
312 int top
, bottom
, left
, right
;
319 dc
.GetSize(&pageWidth
, &pageHeight
);
321 margins
.top
= 0; //(1*pageHeight)/10; // 10%
322 margins
.bottom
= pageHeight
;// (9*pageHeight)/10; // 90%
323 margins
.left
= 0; //(1*pageWidth)/10;
324 margins
.right
= pageWidth
; //(9*pageWidth)/10;
328 margins
.top
= 0; margins
.left
= 0;
332 position
.y
= margins
.top
;
333 position
.x
= margins
.left
;
335 // if the cursorobject is a cmd, we need to find the first
337 while(cursorObject
!= end()
338 && (*cursorObject
)->GetType() == WXLO_TYPE_CMD
)
341 headOfLine
= begin();
342 position_HeadOfLine
= position
;
344 // setting up the default:
345 dc
.SetTextForeground( *wxBLACK
);
346 dc
.SetTextBackground( *wxWHITE
);
347 dc
.SetBackgroundMode( wxSOLID
); // to enable setting of text background
348 dc
.SetFont( *wxNORMAL_FONT
);
351 //FIXME: who frees the brush, how long does it need to exist?
353 m_DefaultSetting
->Draw(dc
,wxPoint(0,0),0,true);
355 // we calculate everything for drawing a line, then rewind to the
356 // begin of line and actually draw it
364 type
= (*i
)->GetType();
366 // to initialise sizes of objects, we need to call Draw
367 if(draw
&& (pageNo
== -1 || pageNo
== currentPage
))
369 (*i
)->Draw(dc
, position
, baseLine
, draw
);
370 #ifdef WXLAYOUT_DEBUG
372 wxLogDebug("first position = (%d,%d)",(int) position
.x
, (int)position
.y
);
375 // update coordinates for next object:
376 size
= (*i
)->GetSize(&objBaseLine
);
377 if(findObject
&& draw
) // we need to look for an object
379 if(findCoords
.y
>= position
.y
380 && findCoords
.y
<= position
.y
+size
.y
381 && findCoords
.x
>= position
.x
382 && findCoords
.x
<= position
.x
+size
.x
)
385 findObject
= false; // speeds things up
389 if(m_Editable
&& draw
&& i
== cursorObject
)
391 WXL_VAR((**cursorObject
).GetType());
392 WXL_VAR(m_CursorPosition
.x
); WXL_VAR(m_CursorPosition
.y
);
393 if(type
== WXLO_TYPE_TEXT
) // special treatment
395 long descent
= 0l; long width
, height
;
396 tobj
= (wxLayoutObjectText
*)*i
;
397 String str
= tobj
->GetText();
398 WXL_VAR(m_CursorPosition
.x
);
399 str
= str
.substr(0, cursorOffset
);
400 dc
.GetTextExtent(Str(str
), &width
,&height
, &descent
);
401 cursorPosition
= wxPoint(position
.x
+width
,
402 position
.y
+(baseLineSkip
-height
));
403 cursorSize
= wxPoint(1, height
);
405 else if(type
== WXLO_TYPE_LINEBREAK
)
407 WXL_VAR(cursorOffset
);
409 cursorPosition
= wxPoint(0, position
.y
+baseLineSkip
);
411 cursorPosition
= wxPoint(0, position
.y
);
412 cursorSize
= wxPoint(1,baseLineSkip
);
417 // this is not necessarily the most "beautiful" solution:
418 //cursorPosition = wxPoint(position.x, position.y);
419 //cursorSize = wxPoint(size.x > 0 ? size.x : 1,size.y > 0 ? size.y : baseLineSkip);
420 cursorPosition
= wxPoint(position
.x
+size
.x
, position
.y
+(size
.y
-baseLineSkip
));
421 cursorSize
= wxPoint(1, baseLineSkip
);
425 // calculate next object's position:
426 position
.x
+= size
.x
;
427 if(position
.x
> m_MaxX
)
430 // do we need to increase the line's height?
431 if(size
.y
> baseLineSkip
)
433 baseLineSkip
= size
.y
;
436 if(objBaseLine
> baseLine
)
438 baseLine
= objBaseLine
;
442 // now check whether we have finished handling this line:
443 if(type
== WXLO_TYPE_LINEBREAK
|| i
== tail())
445 if(recalculate
) // do this line again
447 position
.x
= position_HeadOfLine
.x
;
452 if(! draw
) // finished calculating sizes
454 // if the this line needs to go onto a new page, we need
455 // to change pages before drawing it:
456 if(pageNo
> 0 && position
.y
> margins
.bottom
)
459 position_HeadOfLine
.y
= margins
.top
;
461 if(reallyDraw
&& (pageNo
== -1 || pageNo
== currentPage
))
463 // do this line again, this time drawing it
464 position
= position_HeadOfLine
;
470 else // we have drawn a line, so continue calculating next one
474 // is it a linebreak?
475 if(type
== WXLO_TYPE_LINEBREAK
|| i
== tail())
477 position
.x
= margins
.left
;
478 position
.y
+= baseLineSkip
;
479 baseLine
= m_FontPtSize
;
480 objBaseLine
= baseLine
; // not all objects set it
481 baseLineSkip
= (BASELINESTRETCH
* baseLine
)/10;
484 position_HeadOfLine
= position
;
491 dc
.DrawRectangle(cursorPosition
.x
, cursorPosition
.y
,
492 cursorSize
.x
, cursorSize
.y
);
498 #ifdef WXLAYOUT_DEBUG
500 wxLayoutList::Debug(void)
503 wxLayoutObjectList::iterator i
;
505 wxLogDebug("------------------------debug start-------------------------");
506 for(i
= begin(); i
!= end(); i
++)
508 wxLogDebug("-----------------------debug end----------------------------");
510 // show current object:
512 i
= FindCurrentObject(&offs
);
513 wxLogDebug(" line length: %l", (long int) GetLineLength(i
,offs
));
516 wxLogDebug("<<no object found>>");
517 return; // FIXME we should set cursor position to maximum allowed
520 if((*i
)->GetType() == WXLO_TYPE_TEXT
)
521 wxLogDebug(" \"%s\", offs=%d",((wxLayoutObjectText
*)(*i
))->GetText().c_str(), (int) offs
);
523 wxLogDebug(g_aTypeStrings
[(*i
)->GetType()]);
528 wxLayoutList::ShowCurrentObject()
531 wxLayoutObjectList::iterator i
= FindCurrentObject(&offs
);
533 wxLayoutDebug("Cursor is at (%d, %d)",
534 m_CursorPosition
.x
, m_CursorPosition
.y
);
536 i
= FindCurrentObject(&offs
);
537 wxLogDebug(" Line length: %d", GetLineLength(i
));
541 wxLogDebug("<<no object found>>");
542 return; // FIXME we should set cursor position to maximum allowed
545 if((*i
)->GetType() == WXLO_TYPE_TEXT
)
546 wxLogDebug(" \"%s\", offs: %d",
547 ((wxLayoutObjectText
*)(*i
))->GetText().c_str(), offs
);
549 wxLogDebug(" %s", TypeString((*i
)->GetType()));
554 /******************** editing stuff ********************/
556 // don't change this, I know how to optimise this and will do it real
561 * Finds the object belonging to a given cursor position cpos and
562 * returns an iterator to that object and stores the relative cursor
563 * position in offset.
565 * For linebreaks, the offset can be 0=before or 1=after.
567 * If the cpos coordinates don't exist, they are modified.
570 wxLayoutObjectList::iterator
571 wxLayoutList::FindObjectCursor(wxPoint
*cpos
, CoordType
*offset
)
573 wxPoint object
= wxPoint(0,0); // runs along the objects
575 wxLayoutObjectList::iterator i
;
577 #ifdef WXLAYOUT_DEBUG
578 wxLayoutDebug("Looking for object at (%d, %d)", cpos
->x
, cpos
->y
);
580 for(i
= begin(); i
!= end() && object
.y
<= cpos
->y
; i
++)
582 width
= (**i
).CountPositions();
583 if(cpos
->y
== object
.y
) // a possible candidate
585 if((**i
).GetType() ==WXLO_TYPE_LINEBREAK
)
587 if(cpos
->x
== object
.x
)
589 if(offset
) *offset
= 0;
592 if(offset
) *offset
=1;
596 if(cpos
->x
>= object
.x
&& cpos
->x
<= object
.x
+width
) // overlap
598 if(offset
) *offset
= cpos
->x
-object
.x
;
599 #ifdef WXLAYOUT_DEBUG
600 wxLayoutDebug(" found object at (%d, %d), type: %s",
601 object
.x
, object
.y
, TypeString((*i
)->GetType()));
606 // no overlap, increment coordinates
608 if((**i
).GetType() == WXLO_TYPE_LINEBREAK
)
614 #ifdef WXLAYOUT_DEBUG
615 wxLayoutDebug(" not found");
617 // return last object, coordinates of that one:
621 if((**i
).GetType()==WXLO_TYPE_LINEBREAK
)
627 cpos
->x
= object
.x
; // would be the coordinate of next object
629 cpos
->x
+= width
; // last object's width
630 if(*offset
) *offset
= cpos
->x
-object
.x
;
631 return i
; // not found
634 wxLayoutObjectList::iterator
635 wxLayoutList::FindCurrentObject(CoordType
*offset
)
637 wxLayoutObjectList::iterator obj
= end();
639 obj
= FindObjectCursor(&m_CursorPosition
, offset
);
640 if(obj
== end()) // not ideal yet
643 if(obj
!= end()) // tail really exists
644 *offset
= (*obj
)->CountPositions(); // at the end of it
650 wxLayoutList::MoveCursor(int dx
, int dy
)
652 CoordType offs
, lineLength
;
653 wxLayoutObjectList::iterator i
;
655 bool rc
= true; // have we moved?
657 if(dy
> 0 && m_CursorPosition
.y
< m_MaxLine
)
658 m_CursorPosition
.y
+= dy
;
659 else if(dy
< 0 && m_CursorPosition
.y
> 0)
660 m_CursorPosition
.y
+= dy
; // dy is negative
661 if(m_CursorPosition
.y
< 0)
663 m_CursorPosition
.y
= 0;
666 else if (m_CursorPosition
.y
> m_MaxLine
)
668 m_CursorPosition
.y
= m_MaxLine
;
674 i
= FindCurrentObject(&offs
);
675 lineLength
= GetLineLength(i
,offs
);
676 if(m_CursorPosition
.x
< lineLength
)
678 m_CursorPosition
.x
++;
684 if(m_CursorPosition
.y
< m_MaxLine
)
686 m_CursorPosition
.y
++;
687 m_CursorPosition
.x
= 0;
693 break; // cannot move there
699 if(m_CursorPosition
.x
> 0)
701 m_CursorPosition
.x
--;
706 if(m_CursorPosition
.y
> 0)
708 m_CursorPosition
.y
--;
709 m_CursorPosition
.x
= 0;
710 i
= FindCurrentObject(&offs
);
711 lineLength
= GetLineLength(i
,offs
);
712 m_CursorPosition
.x
= lineLength
;
719 break; // cannot move left any more
724 i
= FindCurrentObject(&offs
);
725 lineLength
= GetLineLength(i
,offs
);
726 if(m_CursorPosition
.x
> lineLength
)
728 m_CursorPosition
.x
= lineLength
;
731 #ifdef WXLAYOUT_DEBUG
738 wxLayoutList::Delete(CoordType count
)
748 wxLayoutObjectList::iterator i
;
752 i
= FindCurrentObject(&offs
);
753 startover
: // ugly, but easiest way to do it
755 return; // we cannot delete anything more
757 /* Here we need to treat linebreaks differently.
758 If offs==0 we are before the linebreak, otherwise behind. */
759 if((*i
)->GetType() == WXLO_TYPE_LINEBREAK
)
766 continue; // we're done
768 else // delete the object behind the linebreak
770 i
++; // we increment and continue as normal
775 else if((*i
)->GetType() == WXLO_TYPE_TEXT
)
777 wxLayoutObjectText
*tobj
= (wxLayoutObjectText
*)*i
;
778 CoordType len
= tobj
->CountPositions();
779 // If we find the end of a text object, this means that we
780 // have to delete from the object following it.
787 else if(len
<= count
) // delete this object
796 tobj
->GetText().erase(offs
,len
);
797 return; // we are done
800 else// all other objects: delete the object
801 // this only works as expected if the non-text object has 0/1
802 // as offset values. Not tested with "longer" objects.
804 CoordType len
= (*i
)->CountPositions();
807 count
= count
> len
? count
-= len
: 0;
808 erase(i
); // after this, i is the iterator for the following object
811 else // delete the following object
813 i
++; // we increment and continue as normal
819 while(count
&& i
!= end());
823 wxLayoutList::Insert(wxLayoutObjectBase
*obj
)
827 wxLayoutObjectList::iterator i
= FindCurrentObject(&offs
);
829 WXL_TRACE(Insert(obj
));
835 // do we have to split a text object?
836 else if((*i
)->GetType() == WXLO_TYPE_TEXT
&& offs
!= (*i
)->CountPositions())
838 wxLayoutObjectText
*tobj
= (wxLayoutObjectText
*) *i
;
839 #ifdef WXLAYOUT_DEBUG
840 wxLayoutDebug("text: %s", tobj
->GetText().c_str());
843 String left
= tobj
->GetText().substr(0,offs
); // get part before cursor
844 WXL_VAR(left
.c_str());
845 tobj
->GetText() = tobj
->GetText().substr(offs
,(*i
)->CountPositions()-offs
); // keeps the right half
846 WXL_VAR(tobj
->GetText().c_str());
848 insert(i
,new wxLayoutObjectText(left
)); // inserts before
852 // all other cases, append after object:
853 wxLayoutObjectList::iterator j
= i
; // we want to apend after this object
861 m_CursorPosition
.x
+= obj
->CountPositions();
862 if(obj
->GetType() == WXLO_TYPE_LINEBREAK
)
867 wxLayoutList::Insert(String
const &text
)
869 wxLayoutObjectText
*tobj
= NULL
;
870 wxLayoutObjectList::iterator j
;
872 WXL_TRACE(Insert(text
));
878 wxLayoutObjectList::iterator i
= FindCurrentObject(&offs
);
882 Insert(new wxLayoutObjectText(text
));
886 switch((**i
).GetType())
889 // insert into an existing text object:
890 WXL_TRACE(inserting into existing object
);
891 tobj
= (wxLayoutObjectText
*)*i
;
893 tobj
->GetText().insert(offs
,text
);
895 case WXLO_TYPE_LINEBREAK
:
898 if(offs
== 0) // try to append to previous object
901 if(j
!= end() && (**j
).GetType() == WXLO_TYPE_TEXT
)
903 tobj
= (wxLayoutObjectText
*)*j
;
904 tobj
->GetText()+=text
;
907 insert(i
,new wxLayoutObjectText(text
));
909 else // cursor after linebreak
912 if(j
!= end() && (**j
).GetType() == WXLO_TYPE_TEXT
)
914 tobj
= (wxLayoutObjectText
*)*j
;
915 tobj
->GetText()=text
+tobj
->GetText();
920 push_back(new wxLayoutObjectText(text
));
922 insert(j
,new wxLayoutObjectText(text
));
929 WXL_TRACE(checking previous object
);
930 if(j
!= end() && (**j
).GetType() == WXLO_TYPE_TEXT
)
932 tobj
= (wxLayoutObjectText
*)*j
;
933 tobj
->GetText()+=text
;
935 else // insert a new text object
937 WXL_TRACE(creating
new object
);
938 Insert(new wxLayoutObjectText(text
)); //FIXME not too optimal, slow
939 return; // position gets incremented in Insert(obj)
943 m_CursorPosition
.x
+= strlen(text
.c_str());
947 wxLayoutList::GetLineLength(wxLayoutObjectList::iterator i
, CoordType offs
)
954 if(offs
== 0 && (**i
).GetType() == WXLO_TYPE_LINEBREAK
)
955 // we are before a linebrak
957 // search backwards for beginning of line:
958 while(i
!= begin() && (*i
)->GetType() != WXLO_TYPE_LINEBREAK
)
960 if((*i
)->GetType() == WXLO_TYPE_LINEBREAK
)
962 // now we can start counting:
963 while(i
!= end() && (*i
)->GetType() != WXLO_TYPE_LINEBREAK
)
965 len
+= (*i
)->CountPositions();
972 wxLayoutList::Clear(int family
, int size
, int style
, int weight
,
973 int underline
, char const *fg
, char const *bg
)
975 wxLayoutObjectList::iterator i
= begin();
977 while(i
!= end()) // == while valid
982 m_FontUnderline
= false;
983 m_FontFamily
= family
;
985 m_FontWeight
= weight
;
986 m_ColourFG
= wxTheColourDatabase
->FindColour(fg
);
987 m_ColourBG
= wxTheColourDatabase
->FindColour(bg
);
989 if(! m_ColourFG
) m_ColourFG
= wxBLACK
;
990 if(! m_ColourBG
) m_ColourBG
= wxWHITE
;
992 m_Position
= wxPoint(0,0);
993 m_CursorPosition
= wxPoint(0,0);
995 m_LineHeight
= (BASELINESTRETCH
*m_FontPtSize
)/10;
996 m_MaxX
= 0; m_MaxY
= 0;
1000 delete m_DefaultSetting
;
1001 m_DefaultSetting
= new
1002 wxLayoutObjectCmd(m_FontPtSize
,m_FontFamily
,m_FontStyle
,
1003 m_FontWeight
,m_FontUnderline
,
1004 m_ColourFG
, m_ColourBG
);
1009 /******************** printing stuff ********************/
1011 bool wxLayoutPrintout::OnPrintPage(int page
)
1016 m_llist
->Draw(*dc
,false,wxPoint(0,0),page
);
1023 bool wxLayoutPrintout::OnBeginDocument(int startPage
, int endPage
)
1025 if (!wxPrintout::OnBeginDocument(startPage
, endPage
))
1031 void wxLayoutPrintout::GetPageInfo(int *minPage
, int *maxPage
, int *selPageFrom
, int *selPageTo
)
1034 // This code doesn't work, because we don't have a DC yet.
1035 // How on earth are we supposed to calculate the number of pages then?
1036 *minPage
= 0; // set this to 0 to disable editing of page numbers
1039 *selPageFrom
= 0; // set this to 0 to hide page number controls
1043 // *maxPage = 32000;
1045 // *selPageFrom = 1;
1050 int pageWidth
, pageHeight
;
1055 dc
->GetSize(&pageWidth
, &pageHeight
);
1056 // don't draw but just recalculate sizes:
1057 m_llist
->Draw(*dc
,false,wxPoint(0,0),-1,false);
1058 m_llist
->GetSize(NULL
,&height
,NULL
);
1061 *maxPage
= height
/pageHeight
+1;
1064 *selPageTo
= *maxPage
;
1065 m_maxPage
= *maxPage
;
1070 bool wxLayoutPrintout::HasPage(int pageNum
)
1072 return pageNum
<= 5; // for testing
1073 // return m_maxPage >= pageNum;
1078 wxLayoutList::MakePrintout(wxString
const &name
)
1080 return new wxLayoutPrintout(*this,name
);