]> git.saurik.com Git - wxWidgets.git/blob - user/wxLayout/wxlwindow.cpp
slowdown effect
[wxWidgets.git] / user / wxLayout / wxlwindow.cpp
1 /*-*- c++ -*-********************************************************
2 * wxLwindow.h : a scrolled Window for displaying/entering rich text*
3 * *
4 * (C) 1998, 1999 by Karsten Ballüder (Ballueder@usa.net) *
5 * *
6 * $Id$
7 *******************************************************************/
8
9 #ifdef __GNUG__
10 # pragma implementation "wxlwindow.h"
11 #endif
12
13 #include "wx/wxprec.h"
14 #ifdef __BORLANDC__
15 # pragma hdrstop
16 #endif
17
18
19 #include "Mpch.h"
20 #ifdef M_BASEDIR
21 # ifndef USE_PCH
22 # include "Mcommon.h"
23 # include "gui/wxMenuDefs.h"
24 # include "gui/wxMApp.h"
25 # endif // USE_PCH
26 # include "gui/wxlwindow.h"
27 # include "gui/wxlparser.h"
28 #else
29 # ifdef __WXMSW__
30 # include <windows.h>
31 # undef FindWindow
32 # undef GetCharWidth
33 # undef StartDoc
34 # endif
35
36 # include "wxlwindow.h"
37 # include "wxlparser.h"
38 #endif
39
40 #include <wx/clipbrd.h>
41 #include <wx/textctrl.h>
42 #include <wx/dataobj.h>
43
44 #include <ctype.h>
45
46 #ifdef WXLAYOUT_DEBUG
47 # define WXLO_DEBUG(x) wxLogDebug x
48 #else
49 # define WXLO_DEBUG(x)
50 #endif
51
52 /// offsets to put a nice frame around text
53 #define WXLO_XOFFSET 4
54 #define WXLO_YOFFSET 4
55
56 /// offset to the right and bottom for when to redraw scrollbars
57 #define WXLO_ROFFSET 20
58 #define WXLO_BOFFSET 20
59
60 BEGIN_EVENT_TABLE(wxLayoutWindow,wxScrolledWindow)
61 EVT_PAINT (wxLayoutWindow::OnPaint)
62 EVT_CHAR (wxLayoutWindow::OnChar)
63 EVT_KEY_UP (wxLayoutWindow::OnKeyUp)
64 EVT_LEFT_DOWN(wxLayoutWindow::OnLeftMouseClick)
65 EVT_RIGHT_DOWN(wxLayoutWindow::OnRightMouseClick)
66 EVT_LEFT_DCLICK(wxLayoutWindow::OnMouseDblClick)
67 EVT_MOTION (wxLayoutWindow::OnMouseMove)
68 EVT_MENU_RANGE(WXLOWIN_MENU_FIRST, WXLOWIN_MENU_LAST, wxLayoutWindow::OnMenu)
69 EVT_SET_FOCUS(wxLayoutWindow::OnSetFocus)
70 EVT_KILL_FOCUS(wxLayoutWindow::OnKillFocus)
71 END_EVENT_TABLE()
72
73 wxLayoutWindow::wxLayoutWindow(wxWindow *parent)
74 : wxScrolledWindow(parent, -1, wxDefaultPosition, wxDefaultSize,
75 wxHSCROLL | wxVSCROLL | wxBORDER)
76
77 {
78 m_Editable = false;
79 m_doSendEvents = false;
80 m_ViewStartX = 0; m_ViewStartY = 0;
81 m_DoPopupMenu = true;
82 m_PopupMenu = MakeFormatMenu();
83 m_memDC = new wxMemoryDC;
84 m_bitmap = new wxBitmap(4,4);
85 m_bitmapSize = wxPoint(4,4);
86 m_llist = new wxLayoutList();
87 m_BGbitmap = NULL;
88 m_ScrollToCursor = false;
89 SetWrapMargin(0);
90 wxPoint max = m_llist->GetSize();
91 SetScrollbars(10, 20 /*lineHeight*/, max.x/10+1, max.y/20+1);
92 EnableScrolling(true,true);
93 m_maxx = max.x; m_maxy = max.y;
94 m_Selecting = false;
95 SetCursor(wxCURSOR_IBEAM);
96 SetDirty();
97 }
98
99 wxLayoutWindow::~wxLayoutWindow()
100 {
101 delete m_memDC; // deletes bitmap automatically (?)
102 delete m_bitmap;
103 delete m_llist;
104 delete m_PopupMenu;
105 SetBackgroundBitmap(NULL);
106 }
107
108 void
109 wxLayoutWindow::Clear(int family,
110 int size,
111 int style,
112 int weight,
113 int underline,
114 wxColour *fg,
115 wxColour *bg)
116 {
117 GetLayoutList()->Clear(family,size,style,weight,underline,fg,bg);
118 SetBackgroundColour(*GetLayoutList()->GetDefaults()->GetBGColour());
119 ResizeScrollbars(true);
120 SetDirty();
121 SetModified(false);
122 wxRect r;
123 int w,h;
124 r.x = r.y = 0; GetSize(&w,&h);
125 r.width = w;
126 r.height = h;
127 DoPaint(&r);
128 }
129
130 #ifdef __WXMSW__
131 long
132 wxLayoutWindow::MSWGetDlgCode()
133 {
134 // if we don't return this, we won't get OnChar() events for TABs and ENTER
135 return DLGC_WANTCHARS | DLGC_WANTARROWS | DLGC_WANTMESSAGE;
136 }
137 #endif //MSW
138
139 void
140 wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
141 {
142 wxPaintDC dc( this );
143 PrepareDC( dc );
144 SetFocus();
145
146 wxPoint findPos;
147 findPos.x = dc.DeviceToLogicalX(event.GetX());
148 findPos.y = dc.DeviceToLogicalY(event.GetY());
149
150 findPos.x -= WXLO_XOFFSET;
151 findPos.y -= WXLO_YOFFSET;
152
153 if(findPos.x < 0) findPos.x = 0;
154 if(findPos.y < 0) findPos.y = 0;
155
156 m_ClickPosition = wxPoint(event.GetX(), event.GetY());
157
158 wxPoint cursorPos;
159 bool found;
160 wxLayoutObject *obj = m_llist->FindObjectScreen(dc, findPos,
161 &cursorPos, &found);
162
163 //has the mouse only been moved?
164 if(eventId == WXLOWIN_MENU_MOUSEMOVE)
165 {
166 // found is only true if we are really over an object, not just
167 // behind it
168 if(found && obj && obj->GetUserData() != NULL)
169 {
170 if(!m_HandCursor)
171 SetCursor(wxCURSOR_HAND);
172 m_HandCursor = TRUE;
173 }
174 else
175 {
176 if(m_HandCursor)
177 SetCursor(wxCURSOR_IBEAM);
178 m_HandCursor = FALSE;
179 }
180 return;
181 }
182
183 // always move cursor to mouse click:
184 if(obj && eventId == WXLOWIN_MENU_LCLICK)
185 {
186 m_llist->MoveCursorTo(cursorPos);
187 ScrollToCursor();
188 Refresh(FALSE); // DoPaint suppresses flicker under GTK
189 }
190 if(!m_doSendEvents) // nothing to do
191 return;
192
193 // only do the menu if activated, editable and not on a clickable object
194 if(eventId == WXLOWIN_MENU_RCLICK
195 && IsEditable()
196 && (! obj || (obj && obj->GetUserData() == NULL))
197 )
198 {
199 PopupMenu(m_PopupMenu, m_ClickPosition.x, m_ClickPosition.y);
200 return;
201 }
202 // find the object at this position
203 if(obj)
204 {
205 wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, eventId);
206 commandEvent.SetEventObject( this );
207 commandEvent.SetClientData((char *)obj);
208 GetEventHandler()->ProcessEvent(commandEvent);
209 }
210 }
211
212 /*
213 * Some simple keyboard handling.
214 */
215 void
216 wxLayoutWindow::OnChar(wxKeyEvent& event)
217 {
218 int keyCode = event.KeyCode();
219
220 #ifdef WXLAYOUT_DEBUG
221 if(keyCode == WXK_F1)
222 {
223 m_llist->Debug();
224 return;
225 }
226 #endif
227
228 if(! m_Selecting && event.ShiftDown())
229 {
230 switch(keyCode)
231 {
232 case WXK_UP:
233 case WXK_DOWN:
234 case WXK_RIGHT:
235 case WXK_LEFT:
236 case WXK_PRIOR:
237 case WXK_NEXT:
238 case WXK_HOME:
239 case WXK_END:
240 m_Selecting = true;
241 m_llist->StartSelection();
242 break;
243 default:
244 ;
245 }
246 }
247
248 /* These two nested switches work like this:
249 The first one processes all non-editing keycodes, to move the
250 cursor, etc. It's default will process all keycodes causing
251 modifications to the buffer, but only if editing is allowed.
252 */
253 switch(keyCode)
254 {
255 case WXK_RIGHT:
256 m_llist->MoveCursorHorizontally(1);
257 break;
258 case WXK_LEFT:
259 m_llist->MoveCursorHorizontally(-1);
260 break;
261 case WXK_UP:
262 m_llist->MoveCursorVertically(-1);
263 break;
264 case WXK_DOWN:
265 m_llist->MoveCursorVertically(1);
266 break;
267 case WXK_PRIOR:
268 m_llist->MoveCursorVertically(-20);
269 break;
270 case WXK_NEXT:
271 m_llist->MoveCursorVertically(20);
272 break;
273 case WXK_HOME:
274 m_llist->MoveCursorToBeginOfLine();
275 break;
276 case WXK_END:
277 m_llist->MoveCursorToEndOfLine();
278 break;
279 default:
280 if(keyCode == 'c' && event.ControlDown())
281 Copy();
282 if( IsEditable() )
283 {
284 /* First, handle control keys */
285 if(event.ControlDown() && ! event.AltDown())
286 {
287 switch(keyCode)
288 {
289 case WXK_DELETE :
290 case 'd':
291 m_llist->Delete(1);
292 break;
293 case 'y':
294 m_llist->DeleteLines(1);
295 break;
296 case 'h': // like backspace
297 if(m_llist->MoveCursorHorizontally(-1)) m_llist->Delete(1);
298 break;
299 case 'u':
300 m_llist->DeleteToBeginOfLine();
301 break;
302 case 'k':
303 m_llist->DeleteToEndOfLine();
304 break;
305 case 'v':
306 Paste();
307 break;
308 #ifdef WXLAYOUT_DEBUG
309 case WXK_F1:
310 m_llist->SetFont(-1,-1,-1,-1,true); // underlined
311 break;
312 #endif
313 default:
314 ;
315 }
316 }
317 // ALT only:
318 else if( event.AltDown() && ! event.ControlDown() )
319 {
320 switch(keyCode)
321 {
322 case WXK_DELETE:
323 case 'd':
324 m_llist->DeleteWord();
325 break;
326 default:
327 ;
328 }
329 }
330 // no control keys:
331 else if ( ! event.AltDown() && ! event.ControlDown())
332 {
333 switch(keyCode)
334 {
335 case WXK_INSERT:
336 if(event.ShiftDown())
337 Paste();
338 break;
339 case WXK_DELETE :
340 m_llist->Delete(1);
341 break;
342 case WXK_BACK: // backspace
343 if(m_llist->MoveCursorHorizontally(-1)) m_llist->Delete(1);
344 break;
345 case WXK_RETURN:
346 if(m_WrapMargin > 0)
347 m_llist->WrapLine(m_WrapMargin);
348 m_llist->LineBreak();
349 break;
350 default:
351 if((!(event.ControlDown() || event.AltDown() || event.MetaDown()))
352 && (keyCode < 256 && keyCode >= 32)
353 )
354 {
355 wxString tmp;
356 tmp += keyCode;
357 if(m_WrapMargin > 0 && isspace(keyCode))
358 m_llist->WrapLine(m_WrapMargin);
359 m_llist->Insert(tmp);
360 }
361 break;
362 }
363 }
364 SetDirty();
365 SetModified();
366 }// if(IsEditable())
367 }// first switch()
368 if(m_Selecting)
369 {
370 if(event.ShiftDown())
371 m_llist->ContinueSelection();
372 else
373 {
374 m_llist->EndSelection();
375 m_Selecting = false;
376 }
377 }
378
379 ScrollToCursor();
380 wxRect r = *m_llist->GetUpdateRect();
381 DoPaint(&r);
382 }
383
384 void
385 wxLayoutWindow::OnKeyUp(wxKeyEvent& event)
386 {
387 if(event.KeyCode() == WXK_SHIFT && m_llist->IsSelecting())
388 m_llist->EndSelection();
389 event.Skip();
390 }
391
392
393 void
394 wxLayoutWindow::ScrollToCursor(void)
395 {
396 wxClientDC dc( this );
397 PrepareDC( dc );
398
399 int x0,y0,x1,y1, dx, dy;
400
401 // Calculate where the top of the visible area is:
402 ViewStart(&x0,&y0);
403 GetScrollPixelsPerUnit(&dx, &dy);
404 x0 *= dx; y0 *= dy;
405
406 WXLO_DEBUG(("ScrollToCursor: ViewStart is %d/%d", x0, y0));
407
408 // Get the size of the visible window:
409 GetClientSize(&x1,&y1);
410 wxASSERT(x1 > 0);
411 wxASSERT(y1 > 0);
412 // As we have the values anyway, use them to avoid unnecessary
413 // scrollbar updates.
414 if(x1 > m_maxx) m_maxx = x1;
415 if(y1 > m_maxy) m_maxy = y1;
416 /* Make sure that the scrollbars are at a position so that the
417 cursor is visible if we are editing. */
418 /** Scroll so that cursor is visible! */
419 WXLO_DEBUG(("m_ScrollToCursor = %d", (int) m_ScrollToCursor));
420 wxPoint cc = m_llist->GetCursorScreenPos(*m_memDC);
421 if(cc.x < x0 || cc.y < y0
422 || cc.x >= x0+(9*x1)/10 || cc.y >= y0+(9*y1/10)) // (9*x)/10 == 90%
423 {
424 int nx, ny;
425 nx = cc.x - x1/2; if(nx < 0) nx = 0;
426 ny = cc.y - y1/2; if(ny < 0) ny = 0;
427 Scroll(nx/dx,ny/dy); // new view start
428 x0 = nx; y0 = ny;
429 m_ScrollToCursor = false; // avoid recursion
430 }
431 }
432
433 void
434 wxLayoutWindow::OnPaint( wxPaintEvent &WXUNUSED(event)) // or: OnDraw(wxDC& dc)
435 {
436 wxRect region = GetUpdateRegion().GetBox();
437 InternalPaint(& region);
438 }
439
440 void
441 wxLayoutWindow::DoPaint(const wxRect *updateRect)
442 {
443 #ifdef __WXGTK__
444 InternalPaint(updateRect);
445 #else
446 Refresh(FALSE, updateRect); // Causes bad flicker under wxGTK!!!
447 #endif
448 }
449
450 void
451 wxLayoutWindow::InternalPaint(const wxRect *updateRect)
452 {
453 wxPaintDC dc( this );
454 PrepareDC( dc );
455
456 int x0,y0,x1,y1, dx, dy;
457
458 // Calculate where the top of the visible area is:
459 ViewStart(&x0,&y0);
460 GetScrollPixelsPerUnit(&dx, &dy);
461 x0 *= dx; y0 *= dy;
462
463 // Get the size of the visible window:
464 GetClientSize(&x1,&y1);
465 wxASSERT(x1 > 0);
466 wxASSERT(y1 > 0);
467 // As we have the values anyway, use them to avoid unnecessary
468 // scrollbar updates.
469 if(x1 > m_maxx) m_maxx = x1;
470 if(y1 > m_maxy) m_maxy = y1;
471
472 WXLO_DEBUG(("Update rect: %ld,%ld / %ld,%ld",
473 updateRect->x, updateRect->y,
474 updateRect->x+updateRect->width,
475 updateRect->y+updateRect->height));
476
477 if(IsDirty())
478 {
479 m_llist->Layout(dc);
480 ResizeScrollbars();
481 }
482 /* Check whether the window has grown, if so, we need to reallocate
483 the bitmap to be larger. */
484 if(x1 > m_bitmapSize.x || y1 > m_bitmapSize.y)
485 {
486 wxASSERT(m_bitmapSize.x > 0);
487 wxASSERT(m_bitmapSize.y > 0);
488
489 m_memDC->SelectObject(wxNullBitmap);
490 delete m_bitmap;
491 m_bitmapSize = wxPoint(x1,y1);
492 m_bitmap = new wxBitmap(x1,y1);
493 m_memDC->SelectObject(*m_bitmap);
494 }
495
496 m_memDC->SetDeviceOrigin(0,0);
497 m_memDC->SetBrush(wxBrush(*m_llist->GetDefaults()->GetBGColour(),wxSOLID));
498 m_memDC->SetPen(wxPen(*m_llist->GetDefaults()->GetBGColour(),
499 0,wxTRANSPARENT));
500 m_memDC->SetLogicalFunction(wxCOPY);
501
502 /* Either fill the background with the background bitmap, or clear
503 it. */
504 if(m_BGbitmap)
505 {
506 CoordType
507 y, x,
508 w = m_BGbitmap->GetWidth(),
509 h = m_BGbitmap->GetHeight();
510 for(y = 0; y < y1; y+=h)
511 for(x = 0; x < x1; x+=w)
512 m_memDC->DrawBitmap(*m_BGbitmap, x, y);
513 m_memDC->SetBackgroundMode(wxTRANSPARENT);
514 }
515 else
516 {
517 // clear the background: (must not be done if we use the update rectangle!)
518 m_memDC->SetBackgroundMode(wxSOLID);
519 m_memDC->DrawRectangle(0,0,x1, y1);
520 }
521
522
523 /* This is the important bit: we tell the list to draw itself: */
524 #if WXLO_DEBUG_URECT
525 WXLO_DEBUG(("Update rect: %ld,%ld / %ld,%ld",
526 updateRect->x, updateRect->y,
527 updateRect->x+updateRect->width,
528 updateRect->y+updateRect->height));
529 #endif
530
531 // Device origins on the memDC are suspect, we translate manually
532 // with the translate parameter of Draw().
533 wxPoint offset(-x0+WXLO_XOFFSET,-y0+WXLO_YOFFSET);
534 m_llist->Draw(*m_memDC,offset, y0, y0+y1);
535
536 // We start calculating a new update rect before drawing the
537 // cursor, so that the cursor coordinates get included in the next
538 // update rectangle (although they are drawn on the memDC, this is
539 // needed to erase it):
540 m_llist->InvalidateUpdateRect();
541 m_llist->DrawCursor(*m_memDC,
542 m_HaveFocus && IsEditable(), // draw a thick
543 // cursor for editable windows with focus
544 offset);
545
546 // Now copy everything to the screen:
547 #if 0
548 // This somehow doesn't work, but even the following bit with the
549 // whole rect at once is still a bit broken I think.
550 wxRegionIterator ri ( GetUpdateRegion() );
551 if(ri)
552 while(ri)
553 {
554 WXLO_DEBUG(("UpdateRegion: %ld,%ld, %ld,%ld",
555 ri.GetX(),ri.GetY(),ri.GetW(),ri.GetH()));
556 dc.Blit(x0+ri.GetX(),y0+ri.GetY(),ri.GetW(),ri.GetH(),
557 m_memDC,ri.GetX(),ri.GetY(),wxCOPY,FALSE);
558 ri++;
559 }
560 else
561 #endif
562 {
563 // FIXME: Trying to copy only the changed parts, but it does not seem
564 // to work:
565 // x0 = updateRect->x; y0 = updateRect->y;
566 // if(updateRect->height < y1)
567 // y1 = updateRect->height;
568 // y1 += WXLO_YOFFSET; //FIXME might not be needed
569 dc.Blit(x0,y0,x1,y1,m_memDC,0,0,wxCOPY,FALSE);
570 }
571
572 ResetDirty();
573 m_ScrollToCursor = false;
574 }
575
576 // change the range and position of scrollbars
577 void
578 wxLayoutWindow::ResizeScrollbars(bool exact)
579 {
580 wxPoint max = m_llist->GetSize();
581
582 WXLO_DEBUG(("ResizeScrollbars: GetSize: %ld, %ld", (long int)max.x,
583 (long int) max.y));
584 if(max.x > m_maxx || max.y > m_maxy
585 || max.x > m_maxx-WXLO_ROFFSET || max.y > m_maxy-WXLO_BOFFSET
586 || exact)
587 {
588 if(! exact)
589 {
590 // add an extra bit to the sizes to avoid future updates
591 max.x = max.x+WXLO_ROFFSET;
592 max.y = max.y+WXLO_BOFFSET;
593 }
594 ViewStart(&m_ViewStartX, &m_ViewStartY);
595 SetScrollbars(10, 20, max.x/10+1,max.y/20+1,m_ViewStartX,m_ViewStartY,true);
596 m_maxx = max.x; m_maxy = max.y;
597 }
598 }
599
600 void
601 wxLayoutWindow::Paste(void)
602 {
603 wxString text;
604 // Read some text
605 if (wxTheClipboard->Open())
606 {
607 wxTextDataObject data;
608 if (wxTheClipboard->IsSupported( data.GetFormat() ))
609 {
610 wxTheClipboard->GetData(&data);
611 text += data.GetText();
612 }
613 wxTheClipboard->Close();
614 }
615 #if 0
616 /* My attempt to get the primary selection, but it does not
617 work. :-( */
618 if(text.Length() == 0)
619 {
620 wxTextCtrl tmp_tctrl(this,-1);
621 tmp_tctrl.Paste();
622 text += tmp_tctrl.GetValue();
623 }
624 #endif
625 wxLayoutImportText( m_llist, text);
626 }
627
628 bool
629 wxLayoutWindow::Copy(void)
630 {
631 // Calling GetSelection() will automatically do an EndSelection()
632 // on the list, but we need to take a note of it, too:
633 if(m_Selecting)
634 {
635 m_Selecting = false;
636 m_llist->EndSelection();
637 }
638 wxLayoutList *llist = m_llist->GetSelection();
639 if(! llist)
640 return FALSE;
641
642 wxString text;
643 wxLayoutExportObject *export;
644 wxLayoutExportStatus status(llist);
645 while((export = wxLayoutExport( &status, WXLO_EXPORT_AS_TEXT)) != NULL)
646 {
647 if(export->type == WXLO_EXPORT_TEXT)
648 text << *(export->content.text);
649 delete export;
650 }
651 delete llist;
652
653 // The exporter always appends a newline, so we chop it off if it
654 // is there:
655 {
656 size_t len = text.Length();
657 if(len > 2 && text[len-2] == '\r') // Windows
658 text = text.Mid(0,len-2);
659 else if(len > 1 && text[len-1] == '\n')
660 text = text.Mid(0,len-1);
661 }
662
663 // Read some text
664 if (wxTheClipboard->Open())
665 {
666 wxTextDataObject *data = new wxTextDataObject( text );
667 bool rc = wxTheClipboard->SetData( data );
668 wxTheClipboard->Close();
669 return rc;
670 }
671 return FALSE;
672 }
673
674 bool
675 wxLayoutWindow::Cut(void)
676 {
677 if(Copy())
678 {
679 m_llist->DeleteSelection();
680 return TRUE;
681 }
682 else
683 return FALSE;
684 }
685 bool
686 wxLayoutWindow::Find(const wxString &needle,
687 wxPoint * fromWhere)
688 {
689 wxPoint found;
690
691 if(fromWhere == NULL)
692 found = m_llist->FindText(needle, m_llist->GetCursorPos());
693 else
694 found = m_llist->FindText(needle, *fromWhere);
695 if(found.x != -1)
696 {
697 if(fromWhere)
698 {
699 *fromWhere = found;
700 fromWhere->x ++;
701 }
702 m_llist->MoveCursorTo(found);
703 ScrollToCursor();
704 return true;
705 }
706 return false;
707 }
708
709 wxMenu *
710 wxLayoutWindow::MakeFormatMenu()
711 {
712 wxMenu *m = new wxMenu(_("Layout Menu"));
713
714 m->Append(WXLOWIN_MENU_LARGER ,_("&Larger"),_("Switch to larger font."), false);
715 m->Append(WXLOWIN_MENU_SMALLER ,_("&Smaller"),_("Switch to smaller font."), false);
716 m->AppendSeparator();
717 m->Append(WXLOWIN_MENU_UNDERLINE_ON, _("&Underline on"),_("Activate underline mode."), false);
718 m->Append(WXLOWIN_MENU_UNDERLINE_OFF,_("&Underline off"),_("Deactivate underline mode."), false);
719 m->Append(WXLOWIN_MENU_BOLD_ON ,_("&Bold on"),_("Activate bold mode."), false);
720 m->Append(WXLOWIN_MENU_BOLD_OFF ,_("&Bold off"),_("Deactivate bold mode."), false);
721 m->Append(WXLOWIN_MENU_ITALICS_ON ,_("&Italics on"),_("Activate italics mode."), false);
722 m->Append(WXLOWIN_MENU_ITALICS_OFF ,_("&Italics off"),_("Deactivate italics mode."), false);
723 m->AppendSeparator();
724 m->Append(WXLOWIN_MENU_ROMAN ,_("&Roman"),_("Switch to roman font."), false);
725 m->Append(WXLOWIN_MENU_TYPEWRITER,_("&Typewriter"),_("Switch to typewriter font."), false);
726 m->Append(WXLOWIN_MENU_SANSSERIF ,_("&Sans Serif"),_("Switch to sans serif font."), false);
727 return m;
728 }
729
730 void wxLayoutWindow::OnMenu(wxCommandEvent& event)
731 {
732 switch (event.GetId())
733 {
734 case WXLOWIN_MENU_LARGER:
735 m_llist->SetFontLarger(); break;
736 case WXLOWIN_MENU_SMALLER:
737 m_llist->SetFontSmaller(); break;
738 case WXLOWIN_MENU_UNDERLINE_ON:
739 m_llist->SetFontUnderline(true); break;
740 case WXLOWIN_MENU_UNDERLINE_OFF:
741 m_llist->SetFontUnderline(false); break;
742 case WXLOWIN_MENU_BOLD_ON:
743 m_llist->SetFontWeight(wxBOLD); break;
744 case WXLOWIN_MENU_BOLD_OFF:
745 m_llist->SetFontWeight(wxNORMAL); break;
746 case WXLOWIN_MENU_ITALICS_ON:
747 m_llist->SetFontStyle(wxITALIC); break;
748 case WXLOWIN_MENU_ITALICS_OFF:
749 m_llist->SetFontStyle(wxNORMAL); break;
750 case WXLOWIN_MENU_ROMAN:
751 m_llist->SetFontFamily(wxROMAN); break;
752 case WXLOWIN_MENU_TYPEWRITER:
753 m_llist->SetFontFamily(wxFIXED); break;
754 case WXLOWIN_MENU_SANSSERIF:
755 m_llist->SetFontFamily(wxSWISS); break;
756 }
757 }
758
759 void
760 wxLayoutWindow::OnSetFocus(wxFocusEvent &ev)
761 {
762 m_HaveFocus = true;
763 //FIXME: need argument DoPaint(); // to repaint the cursor
764 }
765
766 void
767 wxLayoutWindow::OnKillFocus(wxFocusEvent &ev)
768 {
769 m_HaveFocus = false;
770 //FIXME: need argument DoPaint(); // to repaint the cursor
771 }