]> git.saurik.com Git - wxWidgets.git/blob - user/wxLayout/wxllist.cpp
implemented correct setting of background colour for text
[wxWidgets.git] / user / wxLayout / wxllist.cpp
1 /*-*- c++ -*-********************************************************
2 * wxFTCanvas: a canvas for editing formatted text *
3 * *
4 * (C) 1998 by Karsten Ballüder (Ballueder@usa.net) *
5 * *
6 * $Id$ *
7 *******************************************************************/
8
9 /*
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
18 first character
19 */
20
21 #ifdef __GNUG__
22 #pragma implementation "wxllist.h"
23 #endif
24
25 #include "wxllist.h"
26 #include "iostream.h"
27
28 #include <wx/dc.h>
29 #include <wx/postscrp.h>
30 #include <wx/print.h>
31
32 #define BASELINESTRETCH 12
33
34 #define VAR(x) cerr << #x"=" << x << endl;
35 #define DBG_POINT(p) cerr << #p << ": " << p.x << ',' << p.y << endl
36 #define TRACE(f) cerr << #f":" << endl;
37
38 #ifdef WXLAYOUT_DEBUG
39 static const char *_t[] = { "invalid", "text", "cmd", "icon",
40 "linebreak"};
41
42 void
43 wxLayoutObjectBase::Debug(void)
44 {
45 CoordType bl = 0;
46 cerr << _t[GetType()] << ": size=" << GetSize(&bl).x << ","
47 << GetSize(&bl).y << " bl=" << bl;
48 }
49 #endif
50
51 //-------------------------- wxLayoutObjectText
52
53 wxLayoutObjectText::wxLayoutObjectText(const String &txt)
54 {
55 m_Text = txt;
56 m_Width = 0;
57 m_Height = 0;
58 }
59
60
61 wxPoint
62 wxLayoutObjectText::GetSize(CoordType *baseLine) const
63 {
64 if(baseLine) *baseLine = m_BaseLine;
65 return wxPoint(m_Width, m_Height);
66 }
67
68 void
69 wxLayoutObjectText::Draw(wxDC &dc, wxPoint position, CoordType baseLine,
70 bool draw)
71 {
72 long descent = 0l;
73 dc.GetTextExtent(Str(m_Text),&m_Width, &m_Height, &descent);
74 //FIXME: wxGTK does not set descent to a descent value yet.
75 if(descent == 0)
76 descent = (2*m_Height)/10; // crude fix
77 m_BaseLine = m_Height - descent;
78 position.y += baseLine-m_BaseLine;
79 if(draw)
80 dc.DrawText(Str(m_Text),position.x,position.y);
81 # ifdef WXLAYOUT_DEBUG
82 // dc.DrawRectangle(position.x, position.y, m_Width, m_Height);
83 # endif
84 }
85
86 #ifdef WXLAYOUT_DEBUG
87 void
88 wxLayoutObjectText::Debug(void)
89 {
90 wxLayoutObjectBase::Debug();
91 cerr << " `" << m_Text << '\'';
92 }
93 #endif
94
95 //-------------------------- wxLayoutObjectIcon
96
97 wxLayoutObjectIcon::wxLayoutObjectIcon(wxIcon *icon)
98 {
99 m_Icon = icon;
100 }
101
102 void
103 wxLayoutObjectIcon::Draw(wxDC &dc, wxPoint position, CoordType baseLine,
104 bool draw)
105 {
106 position.y += baseLine - m_Icon->GetHeight();
107 if(draw)
108 dc.DrawIcon(m_Icon,position.x,position.y);
109 }
110
111 wxPoint
112 wxLayoutObjectIcon::GetSize(CoordType *baseLine) const
113 {
114 wxASSERT(baseLine);
115 *baseLine = m_Icon->GetHeight();
116 return wxPoint(m_Icon->GetWidth(), m_Icon->GetHeight());
117 }
118
119 //-------------------------- wxLayoutObjectCmd
120
121
122 wxLayoutObjectCmd::wxLayoutObjectCmd(int size, int family, int style, int
123 weight, bool underline,
124 wxColour const *fg, wxColour const *bg)
125
126 {
127 m_font = new wxFont(size,family,style,weight,underline);
128 m_ColourFG = fg;
129 m_ColourBG = bg;
130 }
131
132 wxLayoutObjectCmd::~wxLayoutObjectCmd()
133 {
134 delete m_font;
135 }
136
137 wxLayoutStyleInfo *
138 wxLayoutObjectCmd::GetStyle(void) const
139 {
140 wxLayoutStyleInfo *si = new wxLayoutStyleInfo();
141
142
143 si->size = m_font->GetPointSize();
144 si->family = m_font->GetFamily();
145 si->style = m_font->GetStyle();
146 si->underline = m_font->GetUnderlined();
147 si->weight = m_font->GetWeight();
148
149 si->fg_red = m_ColourFG->Red();
150 si->fg_green = m_ColourFG->Green();
151 si->fg_blue = m_ColourFG->Blue();
152 si->bg_red = m_ColourBG->Red();
153 si->bg_green = m_ColourBG->Green();
154 si->bg_blue = m_ColourBG->Blue();
155
156 return si;
157 }
158
159 void
160 wxLayoutObjectCmd::Draw(wxDC &dc, wxPoint position, CoordType lineHeight,
161 bool draw)
162 {
163 wxASSERT(m_font);
164 // this get called even when draw==false, so that recalculation
165 // uses right font sizes
166 dc.SetFont(m_font);
167 if(m_ColourFG)
168 dc.SetTextForeground(*m_ColourFG);
169 if(m_ColourBG)
170 dc.SetTextBackground(*m_ColourBG);
171 }
172
173 //-------------------------- wxwxLayoutList
174
175 wxLayoutList::wxLayoutList()
176 {
177 m_DefaultSetting = NULL;
178 Clear();
179 }
180
181 wxLayoutList::~wxLayoutList()
182 {
183 if(m_DefaultSetting)
184 delete m_DefaultSetting;
185 }
186
187
188 void
189 wxLayoutList::LineBreak(void)
190 {
191 Insert(new wxLayoutObjectLineBreak);
192 m_CursorPosition.x = 0; m_CursorPosition.y++;
193 }
194
195 void
196 wxLayoutList::SetFont(int family, int size, int style, int weight,
197 int underline, wxColour const *fg,
198 wxColour const *bg)
199 {
200 if(family != -1) m_FontFamily = family;
201 if(size != -1) m_FontPtSize = size;
202 if(style != -1) m_FontStyle = style;
203 if(weight != -1) m_FontWeight = weight;
204 if(underline != -1) m_FontUnderline = underline;
205
206 if(fg != NULL) m_ColourFG = fg;
207 if(bg != NULL) m_ColourBG = bg;
208
209 Insert(
210 new wxLayoutObjectCmd(m_FontPtSize,m_FontFamily,m_FontStyle,m_FontWeight,m_FontUnderline,
211 m_ColourFG, m_ColourBG));
212 }
213
214 void
215 wxLayoutList::SetFont(int family, int size, int style, int weight,
216 int underline, char const *fg, char const *bg)
217 {
218 wxColour const
219 * cfg = NULL,
220 * cbg = NULL;
221
222 if( fg )
223 cfg = wxTheColourDatabase->FindColour(fg);
224 if( bg )
225 cbg = wxTheColourDatabase->FindColour(bg);
226
227 SetFont(family,size,style,weight,underline,cfg,cbg);
228 }
229
230
231 /// for access by wxLayoutWindow:
232 void
233 wxLayoutList::GetSize(CoordType *max_x, CoordType *max_y,
234 CoordType *lineHeight)
235 {
236 wxASSERT(max_x); wxASSERT(max_y); wxASSERT(lineHeight);
237 *max_x = m_MaxX;
238 *max_y = m_MaxY;
239 *lineHeight = m_LineHeight;
240 }
241
242 wxLayoutObjectBase *
243 wxLayoutList::Draw(wxDC &dc, bool findObject, wxPoint const &findCoords)
244 {
245 wxLayoutObjectList::iterator i;
246
247 // in case we need to look for an object
248 wxLayoutObjectBase *foundObject = NULL;
249
250 // first object in current line
251 wxLayoutObjectList::iterator headOfLine;
252
253 // do we need to recalculate current line?
254 bool recalculate = false;
255
256 // do we calculate or draw? Either true or false.
257 bool draw = false;
258 // drawing parameters:
259 wxPoint position = wxPoint(0,0);
260 wxPoint position_HeadOfLine;
261 CoordType baseLine = m_FontPtSize;
262 CoordType baseLineSkip = (BASELINESTRETCH * baseLine)/10;
263
264 // we trace the objects' cursor positions so we can draw the cursor
265 wxPoint cursor = wxPoint(0,0);
266 // the cursor position inside the object
267 CoordType cursorOffset = 0;
268 // object under cursor
269 wxLayoutObjectList::iterator cursorObject = FindCurrentObject(&cursorOffset);
270
271 // queried from each object:
272 wxPoint size = wxPoint(0,0);
273 CoordType objBaseLine = baseLine;
274 wxLayoutObjectType type;
275
276 // used temporarily
277 wxLayoutObjectText *tobj = NULL;
278
279
280 // this is needed for printing to a printer:
281 // only interesting for printer/PS output
282 int pageWidth, pageHeight; //GetSize() still needs int at the moment
283 struct
284 {
285 int top, bottom, left, right;
286 } margins;
287
288 if(
289 #ifdef __WXMSW__
290 dc.IsKindOf(CLASSINFO(wxPrinterDC)) ||
291 #endif
292 dc.IsKindOf(CLASSINFO(wxPostScriptDC)))
293 {
294 VAR(wxThePrintSetupData);
295
296 dc.GetSize(&pageWidth, &pageHeight);
297 dc.StartDoc(_("Printing..."));
298 dc.StartPage();
299 margins.top = (1*pageHeight)/10; // 10%
300 margins.bottom = (9*pageHeight)/10; // 90%
301 margins.left = (1*pageWidth)/10;
302 margins.right = (9*pageWidth)/10;
303 }
304 else
305 {
306 margins.top = 0; margins.left = 0;
307 margins.right = -1;
308 margins.bottom = -1;
309 }
310 position.y = margins.right;
311 position.x = margins.left;
312
313 VAR(findObject); VAR(findCoords.x); VAR(findCoords.y);
314 // if the cursorobject is a cmd, we need to find the first
315 // printable object:
316 while(cursorObject != end()
317 && (*cursorObject)->GetType() == WXLO_TYPE_CMD)
318 cursorObject++;
319
320 headOfLine = begin();
321 position_HeadOfLine = position;
322
323 // setting up the default:
324 dc.SetTextForeground( *wxBLACK );
325 dc.SetTextBackground( *wxWHITE );
326 dc.SetBackgroundMode( wxSOLID ); // to enable setting of text background
327 dc.SetFont( *wxNORMAL_FONT );
328
329
330 //FIXME: who frees the brush, how long does it need to exist?
331 if(m_DefaultSetting)
332 {
333 m_DefaultSetting->Draw(dc,wxPoint(0,0),0,true);
334 dc.SetBackground( wxBrush(* m_DefaultSetting->GetBGColour(),wxSOLID));
335 }
336 else
337 dc.SetBackground( wxBrush(wxColour("White"), wxSOLID) );
338
339 dc.Clear();
340
341
342
343 // we calculate everything for drawing a line, then rewind to the
344 // begin of line and actually draw it
345 i = begin();
346 for(;;)
347 {
348 recalculate = false;
349
350 if(i == end())
351 break;
352 type = (*i)->GetType();
353
354 // to initialise sizes of objects, we need to call Draw
355 (*i)->Draw(dc, position, baseLine, draw);
356
357 // update coordinates for next object:
358 size = (*i)->GetSize(&objBaseLine);
359 if(findObject && draw) // we need to look for an object
360 {
361 if(findCoords.y >= position.y
362 && findCoords.y <= position.y+size.y
363 && findCoords.x >= position.x
364 && findCoords.x <= position.x+size.x)
365 {
366 foundObject = *i;
367 findObject = false; // speeds things up
368 }
369 }
370 // draw the cursor
371 if(m_Editable && draw && i == cursorObject)
372 {
373 if(type == WXLO_TYPE_TEXT) // special treatment
374 {
375 long descent = 0l; long width, height;
376 tobj = (wxLayoutObjectText *)*i;
377 String str = tobj->GetText();
378 VAR(m_CursorPosition.x); VAR(cursor.x);
379 str = str.substr(0, cursorOffset);
380 VAR(str);
381 dc.GetTextExtent(Str(str), &width,&height, &descent);
382 VAR(height);
383 VAR(width); VAR(descent);
384 dc.DrawLine(position.x+width,
385 position.y+(baseLineSkip-height),
386 position.x+width, position.y+baseLineSkip);
387 }
388 else
389 {
390 if(type == WXLO_TYPE_LINEBREAK)
391 dc.DrawLine(0, position.y+baseLineSkip, 0, position.y+2*baseLineSkip);
392 else
393 {
394 if(size.x == 0)
395 {
396 if(size.y == 0)
397 dc.DrawLine(position.x, position.y, position.x, position.y+baseLineSkip);
398 else
399 dc.DrawLine(position.x, position.y, position.x, position.y+size.y);
400 }
401 else
402 dc.DrawRectangle(position.x, position.y, size.x, size.y);
403 }
404 }
405 }
406
407 // calculate next object's position:
408 position.x += size.x;
409
410 // do we need to increase the line's height?
411 if(size.y > baseLineSkip)
412 {
413 baseLineSkip = size.y;
414 recalculate = true;
415 }
416 if(objBaseLine > baseLine)
417 {
418 baseLine = objBaseLine;
419 recalculate = true;
420 }
421
422 // now check whether we have finished handling this line:
423 if(type == WXLO_TYPE_LINEBREAK || i == tail())
424 {
425 if(recalculate) // do this line again
426 {
427 position.x = position_HeadOfLine.x;
428 i = headOfLine;
429 continue;
430 }
431
432 if(! draw) // finished calculating sizes
433 {
434 // if the this line needs to go onto a new page, we need
435 // to change pages before drawing it:
436 if(margins.bottom != -1 && position.y > margins.bottom)
437 {
438 dc.EndPage();
439 position_HeadOfLine.y = margins.top;
440 dc.StartPage();
441 }
442 // do this line again, this time drawing it
443 position = position_HeadOfLine;
444 draw = true;
445 i = headOfLine;
446 continue;
447 }
448 else // we have drawn a line, so continue calculating next one
449 draw = false;
450 }
451
452 if(position.x+size.x > m_MaxX)
453 m_MaxX = position.x+size.x;
454 // is it a linebreak?
455 if(type == WXLO_TYPE_LINEBREAK || i == tail())
456 {
457 position.x = margins.left;
458 position.y += baseLineSkip;
459 baseLine = m_FontPtSize;
460 objBaseLine = baseLine; // not all objects set it
461 baseLineSkip = (BASELINESTRETCH * baseLine)/10;
462 headOfLine = i;
463 headOfLine++;
464 position_HeadOfLine = position;
465 }
466 i++;
467 }
468 dc.EndDoc();
469 m_MaxY = position.y;
470 return foundObject;
471 }
472
473 #ifdef WXLAYOUT_DEBUG
474 void
475 wxLayoutList::Debug(void)
476 {
477 CoordType offs;
478 wxLayoutObjectList::iterator i;
479
480 cerr <<
481 "------------------------debug start-------------------------" << endl;
482 for(i = begin(); i != end(); i++)
483 {
484 (*i)->Debug();
485 cerr << endl;
486 }
487 cerr <<
488 "-----------------------debug end----------------------------"
489 << endl;
490 // show current object:
491 cerr << "Cursor: "
492 << m_CursorPosition.x << ','
493 << m_CursorPosition.y;
494
495 i = FindCurrentObject(&offs);
496 cerr << " line length: " << GetLineLength(i) << " ";
497 if(i == end())
498 {
499 cerr << "<<no object found>>" << endl;
500 return; // FIXME we should set cursor position to maximum allowed
501 // value then
502 }
503 if((*i)->GetType() == WXLO_TYPE_TEXT)
504 {
505 cerr << " \"" << ((wxLayoutObjectText *)(*i))->GetText() << "\", offs: "
506 << offs << endl;
507 }
508 else
509 cerr << ' ' << _t[(*i)->GetType()] << endl;
510
511 }
512 #endif
513
514 /******************** editing stuff ********************/
515
516 wxLayoutObjectList::iterator
517 wxLayoutList::FindObjectCursor(wxPoint const &cpos, CoordType *offset)
518 {
519 wxPoint cursor = wxPoint(0,0); // runs along the objects
520 CoordType width;
521 wxLayoutObjectList::iterator i;
522
523 #ifdef WXLAYOUT_DEBUG
524 cerr << "Looking for object at " << cpos.x << ',' << cpos.y <<
525 endl;
526 #endif
527 for(i = begin(); i != end() && cursor.y <= cpos.y; i++)
528 {
529 width = 0;
530 if((*i)->GetType() == WXLO_TYPE_LINEBREAK)
531 {
532 if(cpos.y == cursor.y)
533 {
534 --i;
535 if(offset)
536 *offset = (*i)->CountPositions();
537 return i;
538 }
539 cursor.x = 0; cursor.y ++;
540 }
541 else
542 cursor.x += (width = (*i)->CountPositions());
543 if(cursor.y == cpos.y && (cursor.x > cpos.x ||
544 ((*i)->GetType() != WXLO_TYPE_CMD && cursor.x == cpos.x))
545 ) // found it ?
546 {
547 if(offset)
548 *offset = cpos.x-(cursor.x-width); // 0==cursor before
549 // the object
550 #ifdef WXLAYOUT_DEBUG
551 cerr << " found object at " << cursor.x-width << ',' <<
552 cursor.y << ", type:" << _t[(*i)->GetType()] <<endl;
553 #endif
554 return i;
555 }
556 }
557 #ifdef WXLAYOUT_DEBUG
558 cerr << " not found" << endl;
559 #endif
560 return end(); // not found
561 }
562
563 wxLayoutObjectList::iterator
564 wxLayoutList::FindCurrentObject(CoordType *offset)
565 {
566 wxLayoutObjectList::iterator obj = end();
567
568 obj = FindObjectCursor(m_CursorPosition, offset);
569 if(obj == end()) // not ideal yet
570 {
571 obj = tail();
572 if(obj != end()) // tail really exists
573 *offset = (*obj)->CountPositions(); // at the end of it
574 }
575 return obj;
576 }
577
578 void
579 wxLayoutList::MoveCursor(int dx, int dy)
580 {
581 CoordType offs, lineLength;
582 wxLayoutObjectList::iterator i;
583
584
585 if(dy > 0 && m_CursorPosition.y < m_MaxLine)
586 m_CursorPosition.y += dy;
587 else if(dy < 0 && m_CursorPosition.y > 0)
588 m_CursorPosition.y += dy; // dy is negative
589 if(m_CursorPosition.y < 0)
590 m_CursorPosition.y = 0;
591 else if (m_CursorPosition.y > m_MaxLine)
592 m_CursorPosition.y = m_MaxLine;
593
594 while(dx > 0)
595 {
596 i = FindCurrentObject(&offs);
597 lineLength = GetLineLength(i);
598 if(m_CursorPosition.x < lineLength)
599 {
600 m_CursorPosition.x ++;
601 dx--;
602 continue;
603 }
604 else
605 {
606 if(m_CursorPosition.y < m_MaxLine)
607 {
608 m_CursorPosition.y++;
609 m_CursorPosition.x = 0;
610 dx--;
611 }
612 else
613 break; // cannot move there
614 }
615 }
616 while(dx < 0)
617 {
618 if(m_CursorPosition.x > 0)
619 {
620 m_CursorPosition.x --;
621 dx++;
622 }
623 else
624 {
625 if(m_CursorPosition.y > 0)
626 {
627 m_CursorPosition.y --;
628 m_CursorPosition.x = 0;
629 i = FindCurrentObject(&offs);
630 lineLength = GetLineLength(i);
631 m_CursorPosition.x = lineLength;
632 dx++;
633 continue;
634 }
635 else
636 break; // cannot move left any more
637 }
638 }
639 // final adjustment:
640 i = FindCurrentObject(&offs);
641 lineLength = GetLineLength(i);
642 if(m_CursorPosition.x > lineLength)
643 m_CursorPosition.x = lineLength;
644
645 #ifdef WXLAYOUT_DEBUG
646 i = FindCurrentObject(&offs);
647 cerr << "Cursor: "
648 << m_CursorPosition.x << ','
649 << m_CursorPosition.y;
650
651 if(i == end())
652 {
653 cerr << "<<no object found>>" << endl;
654 return; // FIXME we should set cursor position to maximum allowed
655 // value then
656 }
657 if((*i)->GetType() == WXLO_TYPE_TEXT)
658 {
659 cerr << " \"" << ((wxLayoutObjectText *)(*i))->GetText() << "\", offs: "
660 << offs << endl;
661 }
662 else
663 cerr << ' ' << _t[(*i)->GetType()] << endl;
664 #endif
665 }
666
667 void
668 wxLayoutList::Delete(CoordType count)
669 {
670 TRACE(Delete);
671
672 if(!m_Editable)
673 return;
674
675 VAR(count);
676
677 CoordType offs, len;
678 wxLayoutObjectList::iterator i;
679
680 do
681 {
682 i = FindCurrentObject(&offs);
683 if(i == end())
684 return;
685 #ifdef WXLAYOUT_DEBUG
686 cerr << "trying to delete: " << _t[(*i)->GetType()] << endl;
687 #endif
688 if((*i)->GetType() == WXLO_TYPE_LINEBREAK)
689 m_MaxLine--;
690 if((*i)->GetType() == WXLO_TYPE_TEXT)
691 {
692 wxLayoutObjectText *tobj = (wxLayoutObjectText *)*i;
693 len = tobj->CountPositions();
694 // If we find the end of a text object, this means that we
695 // have to delete from the object following it.
696 if(offs == len)
697 {
698 i++;
699 if((*i)->GetType() == WXLO_TYPE_TEXT)
700 {
701 offs = 0; // delete from begin of next string
702 tobj = (wxLayoutObjectText *)*i;
703 len = tobj->CountPositions();
704 }
705 else
706 {
707 erase(i);
708 return;
709 }
710 }
711 if(len <= count) // delete this object
712 {
713 count -= len;
714 erase(i);
715 }
716 else
717 {
718 len = count;
719 VAR(offs); VAR(len);
720 tobj->GetText().erase(offs,len);
721 return; // we are done
722 }
723 }
724 else // delete the object
725 {
726 len = (*i)->CountPositions();
727 erase(i); // after this, i is the iterator for the following object
728 if(count > len)
729 count -= len;
730 else
731 count = 0;
732 }
733 }
734 while(count && i != end());
735 }
736
737 void
738 wxLayoutList::Insert(wxLayoutObjectBase *obj)
739 {
740 wxASSERT(obj);
741 CoordType offs;
742 wxLayoutObjectList::iterator i = FindCurrentObject(&offs);
743
744 TRACE(Insert(obj));
745
746 if(i == end())
747 push_back(obj);
748 else
749 {
750 // do we have to split a text object?
751 if((*i)->GetType() == WXLO_TYPE_TEXT && offs != 0 && offs != (*i)->CountPositions())
752 {
753 wxLayoutObjectText *tobj = (wxLayoutObjectText *) *i;
754 #ifdef WXLAYOUT_DEBUG
755 cerr << "text: '" << tobj->GetText() << "'" << endl;
756 VAR(offs);
757 #endif
758 String left = tobj->GetText().substr(0,offs); // get part before cursor
759 VAR(left);
760 tobj->GetText() = tobj->GetText().substr(offs,(*i)->CountPositions()-offs); // keeps the right half
761 VAR(tobj->GetText());
762 insert(i,obj);
763 insert(i,new wxLayoutObjectText(left)); // inserts before
764 }
765 else
766 {
767 wxLayoutObjectList::iterator j = i; // we want to apend after this object
768 j++;
769 if(j != end())
770 insert(j, obj);
771 else
772 push_back(obj);
773 }
774 }
775 m_CursorPosition.x += obj->CountPositions();
776 if(obj->GetType() == WXLO_TYPE_LINEBREAK)
777 m_MaxLine++;
778 }
779
780 void
781 wxLayoutList::Insert(String const &text)
782 {
783 wxLayoutObjectText *tobj = NULL;
784 TRACE(Insert(text));
785
786 if(! m_Editable)
787 return;
788
789 CoordType offs;
790 wxLayoutObjectList::iterator i = FindCurrentObject(&offs);
791
792 if(i != end() && (*i)->GetType() == WXLO_TYPE_TEXT)
793 { // insert into an existing text object:
794 TRACE(inserting into existing object);
795 tobj = (wxLayoutObjectText *)*i ;
796 wxASSERT(tobj);
797 tobj->GetText().insert(offs,text);
798 }
799 else // check whether the previous object is text:
800 {
801 wxLayoutObjectList::iterator j = i;
802 j--;
803 TRACE(checking previous object);
804 if(0 && j != end() && (*j)->GetType() == WXLO_TYPE_TEXT)
805 {
806 tobj = (wxLayoutObjectText *)*i;
807 wxASSERT(tobj);
808 tobj->GetText()+=text;
809 }
810 else // insert a new text object
811 {
812 TRACE(creating new object);
813 Insert(new wxLayoutObjectText(text)); //FIXME not too optimal, slow
814 return; // position gets incremented in Insert(obj)
815 }
816 }
817 m_CursorPosition.x += strlen(text.c_str());
818 }
819
820 CoordType
821 wxLayoutList::GetLineLength(wxLayoutObjectList::iterator i)
822 {
823 if(i == end())
824 return 0;
825
826 CoordType len = 0;
827
828 // search backwards for beginning of line:
829 while(i != begin() && (*i)->GetType() != WXLO_TYPE_LINEBREAK)
830 i--;
831 if((*i)->GetType() == WXLO_TYPE_LINEBREAK)
832 i++;
833 // now we can start counting:
834 while(i != end() && (*i)->GetType() != WXLO_TYPE_LINEBREAK)
835 {
836 len += (*i)->CountPositions();
837 i++;
838 }
839 return len;
840 }
841
842 void
843 wxLayoutList::Clear(int family, int size, int style, int weight,
844 int underline, char const *fg, char const *bg)
845 {
846 wxLayoutObjectList::iterator i = begin();
847
848 while(i != end()) // == while valid
849 erase(i);
850
851 // set defaults
852 m_FontPtSize = size;
853 m_FontUnderline = false;
854 m_FontFamily = family;
855 m_FontStyle = style;
856 m_FontWeight = weight;
857 m_ColourFG = wxTheColourDatabase->FindColour(fg);
858 m_ColourBG = wxTheColourDatabase->FindColour(bg);
859
860 m_Position = wxPoint(0,0);
861 m_CursorPosition = wxPoint(0,0);
862 m_MaxLine = 0;
863 m_LineHeight = (BASELINESTRETCH*m_FontPtSize)/10;
864 m_MaxX = 0; m_MaxY = 0;
865
866
867 if(m_DefaultSetting)
868 delete m_DefaultSetting;
869 m_DefaultSetting = new
870 wxLayoutObjectCmd(m_FontPtSize,m_FontFamily,m_FontStyle,
871 m_FontWeight,m_FontUnderline,
872 m_ColourFG, m_ColourBG);
873 }