1 /*-*- c++ -*-********************************************************
2 * wxLwindow.h : a scrolled Window for displaying/entering rich text*
4 * (C) 1998 by Karsten Ballüder (Ballueder@usa.net) *
7 *******************************************************************/
10 # pragma implementation "wxlwindow.h"
18 # include "gui/wxMenuDefs.h"
20 # include "gui/wxlwindow.h"
30 # include "wxlwindow.h"
31 # define TRACEMESSAGE(x)
33 # define WXL_VAR(x) cerr << #x " = " << x ;
35 BEGIN_EVENT_TABLE(wxLayoutWindow
,wxScrolledWindow
)
36 EVT_PAINT (wxLayoutWindow::OnPaint
)
37 EVT_CHAR (wxLayoutWindow::OnChar
)
39 EVT_LEFT_DOWN(wxLayoutWindow::OnLeftMouseClick
)
40 EVT_RIGHT_DOWN(wxLayoutWindow::OnRightMouseClick
)
41 EVT_LEFT_DCLICK(wxLayoutWindow::OnMouseDblClick
)
42 EVT_MENU(WXLOWIN_MENU_LARGER
, wxLayoutWindow::OnMenu
)
43 EVT_MENU(WXLOWIN_MENU_SMALLER
, wxLayoutWindow::OnMenu
)
44 EVT_MENU(WXLOWIN_MENU_UNDERLINE
, wxLayoutWindow::OnMenu
)
45 EVT_MENU(WXLOWIN_MENU_BOLD
, wxLayoutWindow::OnMenu
)
46 EVT_MENU(WXLOWIN_MENU_ITALICS
, wxLayoutWindow::OnMenu
)
47 EVT_MENU(WXLOWIN_MENU_ROMAN
, wxLayoutWindow::OnMenu
)
48 EVT_MENU(WXLOWIN_MENU_TYPEWRITER
, wxLayoutWindow::OnMenu
)
49 EVT_MENU(WXLOWIN_MENU_SANSSERIF
, wxLayoutWindow::OnMenu
)
52 wxLayoutWindow::wxLayoutWindow(wxWindow
*parent
)
53 : wxScrolledWindow(parent
, -1, wxDefaultPosition
, wxDefaultSize
,
54 wxHSCROLL
| wxVSCROLL
| wxBORDER
)
57 m_ScrollbarsSet
= false;
58 m_doSendEvents
= false;
59 m_ViewStartX
= 0; m_ViewStartY
= 0;
64 max_x
, max_y
, lineHeight
;
65 m_llist
.GetSize(&max_x
, &max_y
, &lineHeight
);
66 SetScrollbars(10, lineHeight
, max_x
/10+1, max_y
/lineHeight
+1);
67 EnableScrolling(true,true);
72 wxLayoutWindow::MSWGetDlgCode()
74 // if we don't return this, we won't get OnChar() events
75 return DLGC_WANTCHARS
| DLGC_WANTARROWS
| DLGC_WANTMESSAGE
;
80 wxLayoutWindow::Update(void)
90 m_llist
.DrawCursor(dc
);
94 wxLayoutWindow::OnMouse(int eventId
, wxMouseEvent
& event
)
96 if(!m_doSendEvents
) // nothing to do
104 findPos
.x
= dc
.DeviceToLogicalX(event
.GetX());
105 findPos
.y
= dc
.DeviceToLogicalY(event
.GetY());
107 TRACEMESSAGE(("wxLayoutWindow::OnMouse: (%d, %d) -> (%d, %d)",
108 event
.GetX(), event
.GetY(), findPos
.x
, findPos
.y
));
110 if(eventId
== WXLOWIN_MENU_RCLICK
&& m_DoPopupMenu
&& m_llist
.IsEditable())
112 // when does this menu get freed?
113 // how do we handle toggling? FIXME
114 PopupMenu(MakeFormatMenu(), event
.GetX(), event
.GetY());
117 // find the object at this position
118 wxLayoutObjectBase
*obj
= m_llist
.Find(findPos
);
121 wxCommandEvent
commandEvent(wxEVENT_TYPE_MENU_COMMAND
, eventId
);
122 commandEvent
.SetEventObject( this );
123 commandEvent
.SetClientData((char *)obj
);
124 GetEventHandler()->ProcessEvent(commandEvent
);
129 * some simple keyboard handling
132 wxLayoutWindow::OnChar(wxKeyEvent
& event
)
134 if(! m_llist
.IsEditable()) // do nothing
140 long keyCode
= event
.KeyCode();
144 switch(event
.KeyCode())
147 m_llist
.MoveCursor(1);
150 m_llist
.MoveCursor(-1);
153 m_llist
.MoveCursor(0,-1);
156 m_llist
.MoveCursor(0,1);
159 m_llist
.MoveCursor(0,-20);
162 m_llist
.MoveCursor(0,20);
165 p
= m_llist
.GetCursor();
167 m_llist
.SetCursor(p
);
170 p
= m_llist
.GetCursor();
171 p
.x
= m_llist
.GetLineLength(m_llist
.FindCurrentObject(NULL
));
172 m_llist
.SetCursor(p
);
175 if(event
.ControlDown()) // delete to end of line
177 help
= m_llist
.GetLineLength(
178 m_llist
.FindCurrentObject(NULL
))
179 - m_llist
.GetCursor().x
;
180 m_llist
.Delete(help
? help
: 1);
185 case WXK_BACK
: // backspace
186 if(m_llist
.MoveCursor(-1)) {
194 #ifdef WXLAYOUT_DEBUG
201 if(keyCode
< 256 && keyCode
>= 32)
210 /** Scroll so that cursor is visible! */
211 int x0
,y0
,x1
,y1
,ux
,uy
;
213 GetScrollPixelsPerUnit(&ux
,&uy
);
215 GetClientSize(&x1
,&y1
);
217 wxPoint cc
= m_llist
.GetCursorCoords();
218 int nx
= x0
, ny
= y0
;
219 // when within 10% of borders, scroll to center
220 if(cc
.y
> y0
+(9*y1
)/10)
222 else if (cc
.y
< y0
+y1
/10)
227 if(cc
.x
> x0
+(9*x1
)/10)
229 else if (cc
.x
< x0
+x1
/10)
240 wxLayoutWindow::OnPaint( wxPaintEvent
&WXUNUSED(event
)) // or: OnDraw(wxDC& dc)
242 wxPaintDC
dc( this );
247 // wxGTK: wxMemoryDC broken?
252 WXL_VAR(x0
); WXL_VAR(y0
);
253 WXL_VAR(x1
); WXL_VAR(y1
);
257 memdc
.SelectObject(bm
);
259 // make temporary copy and edit this
260 memdc
.SetDeviceOrigin(x0
,y0
);
261 memdc
.Blit(x0
,y0
,x1
,y1
,&dc
,x0
,y0
,wxCOPY
,FALSE
);
264 dc
.Blit(x0
,y0
,x1
,y1
,&memdc
,x0
,y0
,wxCOPY
,FALSE
);
269 // does the actual painting
271 wxLayoutWindow::DoPaint(wxDC
&dc
)
273 m_llist
.EraseAndDraw(dc
);
274 m_llist
.DrawCursor(dc
);
275 // FIXME: not strictly correct, this does only work for changes behind
276 // the cursor position, not complete redraws
278 if(! m_ScrollbarsSet
)
280 m_ScrollbarsSet
= true; // avoid recursion
286 wxLayoutWindow::UpdateScrollbars(void)
289 max_x
, max_y
, lineHeight
;
291 ViewStart(&m_ViewStartX
, &m_ViewStartY
);
292 m_llist
.GetSize(&max_x
, &max_y
, &lineHeight
);
293 SetScrollbars(10, lineHeight
, max_x
/10+1, max_y
/lineHeight
+1,m_ViewStartX
,m_ViewStartY
,true);
294 //EnableScrolling(true,true);
295 //Scroll(m_ViewStartX, m_ViewStartY);
299 wxLayoutWindow::Print(void)
301 wxPostScriptDC
dc("layout.ps",true,this);
302 if (dc
.Ok() && dc
.StartDoc((char *)_("Printing message...")))
304 //dc.SetUserScale(1.0, 1.0);
311 wxLayoutWindow::MakeFormatMenu()
316 wxMenu
*m
= new wxMenu();
318 m
->Append(WXLOWIN_MENU_LARGER
,_("&Larger"),_("Switch to larger font."), false);
319 m
->Append(WXLOWIN_MENU_SMALLER
,_("&Smaller"),_("Switch to smaller font."), false);
320 m
->AppendSeparator();
321 m
->Append(WXLOWIN_MENU_UNDERLINE
,_("&Underline"),_("Toggle underline mode."), true);
322 m
->Append(WXLOWIN_MENU_BOLD
,_("&Bold"),_("Toggle bold mode."), true);
323 m
->Append(WXLOWIN_MENU_ITALICS
,_("&Italics"),_("Toggle italics mode."), true);
324 m
->AppendSeparator();
325 m
->Append(WXLOWIN_MENU_ROMAN
,_("&Roman"),_("Toggle underline mode."), false);
326 m
->Append(WXLOWIN_MENU_TYPEWRITER
,_("&Typewriter"),_("Toggle bold mode."), false);
327 m
->Append(WXLOWIN_MENU_SANSSERIF
,_("&Sans Serif"),_("Toggle italics mode."), false);
329 return m_PopupMenu
= m
;
332 void wxLayoutWindow::OnMenu(wxCommandEvent
& event
)
334 if(! m_llist
.IsEditable())
337 switch (event
.GetId())
339 case WXLOWIN_MENU_LARGER
:
340 m_llist
.SetFontLarger();
342 case WXLOWIN_MENU_SMALLER
:
343 m_llist
.SetFontSmaller();
345 case WXLOWIN_MENU_UNDERLINE
:
346 m_llist
.SetFontUnderline(
347 m_PopupMenu
->IsChecked(WXLOWIN_MENU_UNDERLINE
) ? false : true
350 case WXLOWIN_MENU_BOLD
:
351 m_llist
.SetFontWeight(
352 m_PopupMenu
->IsChecked(WXLOWIN_MENU_BOLD
) ? wxNORMAL
: wxBOLD
354 case WXLOWIN_MENU_ITALICS
:
355 m_llist
.SetFontStyle(
356 m_PopupMenu
->IsChecked(WXLOWIN_MENU_ITALICS
) ? wxNORMAL
: wxITALIC
359 case WXLOWIN_MENU_ROMAN
:
360 m_llist
.SetFontFamily(wxROMAN
); break;
361 case WXLOWIN_MENU_TYPEWRITER
:
362 m_llist
.SetFontFamily(wxFIXED
); break;
363 case WXLOWIN_MENU_SANSSERIF
:
364 m_llist
.SetFontFamily(wxSWISS
); break;