]> git.saurik.com Git - wxWidgets.git/blob - user/wxLayout/wxllist.cpp
Setting of background colours is now correct.
[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 m_DefaultSetting->Draw(dc,wxPoint(0,0),0,true);
333
334 // we calculate everything for drawing a line, then rewind to the
335 // begin of line and actually draw it
336 i = begin();
337 for(;;)
338 {
339 recalculate = false;
340
341 if(i == end())
342 break;
343 type = (*i)->GetType();
344
345 // to initialise sizes of objects, we need to call Draw
346 (*i)->Draw(dc, position, baseLine, draw);
347
348 // update coordinates for next object:
349 size = (*i)->GetSize(&objBaseLine);
350 if(findObject && draw) // we need to look for an object
351 {
352 if(findCoords.y >= position.y
353 && findCoords.y <= position.y+size.y
354 && findCoords.x >= position.x
355 && findCoords.x <= position.x+size.x)
356 {
357 foundObject = *i;
358 findObject = false; // speeds things up
359 }
360 }
361 // draw the cursor
362 if(m_Editable && draw && i == cursorObject)
363 {
364 if(type == WXLO_TYPE_TEXT) // special treatment
365 {
366 long descent = 0l; long width, height;
367 tobj = (wxLayoutObjectText *)*i;
368 String str = tobj->GetText();
369 VAR(m_CursorPosition.x); VAR(cursor.x);
370 str = str.substr(0, cursorOffset);
371 VAR(str);
372 dc.GetTextExtent(Str(str), &width,&height, &descent);
373 VAR(height);
374 VAR(width); VAR(descent);
375 dc.DrawLine(position.x+width,
376 position.y+(baseLineSkip-height),
377 position.x+width, position.y+baseLineSkip);
378 }
379 else
380 {
381 if(type == WXLO_TYPE_LINEBREAK)
382 dc.DrawLine(0, position.y+baseLineSkip, 0, position.y+2*baseLineSkip);
383 else
384 {
385 if(size.x == 0)
386 {
387 if(size.y == 0)
388 dc.DrawLine(position.x, position.y, position.x, position.y+baseLineSkip);
389 else
390 dc.DrawLine(position.x, position.y, position.x, position.y+size.y);
391 }
392 else
393 dc.DrawRectangle(position.x, position.y, size.x, size.y);
394 }
395 }
396 }
397
398 // calculate next object's position:
399 position.x += size.x;
400
401 // do we need to increase the line's height?
402 if(size.y > baseLineSkip)
403 {
404 baseLineSkip = size.y;
405 recalculate = true;
406 }
407 if(objBaseLine > baseLine)
408 {
409 baseLine = objBaseLine;
410 recalculate = true;
411 }
412
413 // now check whether we have finished handling this line:
414 if(type == WXLO_TYPE_LINEBREAK || i == tail())
415 {
416 if(recalculate) // do this line again
417 {
418 position.x = position_HeadOfLine.x;
419 i = headOfLine;
420 continue;
421 }
422
423 if(! draw) // finished calculating sizes
424 {
425 // if the this line needs to go onto a new page, we need
426 // to change pages before drawing it:
427 if(margins.bottom != -1 && position.y > margins.bottom)
428 {
429 dc.EndPage();
430 position_HeadOfLine.y = margins.top;
431 dc.StartPage();
432 }
433 // do this line again, this time drawing it
434 position = position_HeadOfLine;
435 draw = true;
436 i = headOfLine;
437 continue;
438 }
439 else // we have drawn a line, so continue calculating next one
440 draw = false;
441 }
442
443 if(position.x+size.x > m_MaxX)
444 m_MaxX = position.x+size.x;
445 // is it a linebreak?
446 if(type == WXLO_TYPE_LINEBREAK || i == tail())
447 {
448 position.x = margins.left;
449 position.y += baseLineSkip;
450 baseLine = m_FontPtSize;
451 objBaseLine = baseLine; // not all objects set it
452 baseLineSkip = (BASELINESTRETCH * baseLine)/10;
453 headOfLine = i;
454 headOfLine++;
455 position_HeadOfLine = position;
456 }
457 i++;
458 }
459 dc.EndDoc();
460 m_MaxY = position.y;
461 return foundObject;
462 }
463
464 #ifdef WXLAYOUT_DEBUG
465 void
466 wxLayoutList::Debug(void)
467 {
468 CoordType offs;
469 wxLayoutObjectList::iterator i;
470
471 cerr <<
472 "------------------------debug start-------------------------" << endl;
473 for(i = begin(); i != end(); i++)
474 {
475 (*i)->Debug();
476 cerr << endl;
477 }
478 cerr <<
479 "-----------------------debug end----------------------------"
480 << endl;
481 // show current object:
482 cerr << "Cursor: "
483 << m_CursorPosition.x << ','
484 << m_CursorPosition.y;
485
486 i = FindCurrentObject(&offs);
487 cerr << " line length: " << GetLineLength(i) << " ";
488 if(i == end())
489 {
490 cerr << "<<no object found>>" << endl;
491 return; // FIXME we should set cursor position to maximum allowed
492 // value then
493 }
494 if((*i)->GetType() == WXLO_TYPE_TEXT)
495 {
496 cerr << " \"" << ((wxLayoutObjectText *)(*i))->GetText() << "\", offs: "
497 << offs << endl;
498 }
499 else
500 cerr << ' ' << _t[(*i)->GetType()] << endl;
501
502 }
503 #endif
504
505 /******************** editing stuff ********************/
506
507 wxLayoutObjectList::iterator
508 wxLayoutList::FindObjectCursor(wxPoint const &cpos, CoordType *offset)
509 {
510 wxPoint cursor = wxPoint(0,0); // runs along the objects
511 CoordType width;
512 wxLayoutObjectList::iterator i;
513
514 #ifdef WXLAYOUT_DEBUG
515 cerr << "Looking for object at " << cpos.x << ',' << cpos.y <<
516 endl;
517 #endif
518 for(i = begin(); i != end() && cursor.y <= cpos.y; i++)
519 {
520 width = 0;
521 if((*i)->GetType() == WXLO_TYPE_LINEBREAK)
522 {
523 if(cpos.y == cursor.y)
524 {
525 --i;
526 if(offset)
527 *offset = (*i)->CountPositions();
528 return i;
529 }
530 cursor.x = 0; cursor.y ++;
531 }
532 else
533 cursor.x += (width = (*i)->CountPositions());
534 if(cursor.y == cpos.y && (cursor.x > cpos.x ||
535 ((*i)->GetType() != WXLO_TYPE_CMD && cursor.x == cpos.x))
536 ) // found it ?
537 {
538 if(offset)
539 *offset = cpos.x-(cursor.x-width); // 0==cursor before
540 // the object
541 #ifdef WXLAYOUT_DEBUG
542 cerr << " found object at " << cursor.x-width << ',' <<
543 cursor.y << ", type:" << _t[(*i)->GetType()] <<endl;
544 #endif
545 return i;
546 }
547 }
548 #ifdef WXLAYOUT_DEBUG
549 cerr << " not found" << endl;
550 #endif
551 return end(); // not found
552 }
553
554 wxLayoutObjectList::iterator
555 wxLayoutList::FindCurrentObject(CoordType *offset)
556 {
557 wxLayoutObjectList::iterator obj = end();
558
559 obj = FindObjectCursor(m_CursorPosition, offset);
560 if(obj == end()) // not ideal yet
561 {
562 obj = tail();
563 if(obj != end()) // tail really exists
564 *offset = (*obj)->CountPositions(); // at the end of it
565 }
566 return obj;
567 }
568
569 void
570 wxLayoutList::MoveCursor(int dx, int dy)
571 {
572 CoordType offs, lineLength;
573 wxLayoutObjectList::iterator i;
574
575
576 if(dy > 0 && m_CursorPosition.y < m_MaxLine)
577 m_CursorPosition.y += dy;
578 else if(dy < 0 && m_CursorPosition.y > 0)
579 m_CursorPosition.y += dy; // dy is negative
580 if(m_CursorPosition.y < 0)
581 m_CursorPosition.y = 0;
582 else if (m_CursorPosition.y > m_MaxLine)
583 m_CursorPosition.y = m_MaxLine;
584
585 while(dx > 0)
586 {
587 i = FindCurrentObject(&offs);
588 lineLength = GetLineLength(i);
589 if(m_CursorPosition.x < lineLength)
590 {
591 m_CursorPosition.x ++;
592 dx--;
593 continue;
594 }
595 else
596 {
597 if(m_CursorPosition.y < m_MaxLine)
598 {
599 m_CursorPosition.y++;
600 m_CursorPosition.x = 0;
601 dx--;
602 }
603 else
604 break; // cannot move there
605 }
606 }
607 while(dx < 0)
608 {
609 if(m_CursorPosition.x > 0)
610 {
611 m_CursorPosition.x --;
612 dx++;
613 }
614 else
615 {
616 if(m_CursorPosition.y > 0)
617 {
618 m_CursorPosition.y --;
619 m_CursorPosition.x = 0;
620 i = FindCurrentObject(&offs);
621 lineLength = GetLineLength(i);
622 m_CursorPosition.x = lineLength;
623 dx++;
624 continue;
625 }
626 else
627 break; // cannot move left any more
628 }
629 }
630 // final adjustment:
631 i = FindCurrentObject(&offs);
632 lineLength = GetLineLength(i);
633 if(m_CursorPosition.x > lineLength)
634 m_CursorPosition.x = lineLength;
635
636 #ifdef WXLAYOUT_DEBUG
637 i = FindCurrentObject(&offs);
638 cerr << "Cursor: "
639 << m_CursorPosition.x << ','
640 << m_CursorPosition.y;
641
642 if(i == end())
643 {
644 cerr << "<<no object found>>" << endl;
645 return; // FIXME we should set cursor position to maximum allowed
646 // value then
647 }
648 if((*i)->GetType() == WXLO_TYPE_TEXT)
649 {
650 cerr << " \"" << ((wxLayoutObjectText *)(*i))->GetText() << "\", offs: "
651 << offs << endl;
652 }
653 else
654 cerr << ' ' << _t[(*i)->GetType()] << endl;
655 #endif
656 }
657
658 void
659 wxLayoutList::Delete(CoordType count)
660 {
661 TRACE(Delete);
662
663 if(!m_Editable)
664 return;
665
666 VAR(count);
667
668 CoordType offs, len;
669 wxLayoutObjectList::iterator i;
670
671 do
672 {
673 i = FindCurrentObject(&offs);
674 if(i == end())
675 return;
676 #ifdef WXLAYOUT_DEBUG
677 cerr << "trying to delete: " << _t[(*i)->GetType()] << endl;
678 #endif
679 if((*i)->GetType() == WXLO_TYPE_LINEBREAK)
680 m_MaxLine--;
681 if((*i)->GetType() == WXLO_TYPE_TEXT)
682 {
683 wxLayoutObjectText *tobj = (wxLayoutObjectText *)*i;
684 len = tobj->CountPositions();
685 // If we find the end of a text object, this means that we
686 // have to delete from the object following it.
687 if(offs == len)
688 {
689 i++;
690 if((*i)->GetType() == WXLO_TYPE_TEXT)
691 {
692 offs = 0; // delete from begin of next string
693 tobj = (wxLayoutObjectText *)*i;
694 len = tobj->CountPositions();
695 }
696 else
697 {
698 erase(i);
699 return;
700 }
701 }
702 if(len <= count) // delete this object
703 {
704 count -= len;
705 erase(i);
706 }
707 else
708 {
709 len = count;
710 VAR(offs); VAR(len);
711 tobj->GetText().erase(offs,len);
712 return; // we are done
713 }
714 }
715 else // delete the object
716 {
717 len = (*i)->CountPositions();
718 erase(i); // after this, i is the iterator for the following object
719 if(count > len)
720 count -= len;
721 else
722 count = 0;
723 }
724 }
725 while(count && i != end());
726 }
727
728 void
729 wxLayoutList::Insert(wxLayoutObjectBase *obj)
730 {
731 wxASSERT(obj);
732 CoordType offs;
733 wxLayoutObjectList::iterator i = FindCurrentObject(&offs);
734
735 TRACE(Insert(obj));
736
737 if(i == end())
738 push_back(obj);
739 else
740 {
741 // do we have to split a text object?
742 if((*i)->GetType() == WXLO_TYPE_TEXT && offs != 0 && offs != (*i)->CountPositions())
743 {
744 wxLayoutObjectText *tobj = (wxLayoutObjectText *) *i;
745 #ifdef WXLAYOUT_DEBUG
746 cerr << "text: '" << tobj->GetText() << "'" << endl;
747 VAR(offs);
748 #endif
749 String left = tobj->GetText().substr(0,offs); // get part before cursor
750 VAR(left);
751 tobj->GetText() = tobj->GetText().substr(offs,(*i)->CountPositions()-offs); // keeps the right half
752 VAR(tobj->GetText());
753 insert(i,obj);
754 insert(i,new wxLayoutObjectText(left)); // inserts before
755 }
756 else
757 {
758 wxLayoutObjectList::iterator j = i; // we want to apend after this object
759 j++;
760 if(j != end())
761 insert(j, obj);
762 else
763 push_back(obj);
764 }
765 }
766 m_CursorPosition.x += obj->CountPositions();
767 if(obj->GetType() == WXLO_TYPE_LINEBREAK)
768 m_MaxLine++;
769 }
770
771 void
772 wxLayoutList::Insert(String const &text)
773 {
774 wxLayoutObjectText *tobj = NULL;
775 TRACE(Insert(text));
776
777 if(! m_Editable)
778 return;
779
780 CoordType offs;
781 wxLayoutObjectList::iterator i = FindCurrentObject(&offs);
782
783 if(i != end() && (*i)->GetType() == WXLO_TYPE_TEXT)
784 { // insert into an existing text object:
785 TRACE(inserting into existing object);
786 tobj = (wxLayoutObjectText *)*i ;
787 wxASSERT(tobj);
788 tobj->GetText().insert(offs,text);
789 }
790 else // check whether the previous object is text:
791 {
792 wxLayoutObjectList::iterator j = i;
793 j--;
794 TRACE(checking previous object);
795 if(0 && j != end() && (*j)->GetType() == WXLO_TYPE_TEXT)
796 {
797 tobj = (wxLayoutObjectText *)*i;
798 wxASSERT(tobj);
799 tobj->GetText()+=text;
800 }
801 else // insert a new text object
802 {
803 TRACE(creating new object);
804 Insert(new wxLayoutObjectText(text)); //FIXME not too optimal, slow
805 return; // position gets incremented in Insert(obj)
806 }
807 }
808 m_CursorPosition.x += strlen(text.c_str());
809 }
810
811 CoordType
812 wxLayoutList::GetLineLength(wxLayoutObjectList::iterator i)
813 {
814 if(i == end())
815 return 0;
816
817 CoordType len = 0;
818
819 // search backwards for beginning of line:
820 while(i != begin() && (*i)->GetType() != WXLO_TYPE_LINEBREAK)
821 i--;
822 if((*i)->GetType() == WXLO_TYPE_LINEBREAK)
823 i++;
824 // now we can start counting:
825 while(i != end() && (*i)->GetType() != WXLO_TYPE_LINEBREAK)
826 {
827 len += (*i)->CountPositions();
828 i++;
829 }
830 return len;
831 }
832
833 void
834 wxLayoutList::Clear(int family, int size, int style, int weight,
835 int underline, char const *fg, char const *bg)
836 {
837 wxLayoutObjectList::iterator i = begin();
838
839 while(i != end()) // == while valid
840 erase(i);
841
842 // set defaults
843 m_FontPtSize = size;
844 m_FontUnderline = false;
845 m_FontFamily = family;
846 m_FontStyle = style;
847 m_FontWeight = weight;
848 m_ColourFG = wxTheColourDatabase->FindColour(fg);
849 m_ColourBG = wxTheColourDatabase->FindColour(bg);
850
851 m_Position = wxPoint(0,0);
852 m_CursorPosition = wxPoint(0,0);
853 m_MaxLine = 0;
854 m_LineHeight = (BASELINESTRETCH*m_FontPtSize)/10;
855 m_MaxX = 0; m_MaxY = 0;
856
857
858 if(m_DefaultSetting)
859 delete m_DefaultSetting;
860 m_DefaultSetting = new
861 wxLayoutObjectCmd(m_FontPtSize,m_FontFamily,m_FontStyle,
862 m_FontWeight,m_FontUnderline,
863 m_ColourFG, m_ColourBG);
864 }