--- /dev/null
+
+BUGS
+=====================================================================
+
+- Delete():
+ 1 - occasionally delete deletes too much, maybe when at begin of
+ line?
+ 2 - when in an empty line, Delete() doesn't always merge lines
+ 3 - line numbers aren't updated properly, may be related to 2.
+ 4 - deleting lines leaves later parts of the list unaffected
+ --> just redrawing at least the next two lines doesn't seem
+ enough, strange, don't positions change?
+- dmalloc shows duplicate deletion after merging two lines and
+ deleting the second half
+
+TODO
+=====================================================================
+
+- Add word wrap to wxlwindow/wxllist.
+- Cursor to mouseclick
+- Focus feedback for cursor
+- Selections
+
+- More optimisations
+
/// define the most commonly used list type once:
KBLIST_DEFINE(kbStringList, String);
#endif
-
+//@}
#endif // KBLIST_H
// MyFrame
//-----------------------------------------------------------------------------
- enum ids{ ID_EDIT = 1, ID_ADD_SAMPLE, ID_CLEAR, ID_PRINT,
+ enum ids{ ID_ADD_SAMPLE = 1, ID_CLEAR, ID_PRINT,
ID_PRINT_SETUP, ID_PAGE_SETUP, ID_PREVIEW, ID_PRINT_PS,
ID_PRINT_SETUP_PS, ID_PAGE_SETUP_PS,ID_PREVIEW_PS,
- ID_DPRINT, ID_WRAP, ID_NOWRAP,
+ ID_WRAP, ID_NOWRAP,
ID_WXLAYOUT_DEBUG, ID_QUIT, ID_CLICK, ID_HTML, ID_TEXT, ID_TEST };
IMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame )
BEGIN_EVENT_TABLE(MyFrame,wxFrame)
- EVT_MENU(ID_PRINT, MyFrame::OnPrint)
- EVT_MENU(ID_PREVIEW, MyFrame::OnPrintPreview)
- EVT_MENU(ID_PRINT_SETUP, MyFrame::OnPrintSetup)
- EVT_MENU(ID_PAGE_SETUP, MyFrame::OnPageSetup)
- EVT_MENU(ID_PRINT_PS, MyFrame::OnPrintPS)
- EVT_MENU(ID_PREVIEW_PS, MyFrame::OnPrintPreviewPS)
- EVT_MENU(ID_PRINT_SETUP_PS, MyFrame::OnPrintSetupPS)
- EVT_MENU(ID_PAGE_SETUP_PS, MyFrame::OnPageSetupPS)
- EVT_MENU (-1, MyFrame::OnCommand)
- EVT_COMMAND (-1,-1, MyFrame::OnCommand)
- EVT_CHAR ( wxLayoutWindow::OnChar )
+ EVT_MENU(ID_PRINT, MyFrame::OnPrint)
+ EVT_MENU(ID_PREVIEW, MyFrame::OnPrintPreview)
+ EVT_MENU(ID_PRINT_SETUP, MyFrame::OnPrintSetup)
+ EVT_MENU(ID_PAGE_SETUP, MyFrame::OnPageSetup)
+ EVT_MENU(ID_PRINT_PS, MyFrame::OnPrintPS)
+ EVT_MENU(ID_PREVIEW_PS, MyFrame::OnPrintPreviewPS)
+ EVT_MENU(ID_PRINT_SETUP_PS, MyFrame::OnPrintSetupPS)
+ EVT_MENU(ID_PAGE_SETUP_PS, MyFrame::OnPageSetupPS)
+ EVT_MENU (-1, MyFrame::OnCommand)
+ EVT_COMMAND (-1,-1, MyFrame::OnCommand)
+ EVT_CHAR ( wxLayoutWindow::OnChar )
END_EVENT_TABLE()
-int orientation = wxPORTRAIT;
+ int orientation = wxPORTRAIT;
MyFrame::MyFrame(void) :
- wxFrame( (wxFrame *) NULL, -1, (char *) "wxLayout", wxPoint(20,20), wxSize(600,360) )
+ wxFrame( (wxFrame *) NULL, -1, (char *) "wxLayout", wxPoint(20,20), wxSize(600,360) )
{
CreateStatusBar( 1 );
wxMenu *file_menu = new wxMenu;
file_menu->Append( ID_CLEAR, "Clear");
file_menu->Append( ID_ADD_SAMPLE, "Example");
-// file_menu->Append( ID_EDIT, "Edit");
-// file_menu->Append( ID_WXLAYOUT_DEBUG, "Debug");
- file_menu->Append(ID_PRINT, "&Print...", "Print");
- file_menu->Append(ID_PRINT_SETUP, "Print &Setup...","Setup printer properties");
- file_menu->Append(ID_PAGE_SETUP, "Page Set&up...", "Page setup");
- file_menu->Append(ID_PREVIEW, "Print Pre&view", "Preview");
+ file_menu->Append(ID_PRINT, "&Print...", "Print");
+ file_menu->Append(ID_PRINT_SETUP, "Print &Setup...","Setup printer properties");
+ file_menu->Append(ID_PAGE_SETUP, "Page Set&up...", "Page setup");
+ file_menu->Append(ID_PREVIEW, "Print Pre&view", "Preview");
#ifdef __WXMSW__
- file_menu->AppendSeparator();
- file_menu->Append(ID_PRINT_PS, "Print PostScript...", "Print (PostScript)");
- file_menu->Append(ID_PRINT_SETUP_PS, "Print Setup PostScript...", "Setup printer properties (PostScript)");
- file_menu->Append(ID_PAGE_SETUP_PS, "Page Setup PostScript...", "Page setup (PostScript)");
- file_menu->Append(ID_PREVIEW_PS, "Print Preview PostScript", "Preview (PostScript)");
+ file_menu->AppendSeparator();
+ file_menu->Append(ID_PRINT_PS, "Print PostScript...", "Print (PostScript)");
+ file_menu->Append(ID_PRINT_SETUP_PS, "Print Setup PostScript...", "Setup printer properties (PostScript)");
+ file_menu->Append(ID_PAGE_SETUP_PS, "Page Setup PostScript...", "Page setup (PostScript)");
+ file_menu->Append(ID_PREVIEW_PS, "Print Preview PostScript", "Preview (PostScript)");
#endif
- file_menu->AppendSeparator();
- file_menu->Append(ID_WRAP, "Wrap mode", "Activate wrapping at pixel 200.");
- file_menu->Append(ID_NOWRAP, "No-wrap mode", "Deactivate wrapping.");
+ file_menu->AppendSeparator();
+ file_menu->Append(ID_WRAP, "Wrap mode", "Activate wrapping at pixel 200.");
+ file_menu->Append(ID_NOWRAP, "No-wrap mode", "Deactivate wrapping.");
- file_menu->AppendSeparator();
-// file_menu->Append( ID_DPRINT, "Direct Print");
+ file_menu->AppendSeparator();
file_menu->Append( ID_TEXT, "Export Text");
file_menu->Append( ID_HTML, "Export HTML");
-// file_menu->Append( ID_TEST, "Test");
file_menu->Append( ID_QUIT, "Exit");
wxMenuBar *menu_bar = new wxMenuBar();
m_lwin = new wxLayoutWindow(this);
m_lwin->SetMouseTracking(true);
- m_lwin->GetLayoutList().SetEditable(true);
+ m_lwin->SetEditable(true);
m_lwin->Clear(wxROMAN,16,wxNORMAL,wxNORMAL, false);
m_lwin->SetFocus();
};
void
-MyFrame::AddSampleText(wxLayoutList &llist)
+MyFrame::AddSampleText(wxLayoutList *llist)
{
- llist.SetFont(wxROMAN,16,wxNORMAL,wxNORMAL, false);
- llist.Insert("--");
- llist.LineBreak();
-
- llist.SetFont(wxROMAN);
- llist.Insert("The quick brown fox jumps over the lazy dog.");
- llist.LineBreak();
- llist.Insert("Hello ");
- llist.Insert(new wxLayoutObjectIcon(new wxICON(Micon)));
- llist.LineBreak();
- llist.SetFontWeight(wxBOLD);
- llist.Insert("World! ");
- llist.SetFontWeight(wxNORMAL);
- llist.Insert("The quick brown fox jumps...");
- llist.LineBreak();
-
- llist.Insert("over the lazy dog.");
- llist.SetFont(-1,-1,-1,-1,true);
- llist.Insert("underlined");
- llist.SetFont(-1,-1,-1,-1,false);
- llist.SetFont(wxROMAN);
- llist.Insert("This is ");
- llist.SetFont(-1,-1,-1,wxBOLD); llist.Insert("BOLD "); llist.SetFont(-1,-1,-1,wxNORMAL);
- llist.Insert("and ");
- llist.SetFont(-1,-1,wxITALIC);
- llist.Insert("italics ");
- llist.SetFont(-1,-1,wxNORMAL);
- llist.LineBreak();
+ llist->SetFont(wxROMAN,16,wxNORMAL,wxNORMAL, false);
+ llist->Insert("--");
+ llist->LineBreak();
+
+ llist->SetFont(wxROMAN);
+ llist->Insert("The quick brown fox jumps over the lazy dog.");
+ llist->LineBreak();
+ llist->Insert("Hello ");
+ llist->Insert(new wxLayoutObjectIcon(new wxICON(Micon)));
+ llist->SetFontWeight(wxBOLD);
+ llist->Insert("World! ");
+ llist->SetFontWeight(wxNORMAL);
+ llist->Insert("The quick brown fox jumps...");
+ llist->LineBreak();
+
+ llist->Insert("over the lazy dog.");
+ llist->SetFont(-1,-1,-1,-1,true);
+ llist->Insert("underlined");
+ llist->SetFont(-1,-1,-1,-1,false);
+ llist->SetFont(wxROMAN);
+ llist->Insert("This is ");
+ llist->SetFont(-1,-1,-1,wxBOLD); llist->Insert("BOLD "); llist->SetFont(-1,-1,-1,wxNORMAL);
+ llist->Insert("and ");
+ llist->SetFont(-1,-1,wxITALIC);
+ llist->Insert("italics ");
+ llist->SetFont(-1,-1,wxNORMAL);
+ llist->LineBreak();
- llist.Insert("and ");
- llist.SetFont(-1,-1,wxSLANT);
- llist.Insert("slanted");
- llist.SetFont(-1,-1,wxNORMAL);
- llist.Insert(" text.");
- llist.LineBreak();
-
- llist.Insert("and ");
- llist.SetFont(-1,-1,-1,-1,-1,"blue");
- llist.Insert("blue");
- llist.SetFont(-1,-1,-1,-1,-1,"black");
- llist.Insert(" and ");
- llist.SetFont(-1,-1,-1,-1,-1,"green","black");
- llist.Insert("green on black");
- llist.SetFont(-1,-1,-1,-1,-1,"black","white");
- llist.Insert(" text.");
- llist.LineBreak();
-
- llist.SetFont(-1,-1,wxSLANT);
- llist.Insert("Slanted");
- llist.SetFont(-1,-1,wxNORMAL);
- llist.Insert(" and normal text and ");
- llist.SetFont(-1,-1,wxSLANT);
- llist.Insert("slanted");
- llist.SetFont(-1,-1,wxNORMAL);
- llist.Insert(" again.");
- llist.LineBreak();
+ llist->Insert("and ");
+ llist->SetFont(-1,-1,wxSLANT);
+ llist->Insert("slanted");
+ llist->SetFont(-1,-1,wxNORMAL);
+ llist->Insert(" text.");
+ llist->LineBreak();
+
+ llist->Insert("and ");
+ llist->SetFont(-1,-1,-1,-1,-1,"blue");
+ llist->Insert("blue");
+ llist->SetFont(-1,-1,-1,-1,-1,"black");
+ llist->Insert(" and ");
+ llist->SetFont(-1,-1,-1,-1,-1,"green","black");
+ llist->Insert("green on black");
+ llist->SetFont(-1,-1,-1,-1,-1,"black","white");
+ llist->Insert(" text.");
+ llist->LineBreak();
+
+ llist->SetFont(-1,-1,wxSLANT);
+ llist->Insert("Slanted");
+ llist->SetFont(-1,-1,wxNORMAL);
+ llist->Insert(" and normal text and ");
+ llist->SetFont(-1,-1,wxSLANT);
+ llist->Insert("slanted");
+ llist->SetFont(-1,-1,wxNORMAL);
+ llist->Insert(" again.");
+ llist->LineBreak();
// add some more text for testing:
- llist.Insert("And here the source for the test program:");
- llist.LineBreak();
- llist.SetFont(wxTELETYPE,16);
+ llist->Insert("And here the source for the test program:");
+ llist->LineBreak();
+ llist->SetFont(wxTELETYPE,16);
char buffer[1024];
FILE *in = fopen("wxLayout.cpp","r");
if(in)
fgets(buffer,1024,in);
if(feof(in))
break;
- llist.Insert(buffer);
- llist.LineBreak();
+ llist->Insert(buffer);
+ llist->LineBreak();
}
}
-
+ llist->MoveCursorTo(wxPoint(0,0));
+ m_lwin->SetDirty();
m_lwin->Refresh();
- m_lwin->UpdateScrollbars();
- llist.SetEditable();
- llist.SetCursor(wxPoint(0,0));
}
void
MyFrame::Clear(void)
{
m_lwin->Clear(wxROMAN,16,wxNORMAL,wxNORMAL, false);
- m_lwin->UpdateScrollbars();
}
-/* test the editing */
-void MyFrame::Edit(void)
-{
- wxLayoutList & llist = m_lwin->GetLayoutList();
- //m_lwin->SetEventId(ID_CLICK);
-
- llist.MoveCursor(0);
- llist.MoveCursor(5);
- llist.MoveCursor(0,2);
- llist.Delete(2);
- llist.MoveCursor(2);
- llist.Insert("not");
- llist.LineBreak();
- m_lwin->Refresh();
-}
void MyFrame::OnCommand( wxCommandEvent &event )
{
- cerr << "id:" << event.GetId() << endl;
switch (event.GetId())
{
case ID_QUIT:
Close( TRUE );
break;
case ID_PRINT:
-{
- wxPrinter printer;
- wxLayoutPrintout printout(m_lwin->GetLayoutList(),_("M: Printout"));
- if (! printer.Print(this, &printout, TRUE))
- wxMessageBox(
- _("There was a problem with printing the message:\n"
- "perhaps your current printer is not set up correctly?"),
- _("Printing"), wxOK);
-}
- break;
- case ID_NOWRAP:
- case ID_WRAP:
- m_lwin->GetLayoutList().SetWrapMargin(
- event.GetId() == ID_NOWRAP ? -1 : 40);
- break;
- case ID_DPRINT:
{
- wxLayoutList llist;
- AddSampleText(llist);
- wxPostScriptDC dc("layout.ps",true,this);
- if (dc.Ok() && dc.StartDoc((char *)_("Printing message...")))
- {
- //dc.SetUserScale(1.0, 1.0);
- llist.Draw(dc); //,false,wxPoint(0,0),true);
- dc.EndDoc();
- }
+ wxPrinter printer;
+ wxLayoutPrintout printout(m_lwin->GetLayoutList(),_("M: Printout"));
+ if (! printer.Print(this, &printout, TRUE))
+ wxMessageBox(
+ _("There was a problem with printing the message:\n"
+ "perhaps your current printer is not set up correctly?"),
+ _("Printing"), wxOK);
}
break;
- case ID_EDIT:
- Edit();
+ case ID_NOWRAP:
+ case ID_WRAP:
+//// m_lwin->GetLayoutList()->SetWrapMargin(
+//// event.GetId() == ID_NOWRAP ? -1 : 40);
break;
case ID_ADD_SAMPLE:
AddSampleText(m_lwin->GetLayoutList());
case ID_CLEAR:
Clear();
break;
- case ID_WXLAYOUT_DEBUG:
- m_lwin->GetLayoutList().Debug();
- break;
case ID_CLICK:
cerr << "Received click event." << endl;
break;
case ID_HTML:
{
wxLayoutExportObject *export;
- wxLayoutList::iterator i = m_lwin->GetLayoutList().begin();
+ wxLayoutExportStatus status(m_lwin->GetLayoutList());
- while((export = wxLayoutExport(m_lwin->GetLayoutList(),
- i,WXLO_EXPORT_AS_HTML)) != NULL)
+ while((export = wxLayoutExport( &status, WXLO_EXPORT_AS_HTML)) != NULL)
{
if(export->type == WXLO_EXPORT_HTML)
cout << *(export->content.text);
case ID_TEXT:
{
wxLayoutExportObject *export;
- wxLayoutList::iterator i = m_lwin->GetLayoutList().begin();
+ wxLayoutExportStatus status(m_lwin->GetLayoutList());
- while((export = wxLayoutExport(m_lwin->GetLayoutList(),
- i,WXLO_EXPORT_AS_TEXT)) != NULL)
+ while((export = wxLayoutExport( &status, WXLO_EXPORT_AS_TEXT)) != NULL)
{
if(export->type == WXLO_EXPORT_TEXT)
cout << *(export->content.text);
void MyFrame::OnPrint(wxCommandEvent& WXUNUSED(event))
{
#ifdef __WXMSW__
- wxGetApp().SetPrintMode(wxPRINT_WINDOWS);
+ wxGetApp().SetPrintMode(wxPRINT_WINDOWS);
#else
- wxGetApp().SetPrintMode(wxPRINT_POSTSCRIPT);
+ wxGetApp().SetPrintMode(wxPRINT_POSTSCRIPT);
#endif
- wxPrinter printer;
- wxLayoutPrintout printout( m_lwin->GetLayoutList(),"Printout from wxLayout");
- if (! printer.Print(this, &printout, TRUE))
- wxMessageBox(
- "There was a problem printing.\nPerhaps your current printer is not set correctly?",
- "Printing", wxOK);
+ wxPrinter printer;
+ wxLayoutPrintout printout( m_lwin->GetLayoutList(),"Printout from wxLayout");
+ if (! printer.Print(this, &printout, TRUE))
+ wxMessageBox(
+ "There was a problem printing.\nPerhaps your current printer is not set correctly?",
+ "Printing", wxOK);
}
void MyFrame::OnPrintPS(wxCommandEvent& WXUNUSED(event))
{
- wxGetApp().SetPrintMode(wxPRINT_POSTSCRIPT);
+ wxGetApp().SetPrintMode(wxPRINT_POSTSCRIPT);
- wxPostScriptPrinter printer;
- wxLayoutPrintout printout( m_lwin->GetLayoutList(),"My printout");
- printer.Print(this, &printout, TRUE);
+ wxPostScriptPrinter printer;
+ wxLayoutPrintout printout( m_lwin->GetLayoutList(),"My printout");
+ printer.Print(this, &printout, TRUE);
}
void MyFrame::OnPrintPreview(wxCommandEvent& WXUNUSED(event))
{
#ifdef __WXMSW__
- wxGetApp().SetPrintMode(wxPRINT_WINDOWS);
+ wxGetApp().SetPrintMode(wxPRINT_WINDOWS);
#else
- wxGetApp().SetPrintMode(wxPRINT_POSTSCRIPT);
+ wxGetApp().SetPrintMode(wxPRINT_POSTSCRIPT);
#endif
- wxPrintData printData;
- printData.SetOrientation(orientation);
-
- // Pass two printout objects: for preview, and possible printing.
- wxPrintPreview *preview = new wxPrintPreview(new
- wxLayoutPrintout(
- m_lwin->GetLayoutList()), new wxLayoutPrintout( m_lwin->GetLayoutList()), & printData);
- if (!preview->Ok())
- {
- delete preview;
- wxMessageBox("There was a problem previewing.\nPerhaps your current printer is not set correctly?", "Previewing", wxOK);
- return;
- }
+ wxPrintData printData;
+ printData.SetOrientation(orientation);
+
+ // Pass two printout objects: for preview, and possible printing.
+ wxPrintPreview *preview = new wxPrintPreview(new
+ wxLayoutPrintout(
+ m_lwin->GetLayoutList()), new wxLayoutPrintout( m_lwin->GetLayoutList()), & printData);
+ if (!preview->Ok())
+ {
+ delete preview;
+ wxMessageBox("There was a problem previewing.\nPerhaps your current printer is not set correctly?", "Previewing", wxOK);
+ return;
+ }
- wxPreviewFrame *frame = new wxPreviewFrame(preview, this, "Demo Print Preview", wxPoint(100, 100), wxSize(600, 650));
- frame->Centre(wxBOTH);
- frame->Initialize();
- frame->Show(TRUE);
+ wxPreviewFrame *frame = new wxPreviewFrame(preview, this, "Demo Print Preview", wxPoint(100, 100), wxSize(600, 650));
+ frame->Centre(wxBOTH);
+ frame->Initialize();
+ frame->Show(TRUE);
}
void MyFrame::OnPrintPreviewPS(wxCommandEvent& WXUNUSED(event))
{
- wxGetApp().SetPrintMode(wxPRINT_POSTSCRIPT);
+ wxGetApp().SetPrintMode(wxPRINT_POSTSCRIPT);
- wxPrintData printData;
- printData.SetOrientation(orientation);
+ wxPrintData printData;
+ printData.SetOrientation(orientation);
- // Pass two printout objects: for preview, and possible printing.
- wxPrintPreview *preview = new wxPrintPreview(new wxLayoutPrintout( m_lwin->GetLayoutList()), new wxLayoutPrintout( m_lwin->GetLayoutList()), & printData);
- wxPreviewFrame *frame = new wxPreviewFrame(preview, this, "Demo Print Preview", wxPoint(100, 100), wxSize(600, 650));
- frame->Centre(wxBOTH);
- frame->Initialize();
- frame->Show(TRUE);
+ // Pass two printout objects: for preview, and possible printing.
+ wxPrintPreview *preview = new wxPrintPreview(new wxLayoutPrintout( m_lwin->GetLayoutList()), new wxLayoutPrintout( m_lwin->GetLayoutList()), & printData);
+ wxPreviewFrame *frame = new wxPreviewFrame(preview, this, "Demo Print Preview", wxPoint(100, 100), wxSize(600, 650));
+ frame->Centre(wxBOTH);
+ frame->Initialize();
+ frame->Show(TRUE);
}
void MyFrame::OnPrintSetup(wxCommandEvent& WXUNUSED(event))
{
#ifdef __WXMSW__
- wxGetApp().SetPrintMode(wxPRINT_WINDOWS);
+ wxGetApp().SetPrintMode(wxPRINT_WINDOWS);
#else
- wxGetApp().SetPrintMode(wxPRINT_POSTSCRIPT);
+ wxGetApp().SetPrintMode(wxPRINT_POSTSCRIPT);
#endif
- wxPrintData data;
- data.SetOrientation(orientation);
+ wxPrintData data;
+ data.SetOrientation(orientation);
#ifdef __WXMSW__
- wxPrintDialog printerDialog(this, & data);
+ wxPrintDialog printerDialog(this, & data);
#else
- wxGenericPrintDialog printerDialog(this, & data);
+ wxGenericPrintDialog printerDialog(this, & data);
#endif
- printerDialog.GetPrintData().SetSetupDialog(TRUE);
- printerDialog.ShowModal();
+ printerDialog.GetPrintData().SetSetupDialog(TRUE);
+ printerDialog.ShowModal();
- orientation = printerDialog.GetPrintData().GetOrientation();
+ orientation = printerDialog.GetPrintData().GetOrientation();
}
void MyFrame::OnPageSetup(wxCommandEvent& WXUNUSED(event))
{
#ifdef __WXMSW__
- wxGetApp().SetPrintMode(wxPRINT_WINDOWS);
+ wxGetApp().SetPrintMode(wxPRINT_WINDOWS);
#else
- wxGetApp().SetPrintMode(wxPRINT_POSTSCRIPT);
+ wxGetApp().SetPrintMode(wxPRINT_POSTSCRIPT);
#endif
- wxPageSetupData data;
- data.SetOrientation(orientation);
+ wxPageSetupData data;
+ data.SetOrientation(orientation);
#ifdef __WXMSW__
- wxPageSetupDialog pageSetupDialog(this, & data);
+ wxPageSetupDialog pageSetupDialog(this, & data);
#else
- wxGenericPageSetupDialog pageSetupDialog(this, & data);
+ wxGenericPageSetupDialog pageSetupDialog(this, & data);
#endif
- pageSetupDialog.ShowModal();
+ pageSetupDialog.ShowModal();
- data = pageSetupDialog.GetPageSetupData();
- orientation = data.GetOrientation();
+ data = pageSetupDialog.GetPageSetupData();
+ orientation = data.GetOrientation();
}
void MyFrame::OnPrintSetupPS(wxCommandEvent& WXUNUSED(event))
{
- wxGetApp().SetPrintMode(wxPRINT_POSTSCRIPT);
+ wxGetApp().SetPrintMode(wxPRINT_POSTSCRIPT);
- wxPrintData data;
- data.SetOrientation(orientation);
+ wxPrintData data;
+ data.SetOrientation(orientation);
- wxGenericPrintDialog printerDialog(this, & data);
- printerDialog.GetPrintData().SetSetupDialog(TRUE);
- printerDialog.ShowModal();
+ wxGenericPrintDialog printerDialog(this, & data);
+ printerDialog.GetPrintData().SetSetupDialog(TRUE);
+ printerDialog.ShowModal();
- orientation = printerDialog.GetPrintData().GetOrientation();
+ orientation = printerDialog.GetPrintData().GetOrientation();
}
void MyFrame::OnPageSetupPS(wxCommandEvent& WXUNUSED(event))
{
- wxGetApp().SetPrintMode(wxPRINT_POSTSCRIPT);
+ wxGetApp().SetPrintMode(wxPRINT_POSTSCRIPT);
- wxPageSetupData data;
- data.SetOrientation(orientation);
+ wxPageSetupData data;
+ data.SetOrientation(orientation);
- wxGenericPageSetupDialog pageSetupDialog(this, & data);
- pageSetupDialog.ShowModal();
+ wxGenericPageSetupDialog pageSetupDialog(this, & data);
+ pageSetupDialog.ShowModal();
- orientation = pageSetupDialog.GetPageSetupData().GetOrientation();
+ orientation = pageSetupDialog.GetPageSetupData().GetOrientation();
}
public:
MyFrame(void);
- void Edit(void);
- void AddSampleText(wxLayoutList &llist);
+ void AddSampleText(wxLayoutList *llist);
void Clear(void);
void OnCommand( wxCommandEvent &event );
/*-*- c++ -*-********************************************************
* wxllist: wxLayoutList, a layout engine for text and graphics *
* *
- * (C) 1998 by Karsten Ballüder (Ballueder@usa.net) *
+ * (C) 1998-1999 by Karsten Ballüder (Ballueder@usa.net) *
* *
* $Id$
*******************************************************************/
/*
- - each Object knows its size and how to draw itself
- - the list is responsible for calculating positions
- - the draw coordinates for each object are the top left corner
- - coordinates only get calculated when things get redrawn
- - The cursor position is the position before an object, i.e. if the
- buffer starts with a text-object, cursor 0,0 is just before the
- first character. For all non-text objects, the cursor positions
- are 0==before or 1==behind. So that all non-text objects count as
- one cursor position.
- - Linebreaks are at the end of a line, that is a line like "abc\n"
- is four cursor positions long. This makes sure that cursor
- positions are "as expected", i.e. in "abc\ndef" the 'd' would be
- at positions (x=0,y=1).
-
-
- The redrawing of the cursor no longer erases it at the last
- position, because the list gets redrawn anyway.
-*/
-
-/*
- TODO:
-
- - blinking cursor
- - mouse click positions cursor
- - selection (SetMark(), GetSelection())
- - DND acceptance of text / clipboard support
- - wxlwindow: formatting menu: problem with checked/unchecked consistency gtk bug?
-*/
-
+
+ */
#ifdef __GNUG__
#pragma implementation "wxllist.h"
# include <wx/log.h>
#endif
-#define BASELINESTRETCH 12
+#include <ctype.h>
-// This should never really get created
+/// This should never really get created
#define WXLLIST_TEMPFILE "__wxllist.tmp"
#ifdef WXLAYOUT_DEBUG
-static const char *g_aTypeStrings[] =
-{
- "invalid", "text", "cmd", "icon", "linebreak"
-};
-
-# define wxLayoutDebug wxLogDebug
-# define WXL_VAR(x) cerr << #x " = " << x << endl;
-# define WXL_DBG_POINT(p) wxLayoutDebug(#p ": (%d, %d)", p.x, p.y)
-# define WXL_TRACE(f) wxLayoutDebug(#f ": ")
-# define TypeString(t) g_aTypeStrings[t]
-void
-wxLayoutObjectBase::Debug(void)
-{
- CoordType bl = 0;
- wxLayoutDebug("%s: size = %dx%d, pos=%d,%d, bl = %d",
- TypeString(GetType()), GetSize(&bl).x,
- GetSize(&bl).y,
- GetPosition().x, GetPosition().y, bl);
-}
+# define TypewxString(t) g_aTypewxStrings[t]
+# define WXLO_DEBUG(x) wxLogDebug x
+ static const char *g_aTypewxStrings[] =
+ {
+ "invalid", "text", "cmd", "icon"
+ };
+ void
+ wxLayoutObject::Debug(void)
+ {
+ WXLO_DEBUG(("%s",g_aTypewxStrings[GetType()]));
+ }
#else
-# define WXL_VAR(x)
-# define WXL_DBG_POINT(p)
-# define WXL_TRACE(f)
-# define ShowCurrentObject()
-# define TypeString(t) ""
-inline void wxLayoutDebug(const char *, ...) { }
+# define TypewxString(t) ""
+# define WXLO_DEBUG(x)
#endif
-//-------------------------- wxLayoutObjectText
+/// Cursors smaller than this disappear in XOR drawing mode
+#define WXLO_MINIMUM_CURSOR_WIDTH 4
+
+/// Use this character to estimate a cursor size when none is available.
+#define WXLO_CURSORCHAR "E"
+
+/// Helper function, allows me to compare to wxPoints
+bool operator ==(wxPoint const &p1, wxPoint const &p2)
+{
+ return p1.x == p2.x && p1.y == p2.y;
+}
+
+/// Helper function, allows me to compare to wxPoints
+bool operator !=(wxPoint const &p1, wxPoint const &p2)
+{
+ return p1.x != p2.x || p1.y != p2.y;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ wxLayoutObjectText
-wxLayoutObjectText::wxLayoutObjectText(const String &txt)
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+wxLayoutObjectText::wxLayoutObjectText(const wxString &txt)
{
m_Text = txt;
m_Width = 0;
m_Height = 0;
- m_Position = wxPoint(-1,-1);
+ m_Top = 0;
+ m_Bottom = 0;
}
wxPoint
-wxLayoutObjectText::GetSize(CoordType *baseLine) const
+wxLayoutObjectText::GetSize(CoordType *top, CoordType *bottom) const
{
- if(baseLine) *baseLine = m_BaseLine;
+
+ *top = m_Top; *bottom = m_Bottom;
return wxPoint(m_Width, m_Height);
}
void
-wxLayoutObjectText::Draw(wxDC &dc, wxPoint const &translate)
+wxLayoutObjectText::Draw(wxDC &dc, wxPoint const &coords)
{
- dc.DrawText(Str(m_Text), m_Position.x + translate.x, m_Position.y+translate.y);
- m_IsDirty = false;
+ dc.DrawText(m_Text, coords.x, coords.y-m_Top);
}
void
-wxLayoutObjectText::Layout(wxDC &dc, wxPoint position, CoordType baseLine)
+wxLayoutObjectText::Layout(wxDC &dc)
{
long descent = 0l;
- if(m_Position.x != position.x || m_Position.y != position.y)
- m_IsDirty = true;
-
- m_Position = position;
- dc.GetTextExtent(Str(m_Text),&m_Width, &m_Height, &descent);
- m_BaseLine = m_Height - descent;
- if(m_Position.x != position.x || m_Position.y != position.y)
- m_IsDirty = true;
+ dc.GetTextExtent(m_Text,&m_Width, &m_Height, &descent);
+ m_Bottom = descent;
+ m_Top = m_Height - m_Bottom;
}
#ifdef WXLAYOUT_DEBUG
void
wxLayoutObjectText::Debug(void)
{
- wxLayoutObjectBase::Debug();
- wxLayoutDebug(" `%s`", m_Text.c_str());
+ wxLayoutObject::Debug();
+ WXLO_DEBUG((" `%s`", m_Text.c_str()));
}
#endif
-//-------------------------- wxLayoutObjectIcon
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ wxLayoutObjectIcon
-wxLayoutObjectIcon::wxLayoutObjectIcon(wxIcon const &icon)
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+wxLayoutObjectIcon::wxLayoutObjectIcon(wxBitmap const &icon)
{
- m_Position = wxPoint(-1,-1);
- m_Icon = new wxIcon(icon);
+ m_Icon = new wxBitmap(icon);
}
-wxLayoutObjectIcon::wxLayoutObjectIcon(wxIcon *icon)
+wxLayoutObjectIcon::wxLayoutObjectIcon(wxBitmap *icon)
{
m_Icon = icon;
}
void
-wxLayoutObjectIcon::Draw(wxDC &dc, wxPoint const &translate)
+wxLayoutObjectIcon::Draw(wxDC &dc, wxPoint const &coords)
{
- dc.DrawIcon(*m_Icon,m_Position.x+translate.x, m_Position.y+translate.y);
+ dc.DrawBitmap(*m_Icon, coords.x, coords.y-m_Icon->GetHeight());
}
void
-wxLayoutObjectIcon::Layout(wxDC &dc, wxPoint position, CoordType baseLine)
+wxLayoutObjectIcon::Layout(wxDC & /* dc */)
{
- if(m_Position.x != position.x || m_Position.y != position.y)
- m_IsDirty = true;
- m_Position = position;
}
wxPoint
-wxLayoutObjectIcon::GetSize(CoordType *baseLine) const
+wxLayoutObjectIcon::GetSize(CoordType *top, CoordType *bottom) const
{
- if(baseLine) *baseLine = m_Icon->GetHeight();
+ *top = m_Icon->GetHeight();
+ *bottom = 0;
return wxPoint(m_Icon->GetWidth(), m_Icon->GetHeight());
}
-//-------------------------- wxLayoutObjectCmd
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ wxLayoutObjectIcon
+
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
wxLayoutObjectCmd::wxLayoutObjectCmd(int size, int family, int style, int
weight, bool underline,
wxColour const *fg, wxColour const *bg)
delete m_font;
}
-wxLayoutStyleInfo *
-wxLayoutObjectCmd::GetStyle(void) const
+void
+wxLayoutObjectCmd::GetStyle(wxLayoutStyleInfo *si) const
{
- wxLayoutStyleInfo *si = new wxLayoutStyleInfo();
-
-
si->size = m_font->GetPointSize();
si->family = m_font->GetFamily();
si->style = m_font->GetStyle();
si->bg_red = m_ColourBG->Red();
si->bg_green = m_ColourBG->Green();
si->bg_blue = m_ColourBG->Blue();
-
- return si;
}
void
-wxLayoutObjectCmd::Draw(wxDC &dc, wxPoint const &translate)
+wxLayoutObjectCmd::Draw(wxDC &dc, wxPoint const & /* coords */)
{
wxASSERT(m_font);
dc.SetFont(*m_font);
- if(m_ColourFG)
- dc.SetTextForeground(*m_ColourFG);
- if(m_ColourBG)
- dc.SetTextBackground(*m_ColourBG);
+ if(m_ColourFG) dc.SetTextForeground(*m_ColourFG);
+ if(m_ColourBG) dc.SetTextBackground(*m_ColourBG);
}
+
void
-wxLayoutObjectCmd::Layout(wxDC &dc, wxPoint p, CoordType baseline)
+wxLayoutObjectCmd::Layout(wxDC &dc)
{
- m_Position = p; // required so we can find the right object for cursor
// this get called, so that recalculation uses right font sizes
- Draw(dc,wxPoint(0,0));
-}
-
-//-------------------------- wxLayoutList
-
-wxLayoutList::wxLayoutList()
-{
- m_DefaultSetting = NULL;
- m_WrapMargin = -1;
- m_Editable = FALSE;
- m_boldCursor = FALSE;
-
- Clear();
-}
-
-wxLayoutList::~wxLayoutList()
-{
- if(m_DefaultSetting)
- delete m_DefaultSetting;
- // no deletion of objects, they are owned by the list
+ Draw(dc, wxPoint(0,0));
}
-void
-wxLayoutList::LineBreak(void)
-{
- Insert(new wxLayoutObjectLineBreak);
-}
-void
-wxLayoutList::SetFont(int family, int size, int style, int weight,
- int underline, wxColour const *fg,
- wxColour const *bg)
-{
- if(family != -1) m_FontFamily = family;
- if(size != -1) m_FontPtSize = size;
- if(style != -1) m_FontStyle = style;
- if(weight != -1) m_FontWeight = weight;
- if(underline != -1) m_FontUnderline = underline != 0;
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- if(fg != NULL) m_ColourFG = fg;
- if(bg != NULL) m_ColourBG = bg;
-
- Insert(
- new wxLayoutObjectCmd(m_FontPtSize,m_FontFamily,m_FontStyle,m_FontWeight,m_FontUnderline,
- m_ColourFG, m_ColourBG));
-}
+ The wxLayoutLine object
-void
-wxLayoutList::SetFont(int family, int size, int style, int weight,
- int underline, char const *fg, char const *bg)
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+wxLayoutLine::wxLayoutLine(wxLayoutLine *prev)
{
- wxColour const
- * cfg = NULL,
- * cbg = NULL;
-
- if( fg )
- cfg = wxTheColourDatabase->FindColour(fg);
- if( bg )
- cbg = wxTheColourDatabase->FindColour(bg);
-
- SetFont(family,size,style,weight,underline,cfg,cbg);
+ m_LineNumber = 0;
+ m_Height = 0;
+ m_Length = 0;
+ m_Dirty = true;
+ m_Previous = prev;
+ m_Next = NULL;
+ RecalculatePosition();
+ if(m_Previous)
+ {
+ m_LineNumber = m_Previous->GetLineNumber()+1;
+ m_Next = m_Previous->GetNextLine();
+ m_Previous->m_Next = this;
+ m_Height = m_Previous->GetHeight();
+ }
+ if(m_Next)
+ {
+ m_Next->m_Previous = this;
+ m_Next->MoveLines(+1);
+ m_Next->RecalculatePositions(1);
+ }
}
-
-/// for access by wxLayoutWindow:
-void
-wxLayoutList::GetSize(CoordType *max_x, CoordType *max_y,
- CoordType *lineHeight)
+wxLayoutLine::~wxLayoutLine()
{
-
- if(max_x) *max_x = m_MaxX;
- if(max_y) *max_y = m_MaxY;
- if(lineHeight) *lineHeight = m_LineHeight;
+ // kbList cleans itself
}
-void
-wxLayoutList::ResetSettings(wxDC &dc)
+wxPoint
+wxLayoutLine::RecalculatePosition(void)
{
- // setting up the default:
- dc.SetTextForeground( *wxBLACK );
- dc.SetTextBackground( *wxWHITE );
- dc.SetBackgroundMode( wxSOLID ); // to enable setting of text background
- dc.SetFont( *wxNORMAL_FONT );
- if(m_DefaultSetting)
- m_DefaultSetting->Draw(dc,wxPoint(0,0));
+ if(m_Previous)
+ m_Position = m_Previous->RecalculatePosition() +
+ wxPoint(0,m_Previous->GetHeight());
+ else
+ m_Position = wxPoint(0,0);
+ return m_Position;
}
void
-wxLayoutList::Layout(wxDC &dc, wxLayoutMargins *margins)
+wxLayoutLine::RecalculatePositions(int recurse)
{
- iterator i;
+ wxPoint pos = RecalculatePosition();
- // first object in current line
- wxLayoutObjectList::iterator headOfLine;
- // where we draw next
- wxPoint position, position_HeadOfLine;
- // size of last object
- wxPoint size;
- CoordType baseLine = m_FontPtSize;
- CoordType baseLineSkip = (BASELINESTRETCH * baseLine)/10;
- CoordType objBaseLine = baseLine;
- wxLayoutObjectType type;
-
- // we need to count cursor positions
- wxPoint cursorPos = wxPoint(0,0);
-
- if(margins)
+ if(pos != m_Position)
{
- position.y = margins->top;
- position.x = margins->left;
+ m_Position = pos;
+ if(m_Next) m_Next->RecalculatePositions(--recurse);
}
else
{
- position.y = 0;
- position.x = 0;
+ m_Position = pos;
+ if(recurse && m_Next)
+ m_Next->RecalculatePositions(--recurse);
}
-
- ResetSettings(dc);
-
- i = begin();
- headOfLine = i;
- position_HeadOfLine = position;
+
+}
- do
- {
- if(i == end())
- return;
-
- type = (*i)->GetType();
- (*i)->Layout(dc, position, baseLine);
- size = (*i)->GetSize(&objBaseLine);
- // calculate next object's position:
- position.x += size.x;
+wxLayoutObjectList::iterator
+wxLayoutLine::FindObject(CoordType xpos, CoordType *offset) const
+{
+ wxASSERT(xpos >= 0);
+ wxASSERT(offset);
+ wxLayoutObjectList::iterator i;
+ CoordType x = 0, len;
- // do we need to increase the line's height?
- if(size.y > baseLineSkip)
+ for(i = m_ObjectList.begin(); i != NULLIT; i++)
+ {
+ len = (**i).GetLength();
+ if( x <= xpos && xpos <= x + len )
{
- baseLineSkip = size.y;
- i = headOfLine; position = position_HeadOfLine;
- continue;
+ *offset = xpos-x;
+ return i;
}
- if(objBaseLine > baseLine)
+ x += (**i).GetLength();
+ }
+ return NULLIT;
+}
+
+bool
+wxLayoutLine::Insert(CoordType xpos, wxLayoutObject *obj)
+{
+ wxASSERT(xpos >= 0);
+ wxASSERT(obj != NULL);
+ CoordType offset;
+ wxLOiterator i = FindObject(xpos, &offset);
+ if(i == NULLIT)
+ {
+ if(xpos == 0 ) // aha, empty line!
{
- baseLine = objBaseLine;
- i = headOfLine; position = position_HeadOfLine;
- continue;
+ m_ObjectList.push_back(obj);
+ m_Length += obj->GetLength();
+ return true;
}
+ else
+ return false;
+ }
- // when we reach here, the coordinates are valid, this part of
- // the loop gets run only once per object
- if(position.x > m_MaxX)
- m_MaxX = position.x;
- if(type == WXLO_TYPE_LINEBREAK)
+ CoordType len = (**i).GetLength();
+ if(offset == 0 /*&& i != m_ObjectList.begin()*/) // why?
+ { // insert before this object
+ m_ObjectList.insert(i,obj);
+ m_Length += obj->GetLength();
+ return true;
+ }
+ if(offset == len )
+ {
+ if( i == m_ObjectList.tail()) // last object?
{
- cursorPos.x = 0; cursorPos.y ++;
+ m_ObjectList.push_back(obj);
+ m_Length += obj->GetLength();
}
else
- cursorPos.x += (**i).CountPositions();
-
- // now check whether we have finished handling this line:
- if(type == WXLO_TYPE_LINEBREAK && i != tail())
- {
- position.x = margins ? margins->left : 0;
- position.y += baseLineSkip;
- baseLine = m_FontPtSize;
- objBaseLine = baseLine; // not all objects set it
- baseLineSkip = (BASELINESTRETCH * baseLine)/10;
- headOfLine = i;
- headOfLine++;
- position_HeadOfLine = position;
+ { // insert after current object
+ i++;
+ m_ObjectList.insert(i,obj);
+ m_Length += obj->GetLength();
}
- if(i == m_CursorObject)
- CalculateCursor(dc);
- i++;
+ return true;
}
- while(i != end());
- m_MaxY = position.y + baseLineSkip;
+ /* Otherwise we need to split the current object.
+ Fortunately this can only be a text object. */
+ wxASSERT((**i).GetType() == WXLO_TYPE_TEXT);
+ wxString left, right;
+ wxLayoutObjectText *tobj = (wxLayoutObjectText *) *i;
+ left = tobj->GetText().substr(0,offset);
+ right = tobj->GetText().substr(offset,len-offset);
+ // current text object gets set to right half
+ tobj->GetText() = right; // set new text
+ // before it we insert the new object
+ m_ObjectList.insert(i,obj);
+ m_Length += obj->GetLength();
+ // and before that we insert the left half
+ m_ObjectList.insert(i,new wxLayoutObjectText(left));
+ return true;
}
-
-void
-wxLayoutList::Draw(wxDC &dc,
- CoordType fromLine, CoordType toLine,
- iterator start,
- wxPoint const &translate)
-{
- //Layout(dc); // FIXME just for now
-
- ResetSettings(dc);
-
- wxLayoutObjectList::iterator i;
- if(start == iterator(NULL))
- start = begin();
- else // we need to restore font settings
- {
- for( i = begin() ; i != start; i++)
- if((**i).GetType() == WXLO_TYPE_CMD)
- (**i).Draw(dc,translate); // apply font settings
- }
-
- while( start != end() && (**start).GetPosition().y < fromLine)
+bool
+wxLayoutLine::Insert(CoordType xpos, wxString text)
+{
+ wxASSERT(xpos >= 0);
+ CoordType offset;
+ wxLOiterator i = FindObject(xpos, &offset);
+ if(i != NULLIT && (**i).GetType() == WXLO_TYPE_TEXT)
{
- if((**start).GetType() == WXLO_TYPE_CMD)
- (**start).Draw(dc,translate); // apply font settings
- start++;
+ wxLayoutObjectText *tobj = (wxLayoutObjectText *) *i;
+ tobj->GetText().insert(offset, text);
+ m_Length += text.Length();
}
- for( i = start ;
- i != end() && (toLine == -1 || (**i).GetPosition().y < toLine) ;
- i++ )
- (*i)->Draw(dc,translate);
+ else
+ return Insert(xpos, new wxLayoutObjectText(text));
}
-/** Erase at least to end of line */
-void
-wxLayoutList::EraseAndDraw(wxDC &dc, iterator start, wxPoint const &translate)
+CoordType
+wxLayoutLine::Delete(CoordType xpos, CoordType npos)
{
- //look for begin of line
- while(start != end() && start != begin() && (**start).GetType() !=
- WXLO_TYPE_LINEBREAK)
- start--;
- if(start == iterator(NULL))
- start = begin();
- if(start == iterator(NULL))
- return;
-
- wxPoint p = (**start).GetPosition();
+ CoordType offset;
- //FIXME: wxGTK: MaxX()/MaxY() broken
- //WXL_VAR(dc.MaxX()); WXL_VAR(dc.MaxY());
-
- dc.SetBrush(wxBrush(*m_ColourBG, wxSOLID));
- dc.SetPen(wxPen(*m_ColourBG,0,wxTRANSPARENT));
- dc.DrawRectangle(p.x,p.y,2000,2000); //dc.MaxX(),dc.MaxY());
- Draw(dc,-1,-1,start,translate);
- //dc.DrawRectangle(p.x,p.y,2000,2000); //dc.MaxX(),dc.MaxY());
+ wxASSERT(xpos >= 0);
+ wxASSERT(npos >= 0);
+ wxLOiterator i = FindObject(xpos, &offset);
+ while(npos > 0)
+ {
+ if(i == NULLIT) return false; // FIXME
+ // now delete from that object:
+ if((**i).GetType() != WXLO_TYPE_TEXT)
+ {
+ if(offset != 0) // at end of line after a non-text object
+ return npos;
+ // always len == 1:
+ m_Length -= (**i).GetLength();
+ npos -= m_Length;
+ m_ObjectList.erase(i);
+ }
+ else
+ {
+ // tidy up: remove empty text objects
+ if((**i).GetLength() == 0)
+ {
+ m_ObjectList.erase(i);
+ continue;
+ }
+ // Text object:
+ CoordType max = (**i).GetLength() - offset;
+ if(npos < max) max = npos;
+ if(max == 0)
+ {
+ if(xpos == GetLength())
+ return npos;
+ else
+ { // at the end of an object
+ // move to begin of next object:
+ i++; offset = 0;
+ continue; // start over
+ }
+ }
+ npos -= max;
+ m_Length -= max;
+ if(offset == 0 && max == (**i).GetLength())
+ m_ObjectList.erase(i); // remove the whole object
+ else
+ ((wxLayoutObjectText *)(*i))->GetText().Remove(offset,max);
+ }
+ }
+ return npos;
}
-
-void
-wxLayoutList::CalculateCursor(wxDC &dc)
+bool
+wxLayoutLine::DeleteWord(CoordType xpos)
{
- if(! m_CursorMoved)
- return;
-
- CoordType width, height, descent;
- CoordType baseLineSkip = 20; //FIXME
+ wxASSERT(xpos >= 0);
+ CoordType offset;
- int cursorWidth = m_boldCursor ? 4 : 2;
-
- if( m_CursorObject == iterator(NULL)) // empty list
- {
- m_CursorCoords = wxPoint(0,0);
- m_CursorSize = wxPoint(cursorWidth,baseLineSkip);
- m_CursorMoved = false; // coords are valid
- return;
- }
- wxLayoutObjectBase &obj = **m_CursorObject;
+ wxLOiterator i = FindObject(xpos, &offset);
- m_CursorCoords = obj.GetPosition();
- if(obj.GetType() == WXLO_TYPE_TEXT)
- {
- wxLayoutObjectText *tobj = (wxLayoutObjectText *)&obj;
- String & str = tobj->GetText();
- String sstr = str.substr(0,m_CursorOffset);
- dc.GetTextExtent(sstr,&width,&height,&descent);
- m_CursorCoords = wxPoint(m_CursorCoords.x+width,
- m_CursorCoords.y);
- m_CursorSize = wxPoint(cursorWidth,height);
- }
- else if(obj.GetType() == WXLO_TYPE_LINEBREAK)
+ for(;;)
{
- if(m_CursorOffset == 1) // behind linebreak
- m_CursorCoords = wxPoint(0, m_CursorCoords.y + baseLineSkip);
- //m_CursorCoords = wxPoint(0, m_CursorCoords.y);
- m_CursorSize = wxPoint(cursorWidth,baseLineSkip);
+ if(i == NULLIT) return false;
+ if((**i).GetType() != WXLO_TYPE_TEXT)
+ {
+ // This should only happen when at end of line, behind a non-text
+ // object:
+ if(offset == (**i).GetLength()) return false;
+ m_Length -= (**i).GetLength(); // -1
+ m_ObjectList.erase(i);
+ return true; // we are done
+ }
+ else
+ { // text object:
+ if(offset == (**i).GetLength()) // at end of object
+ {
+ i++; offset = 0;
+ continue;
+ }
+ wxLayoutObjectText *tobj = (wxLayoutObjectText *)*i;
+ size_t count = 0;
+ wxString str = tobj->GetText();
+ str = str.substr(offset,str.Length()-offset);
+ // Find out how many positions we need to delete:
+ // 1. eat leading space
+ while(isspace(str[count])) count++;
+ // 2. eat the word itself:
+ while(isalnum(str[count])) count++;
+ // now delete it:
+ wxASSERT(count+offset <= (size_t) (**i).GetLength());
+ ((wxLayoutObjectText *)*i)->GetText().erase(offset,count);
+ m_Length -= count;
+ return true;
+ }
}
- else
+ wxASSERT(0); // we should never arrive here
+}
+
+wxLayoutLine *
+wxLayoutLine::DeleteLine(bool update)
+{
+ if(m_Next) m_Next->m_Previous = m_Previous;
+ if(m_Previous) m_Previous->m_Next = m_Next;
+ if(update)
{
- // this is not necessarily the most "beautiful" solution:
- //cursorPosition = wxPoint(position.x, position.y);
- //cursorSize = wxPoint(size.x > 0 ? size.x : 1,size.y > 0 ? size.y : baseLineSkip);
- m_CursorCoords = wxPoint(m_CursorCoords.x+obj.GetSize().x, m_CursorCoords.y);
- m_CursorSize = wxPoint(cursorWidth, obj.GetSize().y);
- if(m_CursorSize.y < 1) m_CursorSize.y = baseLineSkip;
+ m_Next->MoveLines(-1);
+ m_Next->RecalculatePositions(1);
}
- m_CursorMoved = false; // coords are valid
+ wxLayoutLine *next = m_Next;
+ delete this;
+ return next;
}
void
-wxLayoutList::DrawCursor(wxDC &dc, bool erase, wxPoint const &translate)
+wxLayoutLine::Draw(wxDC &dc, const wxPoint & offset) const
{
- if(! m_Editable)
- return;
+ wxLayoutObjectList::iterator i;
+ wxPoint pos = offset;
+ pos = pos + GetPosition();
- if(erase)
- ;
-#if 0
- dc.Blit(m_CursorCoords.x+translate.x,
- m_CursorCoords.y+translate.y,
- m_CursorSize.x,m_CursorSize.y,
- &m_CursorMemDC,
- 0, 0, 0, 0);
-#endif
- else
+ pos.y += m_BaseLine;
+
+ for(i = m_ObjectList.begin(); i != NULLIT; i++)
{
- // erase it at the old position:
- if(IsDirty() || CursorMoved())
- {
- // We don't need to erase the cursor because the screen gets
- // redrawn completely.
-// DrawCursor(dc,true);
- // this is needed to update the cursor coordinates
- Layout(dc);
- }
-#if 0
-// Save background:
- wxBitmap bm(m_CursorSize.x+1,m_CursorSize.y+1);
- m_CursorMemDC.SelectObject(bm);
- m_CursorMemDC.Blit(0, 0,
- m_CursorSize.x, m_CursorSize.y,
- &dc,
- m_CursorCoords.x+translate.x,
- m_CursorCoords.y+translate.y, 0, 0);
-#endif
- // draw it:
- dc.SetBrush(*wxBLACK_BRUSH);
- dc.SetPen(wxPen(*wxBLACK,1,wxSOLID));
- dc.DrawRectangle(m_CursorCoords.x+translate.x, m_CursorCoords.y+translate.y,
- m_CursorSize.x, m_CursorSize.y);
+ (**i).Draw(dc, pos);
+ pos.x += (**i).GetWidth();
}
}
-
-
-
-
-
-
-#ifdef WXLAYOUT_DEBUG
void
-wxLayoutList::Debug(void)
+wxLayoutLine::Layout(wxDC &dc, wxPoint *cursorPos, wxPoint
+ *cursorSize,
+ int cx)
{
wxLayoutObjectList::iterator i;
- wxLayoutDebug("------------------------ debug start ------------------------");
- for(i = begin(); i != end(); i++)
- (*i)->Debug();
- wxLayoutDebug("-------------------------- list end -------------------------");
-
- // show current object:
- ShowCurrentObject();
- wxLayoutDebug("------------------------- debug end -------------------------");
-}
+ CoordType
+ oldHeight = m_Height;
+ CoordType
+ topHeight, bottomHeight; // above and below baseline
+ CoordType
+ objHeight = 0,
+ objTopHeight, objBottomHeight;
+ CoordType
+ len, count = 0;
+ m_Height = 0; m_BaseLine = 0;
+ m_Width = 0;
+ topHeight = 0; bottomHeight = 0;
+ wxPoint size;
+ bool cursorFound = false;
-void
-wxLayoutList::ShowCurrentObject()
-{
- wxLayoutDebug("CursorPos (%d, %d)", (int) m_CursorPos.x, (int) m_CursorPos.y);
- wxLayoutDebug("CursorOffset = %d", (int) m_CursorOffset);
- wxLayoutDebug("CursorObject = %p", m_CursorObject);
- if(m_CursorObject == iterator(NULL))
- wxLayoutDebug("<<no object found>>");
- else
+ if(cursorPos)
{
- if((*m_CursorObject)->GetType() == WXLO_TYPE_TEXT)
- wxLayoutDebug(" \"%s\", offs: %d",
- ((wxLayoutObjectText *)(*m_CursorObject))->GetText().c_str(),
- m_CursorOffset);
- else
- wxLayoutDebug(" %s", TypeString((*m_CursorObject)->GetType()));
+ *cursorPos = m_Position;
}
- wxLayoutDebug("Line length: %d", GetLineLength(m_CursorObject));
-
-}
-
-#endif
-
-/******************** editing stuff ********************/
-
-// don't change this, I know how to optimise this and will do it real
-// soon (KB)
-
-/*
- * FindObjectCursor:
- * Finds the object belonging to a given cursor position cpos and
- * returns an iterator to that object and stores the relative cursor
- * position in offset.
- *
- * For linebreaks, the offset can be 0=before or 1=after.
- *
- * If the cpos coordinates don't exist, they are modified.
- */
-
-wxLayoutObjectList::iterator
-wxLayoutList::FindObjectCursor(wxPoint *cpos, CoordType *offset)
-{
- wxPoint object = wxPoint(0,0); // runs along the objects
- CoordType width = 0;
- wxLayoutObjectList::iterator i, begin_it;
- int go_up;
-//#ifdef WXLAYOUT_DEBUG
-// wxLayoutDebug("Looking for object at (%d, %d)", cpos->x, cpos->y);
-//#endif
-
- // optimisation: compare to last looked at object:
- if(cpos->y > m_FoundCursor.y || (cpos->y == m_FoundCursor.y &&
- cpos->x >= m_FoundCursor.x))
- go_up = 1;
- else
- go_up = 0;
-
- //broken at the moment
- //begin_it = m_FoundIterator;
- //m_FoundCursor = *cpos;
- begin_it = begin();
- go_up = 1;
- for(i = begin_it; i != end() && object.y <= cpos->y; )
+ for(i = m_ObjectList.begin(); i != NULLIT; i++)
{
- width = (**i).CountPositions();
- if(cpos->y == object.y) // a possible candidate
- {
- if((**i).GetType() ==WXLO_TYPE_LINEBREAK)
+ (**i).Layout(dc);
+ size = (**i).GetSize(&objTopHeight, &objBottomHeight);
+
+ if(cursorPos && ! cursorFound)
+ { // we need to check whether the text cursor is here
+ len = (**i).GetLength();
+ if(count <= cx && count+len > cx)
{
- if(cpos->x == object.x)
+ if((**i).GetType() == WXLO_TYPE_TEXT)
{
- if(offset) *offset = 0;
- return m_FoundIterator = i;
+ len = cx - count; // pos in object
+ CoordType width, height, descent;
+ dc.GetTextExtent((*(wxLayoutObjectText*)*i).GetText().substr(0,len),
+ &width, &height, &descent);
+ cursorPos->x += width;
+ cursorPos->y = m_Position.y;
+ wxString str;
+ if(len < (**i).GetLength())
+ str = (*(wxLayoutObjectText*)*i).GetText().substr(len,1);
+ else
+ str = WXLO_CURSORCHAR;
+ dc.GetTextExtent(str, &width, &height, &descent);
+ wxASSERT(cursorSize);
+ // Just in case some joker inserted an empty string object:
+ if(width == 0) width = WXLO_MINIMUM_CURSOR_WIDTH;
+ if(height == 0) height = objHeight;
+ cursorSize->x = width;
+ cursorSize->y = height;
+ cursorFound = true; // no more checks
+ }
+ else
+ { // on some other object
+ CoordType top, bottom; // unused
+ *cursorSize = (**i).GetSize(&top,&bottom);
+ cursorPos->y = m_Position.y;
+ cursorFound = true; // no more checks
}
- if(offset) *offset=1;
- cpos->x = object.x;
- return m_FoundIterator = i;
}
- if(cpos->x >= object.x && cpos->x <= object.x+width) // overlap
+ else
{
- if(offset) *offset = cpos->x-object.x;
-//#ifdef WXLAYOUT_DEBUG
-// wxLayoutDebug(" found object at (%d, %d), type: %s",
-// object.x, object.y, TypeString((*i)->GetType()));
-//#endif
- return m_FoundIterator = i;
+ count += len;
+ cursorPos->x += (**i).GetWidth();
}
- }
- // no overlap, increment coordinates
- object.x += width;
- if((**i).GetType() == WXLO_TYPE_LINEBREAK)
+ } // cursor finding
+ objHeight = size.y;
+ m_Width += size.x;
+ if(objHeight > m_Height) m_Height = objHeight;
+ if(objTopHeight > topHeight) topHeight = objTopHeight;
+ if(objBottomHeight > bottomHeight) bottomHeight = objBottomHeight;
+ }
+ if(topHeight + bottomHeight > m_Height) m_Height =
+ topHeight+bottomHeight;
+ m_BaseLine = topHeight;
+
+ if(m_Height == 0)
+ {
+ if(GetPreviousLine()) // empty line
{
- object.x = 0;
- object.y++;
+ m_Height = GetPreviousLine()->GetHeight();
+ m_BaseLine = GetPreviousLine()->m_BaseLine;
}
- if(go_up)
- i++;
else
- i--;
- }//for
-//#ifdef WXLAYOUT_DEBUG
-// wxLayoutDebug(" not found");
-//#endif
-// return last object, coordinates of that one:
- i = tail();
- if(i == end())
- return m_FoundIterator = i;
- if((**i).GetType()==WXLO_TYPE_LINEBREAK)
- {
- if(offset)
- *offset = 1;
- return m_FoundIterator = i;
+ {
+ CoordType width, height, descent;
+ dc.GetTextExtent(WXLO_CURSORCHAR, &width, &height, &descent);
+ m_Height = height;
+ m_BaseLine = m_Height - descent;
+ }
}
- cpos->x = object.x; // would be the coordinate of next object
- cpos->y = object.y;
- cpos->x += width; // last object's width
- if(*offset) *offset = cpos->x-object.x;
- return m_FoundIterator = i; // not found
-}
-
-bool
-wxLayoutList::MoveCursor(int dx, int dy)
-{
- CoordType diff;
- m_CursorMoved = true;
- enum { up, down} direction;
-
- wxPoint newPos = wxPoint(m_CursorPos.x + dx,
- m_CursorPos.y + dy);
-
- // check for bounds
- //if(newPos.x < 0) newPos.x = 0;
- if(newPos.y < 0) newPos.y = 0;
- else if(newPos.y > m_MaxLine) newPos.y = m_MaxLine;
-
- //FIXME: quick and dirty hack: as last object in buffer should be a
- // linebreak, we don't allow to go there
- if(newPos.y >= m_MaxLine)
- return false;
+ // tell next line about coordinate change
+ if(m_Next && objHeight != oldHeight)
+ m_Next->RecalculatePositions();
- if(newPos.y > m_CursorPos.y ||
- newPos.y == m_CursorPos.y &&
- newPos.x >= m_CursorPos.x)
- direction = down;
- else
- direction = up;
-
- if ( !m_CursorObject )
- {
- // list is empty
- return FALSE;
- }
-
- // now move cursor forwards until at the new position:
-
- // first, go to the right line:
- while(newPos.y != m_CursorPos.y)
+ if(cursorPos)
{
- if(direction == down)
+ // this might be the case if the cursor is at the end of the
+ // line or on a command object:
+ if(cursorSize->y < WXLO_MINIMUM_CURSOR_WIDTH)
{
- m_CursorPos.x +=
- (**m_CursorObject).CountPositions() - m_CursorOffset;
- if(m_CursorObject == tail())
- break; // can't go any further
- if((**m_CursorObject).GetType() == WXLO_TYPE_LINEBREAK
- && m_CursorOffset == 0)
+ if(m_BaseLine > 0)
{
- m_CursorPos.y++; m_CursorPos.x = 0;
+ cursorSize->y = m_BaseLine;
+ if(cursorSize->x < WXLO_MINIMUM_CURSOR_WIDTH) cursorSize->x = WXLO_MINIMUM_CURSOR_WIDTH;
}
- m_CursorObject ++; m_CursorOffset = 0;
- }
- else // up
- {
- if(m_CursorObject == begin())
- break; // can't go any further
-
- if((**m_CursorObject).GetType() == WXLO_TYPE_LINEBREAK &&
- m_CursorOffset == 1)
+ else // empty line
{
- m_CursorPos.y--;
- m_CursorPos.x = GetLineLength(m_CursorObject);
+ CoordType width, height, descent;
+ dc.GetTextExtent(WXLO_CURSORCHAR, &width, &height, &descent);
+ cursorSize->x = width;
+ cursorSize->y = height;
}
- m_CursorPos.x -= m_CursorOffset;
- m_CursorObject --; m_CursorOffset = (**m_CursorObject).CountPositions();
}
+ if(m_BaseLine >= cursorSize->y) // the normal case anyway
+ cursorPos->y += m_BaseLine-cursorSize->y;
}
- if(newPos.y != m_CursorPos.y) // reached begin/end of list,
- newPos.y = m_CursorPos.y; // exited by break
-
- // now line is right, go to right column:
- if(dx == 0) // we are moving up or down only
+}
+
+wxLayoutObject *
+wxLayoutLine::FindObject(CoordType xpos)
+{
+ wxASSERT(xpos >= 0);
+ if(xpos > GetWidth()) return NULL;
+
+ CoordType x = 0;
+ for(wxLOiterator i = m_ObjectList.begin(); i != NULLIT; i++)
{
- int max_x = GetLineLength(m_CursorObject);
- if(max_x <= newPos.x) // ... so we don't want to cross linebreaks
- newPos.x = max_x-1; // but just go to the right column
+ x += (**i).GetWidth();
+ if(x > xpos) // we just crossed it
+ return *i;
+ }
+ return NULL;
+}
+
+wxLayoutLine *
+wxLayoutLine::Break(CoordType xpos)
+{
+ wxASSERT(xpos >= 0);
+
+ if(xpos == 0)
+ { // insert an empty line before this one
+ wxLayoutLine *prev = new wxLayoutLine(m_Previous);
+ if(m_Previous == NULL)
+ { // We were in first line, need to link in new empty line
+ // before this.
+ prev->m_Next = this;
+ m_Previous = prev;
+ m_Previous->m_Height = GetHeight(); // this is a wild guess
+ }
+ MoveLines(+1);
+ if(m_Next)
+ m_Next->RecalculatePositions(1);
+ return this;
}
- direction = newPos.x >= m_CursorPos.x ? down : up;
- while(newPos.x != m_CursorPos.x)
+
+ CoordType offset;
+ wxLOiterator i = FindObject(xpos, &offset);
+ if(i == NULLIT)
+ // must be at the end of the line then
+ return new wxLayoutLine(this);
+ // split this line:
+
+ wxLayoutLine *newLine = new wxLayoutLine(this);
+ // split object at i:
+ if((**i).GetType() == WXLO_TYPE_TEXT && offset != 0)
{
- if(direction == down)
- {
- diff = newPos.x - m_CursorPos.x;
- if(diff > (**m_CursorObject).CountPositions()-m_CursorOffset)
- {
- m_CursorPos.x +=
- (**m_CursorObject).CountPositions()-m_CursorOffset;
- if((**m_CursorObject).GetType() == WXLO_TYPE_LINEBREAK &&
- m_CursorOffset == 0)
- m_CursorPos = wxPoint(0, m_CursorPos.y+1);
- if(m_CursorObject == tail())
- break; // cannot go further
- m_CursorObject++; m_CursorOffset = 0;
- }
- else
- {
- if((**m_CursorObject).GetType() == WXLO_TYPE_LINEBREAK)
- {
- newPos.y++; newPos.x -= m_CursorPos.x+1;
- m_CursorPos = wxPoint(0,m_CursorPos.y+1);
- }
- else
- m_CursorPos.x += diff;
- m_CursorOffset += diff;
- }
- }
- else // up
- {
- if(m_CursorPos.x == 0 && m_CursorOffset == 1 &&
- (**m_CursorObject).GetType() == WXLO_TYPE_LINEBREAK) // can we go further up?
- {
- m_CursorPos.y--;
- newPos.y--;
- m_CursorOffset = 0;
- m_CursorPos.x = GetLineLength(m_CursorObject)-1;
- newPos.x += m_CursorPos.x+1;
- continue;
- }
- diff = m_CursorPos.x - newPos.x;
- if(diff >= m_CursorOffset)
- {
- if(m_CursorObject == begin())
- {
- m_CursorOffset = 0;
- m_CursorPos.x = 0;
- break; // cannot go further
- }
- m_CursorObject--;
- m_CursorPos.x -= m_CursorOffset;
- m_CursorOffset = (**m_CursorObject).CountPositions();
- }
- else
- {
- m_CursorPos.x -= diff;
- m_CursorOffset -= diff;
- }
- }
+ wxString left, right;
+ wxLayoutObjectText *tobj = (wxLayoutObjectText *) *i;
+ left = tobj->GetText().substr(0,offset);
+ right = tobj->GetText().substr(offset,tobj->GetLength()-offset);
+ // current text object gets set to left half
+ tobj->GetText() = left; // set new text
+ newLine->Append(new wxLayoutObjectText(right));
+ m_Length -= m_Length - offset;
+ i++; // don't move this object to the new list
}
+ else
+ if(offset > 0)
+ i++; // move objects from here to new list
- return true; // FIXME: when return what?
+ while(i != m_ObjectList.end())
+ {
+ newLine->Append(*i);
+ m_Length -= (**i).GetLength();
+ m_ObjectList.remove(i); // remove without deleting it
+ }
+ if(m_Next)
+ m_Next->RecalculatePositions(2);
+ return newLine;
}
+
+
void
-wxLayoutList::SetCursor(wxPoint const &p)
+wxLayoutLine::MergeNextLine(void)
{
- m_CursorPos = p;
- m_CursorObject = FindObjectCursor(&m_CursorPos, &m_CursorOffset);
- m_CursorMoved = true;
+ wxASSERT(GetNextLine());
+ wxLayoutObjectList &list = GetNextLine()->m_ObjectList;
+ wxLOiterator i;
+
+ for(i = list.begin(); i != list.end();)
+ {
+ Append(*i);
+ list.remove(i); // remove without deleting it
+ }
+ wxASSERT(list.empty());
+ wxLayoutLine *oldnext = GetNextLine();
+ SetNext(GetNextLine()->GetNextLine());
+ delete oldnext;
+ RecalculatePositions(1);
}
-void
-wxLayoutList::Delete(CoordType count)
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ The wxLayoutList object
+
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+wxLayoutList::wxLayoutList()
+{
+ m_DefaultSetting = NULL;
+ m_FirstLine = NULL;
+ InternalClear();
+}
+
+wxLayoutList::~wxLayoutList()
{
- WXL_TRACE(Delete);
+ InternalClear();
+}
- if(!m_Editable)
- return;
+void
+wxLayoutList::InternalClear(void)
+{
+ while(m_FirstLine)
+ m_FirstLine = m_FirstLine->DeleteLine(false);
- m_bModified = true;
-
- CoordType offs = 0;
- wxLayoutObjectList::iterator i;
-
- do
+ if(m_DefaultSetting)
{
- i = m_CursorObject;
- startover: // ugly, but easiest way to do it
- if(i == end())
- return; // we cannot delete anything more
-
- /* Here we need to treat linebreaks differently.
- If m_CursorOffset==0 we are before the linebreak, otherwise behind. */
- if((*i)->GetType() == WXLO_TYPE_LINEBREAK)
- {
- if(m_CursorOffset == 0)
- {
- m_MaxLine--;
- erase(i);
- m_CursorObject = i; // new i!
- m_CursorOffset = 0; // Pos unchanged
- count--;
- continue; // we're done
- }
- else // delete the object behind the linebreak
- {
- i++; // we increment and continue as normal
- m_CursorOffset=0;
- goto startover;
- }
- }
- else if((*i)->GetType() == WXLO_TYPE_TEXT)
- {
- wxLayoutObjectText *tobj = (wxLayoutObjectText *)*i;
- CoordType len = tobj->CountPositions();
- /* If we find the end of a text object, this means that we
- have to delete from the object following it. */
- if(len == m_CursorOffset)
- {
- i++;
- m_CursorOffset = 0;
- goto startover;
- }
- else
- {
- if(m_CursorOffset == 0 && len <= count) // delete this object
- {
- count -= len;
- erase(i);
- m_CursorObject = i;
- m_CursorOffset = 0;
- continue;
- }
-
- int todelete = count;
- if(todelete > len-m_CursorOffset)
- todelete = len-m_CursorOffset;
-
- len = len - todelete;
- tobj->GetText().erase(m_CursorOffset,todelete);
- count -= todelete;
- // cursor unchanged
- return; // we are done
- }
- }
- else// all other objects: delete the object
-// this only works as expected if the non-text object has 0/1
-// as offset values. Not tested with "longer" objects.
- {
- CoordType len = (*i)->CountPositions();
- if(offs == 0)
- {
- count = count > len ? count -= len : 0;
- erase(i); // after this, i is the iterator for the
- // following object
- m_CursorObject = i;
- m_CursorOffset = 0;
- continue;
- }
- else // delete the following object
- {
- i++; // we increment and continue as normal
- m_CursorOffset=0;
- goto startover;
- }
- }
+ delete m_DefaultSetting;
+ m_DefaultSetting = NULL;
}
- while(count && i != end());
+
+ m_CursorPos = wxPoint(0,0);
+ m_CursorScreenPos = wxPoint(0,0);
+ m_CursorSize = wxPoint(0,0);
+ m_FirstLine = new wxLayoutLine(NULL); // empty first line
+ m_CursorLine = m_FirstLine;
}
+void
+wxLayoutList::SetFont(int family, int size, int style, int weight,
+ int underline, wxColour const *fg,
+ wxColour const *bg)
+{
+ if(family != -1) m_FontFamily = family;
+ if(size != -1) m_FontPtSize = size;
+ if(style != -1) m_FontStyle = style;
+ if(weight != -1) m_FontWeight = weight;
+ if(underline != -1) m_FontUnderline = underline != 0;
+
+ if(fg != NULL) m_ColourFG = fg;
+ if(bg != NULL) m_ColourBG = bg;
+
+ Insert(
+ new wxLayoutObjectCmd(m_FontPtSize,m_FontFamily,m_FontStyle,m_FontWeight,m_FontUnderline,
+ m_ColourFG, m_ColourBG));
+}
void
-wxLayoutList::Insert(wxLayoutObjectBase *obj)
+wxLayoutList::SetFont(int family, int size, int style, int weight,
+ int underline, char const *fg, char const *bg)
+
{
- wxCHECK_RET( obj, "no object to insert" );
+ wxColour const
+ * cfg = NULL,
+ * cbg = NULL;
- m_bModified = true;
+ if( fg )
+ cfg = wxTheColourDatabase->FindColour(fg);
+ if( bg )
+ cbg = wxTheColourDatabase->FindColour(bg);
+
+ SetFont(family,size,style,weight,underline,cfg,cbg);
+}
- wxLayoutObjectList::iterator i = m_CursorObject;
+void
+wxLayoutList::Clear(int family, int size, int style, int weight,
+ int /* underline */, char const *fg, char const *bg)
+{
+ InternalClear();
+
+ // set defaults
+ m_FontPtSize = size;
+ m_FontUnderline = false;
+ m_FontFamily = family;
+ m_FontStyle = style;
+ m_FontWeight = weight;
+ m_ColourFG = wxTheColourDatabase->FindColour(fg);
+ m_ColourBG = wxTheColourDatabase->FindColour(bg);
- if(i != iterator(NULL) && (*obj).GetType() == WXLO_TYPE_LINEBREAK)
- {
- m_CursorPos.x = 0; m_CursorPos.y ++;
- }
+ if(! m_ColourFG) m_ColourFG = wxBLACK;
+ if(! m_ColourBG) m_ColourBG = wxWHITE;
- if(i == end())
- {
- push_back(obj);
- m_CursorObject = tail();
- }
- else if(m_CursorOffset == 0)
+ if(m_DefaultSetting)
+ delete m_DefaultSetting;
+
+ m_DefaultSetting = new
+ wxLayoutObjectCmd(m_FontPtSize,m_FontFamily,m_FontStyle,
+ m_FontWeight,m_FontUnderline,
+ m_ColourFG, m_ColourBG);
+}
+
+
+
+bool
+wxLayoutList::MoveCursorTo(wxPoint const &p)
+{
+ wxLayoutLine *line = m_FirstLine;
+ while(line && line->GetLineNumber() != p.y)
+ ;
+ if(line && line->GetLineNumber() == p.y) // found it
{
- insert(i,obj);
- m_CursorObject = i;
+ m_CursorPos.y = p.y;
+ m_CursorLine = line;
+ CoordType len = line->GetLength();
+ if(len >= p.x)
+ {
+ m_CursorPos.x = p.x;
+ return true;
+ }
+ else
+ {
+ m_CursorPos.x = len;
+ return false;
+ }
}
- // do we have to split a text object?
- else if((*i)->GetType() == WXLO_TYPE_TEXT && m_CursorOffset != (*i)->CountPositions())
+ return false;
+}
+
+bool
+wxLayoutList::MoveCursorVertically(int n)
+{
+ if(n < 0) // move up
{
- wxLayoutObjectText *tobj = (wxLayoutObjectText *) *i;
- String left = tobj->GetText().substr(0,m_CursorOffset); // get part before cursor
- tobj->GetText() = tobj->GetText().substr(m_CursorOffset,(*i)->CountPositions()-m_CursorOffset); // keeps the right half
- insert(i,obj);
- m_CursorObject = i; // == obj
- insert(i,new wxLayoutObjectText(left)); // inserts before
+ if(m_CursorLine == m_FirstLine) return false;
+ while(n < 0 && m_CursorLine)
+ {
+ m_CursorLine = m_CursorLine->GetPreviousLine();
+ m_CursorPos.y--;
+ n++;
+ }
+ if(! m_CursorLine)
+ {
+ m_CursorLine = m_FirstLine;
+ m_CursorPos.y = 0;
+ return false;
+ }
+ else
+ {
+ if(m_CursorPos.x > m_CursorLine->GetLength())
+ m_CursorPos.x = m_CursorLine->GetLength();
+ return true;
+ }
}
- else
+ else // move down
{
- // all other cases, append after object:
- wxLayoutObjectList::iterator j = i; // we want to apend after this object
- j++;
- if(j != end())
+ wxLayoutLine *last = m_CursorLine;
+ if(! m_CursorLine->GetNextLine()) return false;
+ while(n > 0 && m_CursorLine)
{
- insert(j, obj);
- m_CursorObject = j;
+ n--;
+ m_CursorPos.y ++;
+ m_CursorLine = m_CursorLine->GetNextLine();
+ }
+ if(! m_CursorLine)
+ {
+ m_CursorLine = last;
+ m_CursorPos.y ++;
+ return false;
}
else
{
- push_back(obj);
- m_CursorObject = tail();
+ if(m_CursorPos.x > m_CursorLine->GetLength())
+ m_CursorPos.x = m_CursorLine->GetLength();
+ return true;
}
}
-
- if(obj->GetType() != WXLO_TYPE_LINEBREAK) // handled separately above
- m_CursorPos.x += obj->CountPositions();
- // applies also for linebreak:
- m_CursorOffset = obj->CountPositions();
-
- if(obj->GetType() == WXLO_TYPE_LINEBREAK)
- m_MaxLine++;
- m_CursorMoved = true;
}
-void
-wxLayoutList::Insert(String const &text)
+bool
+wxLayoutList::MoveCursorHorizontally(int n)
{
- wxLayoutObjectText *tobj = NULL;
- wxLayoutObjectList::iterator j;
+ int move;
+ while(n < 0)
+ {
+ if(m_CursorPos.x == 0) // at begin of line
+ {
+ if(! MoveCursorVertically(-1))
+ break;
+ MoveCursorToEndOfLine();
+ n++;
+ continue;
+ }
+ move = -n;
+ if(move > m_CursorPos.x) move = m_CursorPos.x;
+ m_CursorPos.x -= move; n += move;
+ }
-// WXL_TRACE(Insert(text));
+ while(n > 0)
+ {
+ int len = m_CursorLine->GetLength();
+ if(m_CursorPos.x == len) // at end of line
+ {
+ if(! MoveCursorVertically(1))
+ break;
+ MoveCursorToBeginOfLine();
+ n--;
+ continue;
+ }
+ move = n;
+ if( move >= len-m_CursorPos.x) move = len-m_CursorPos.x;
+ m_CursorPos.x += move;
+ n -= move;
+ }
+ return n == 0;
+}
- if(! m_Editable)
- return;
+bool
+wxLayoutList::Insert(wxString const &text)
+{
+ wxASSERT(m_CursorLine);
+ m_CursorLine->Insert(m_CursorPos.x, text);
+ m_CursorPos.x += text.Length();
+ return true;
+}
- m_bModified = true;
+bool
+wxLayoutList::Insert(wxLayoutObject *obj)
+{
+ wxASSERT(m_CursorLine);
+ m_CursorLine->Insert(m_CursorPos.x, obj);
+ m_CursorPos.x += obj->GetLength();
+ return true;
+}
- wxLayoutObjectList::iterator i = m_CursorObject;
+bool
+wxLayoutList::LineBreak(void)
+{
+ wxASSERT(m_CursorLine);
- if(i == end())
- {
- Insert(new wxLayoutObjectText(text));
- return;
- }
+ bool setFirst = (m_CursorLine == m_FirstLine && m_CursorPos.x == 0);
+ m_CursorLine = m_CursorLine->Break(m_CursorPos.x);
+ if(setFirst) // we were at beginning of first line
+ m_FirstLine = m_CursorLine->GetPreviousLine();
+ m_CursorPos.y++;
+ m_CursorPos.x = 0;
+ return true;
+}
- switch((**i).GetType())
+bool
+wxLayoutList::Delete(CoordType npos)
+{
+ wxASSERT(m_CursorLine);
+ CoordType left;
+ do
{
- case WXLO_TYPE_TEXT:
-// insert into an existing text object:
- tobj = (wxLayoutObjectText *)*i ;
- wxASSERT(tobj);
- tobj->GetText().insert(m_CursorOffset,text);
- m_CursorObject = i;
- m_CursorOffset = m_CursorOffset + text.length();
- m_CursorPos.x += text.length();
- break;
- case WXLO_TYPE_LINEBREAK:
- default:
- j = i;
- if(m_CursorOffset == 0) // try to append to previous object
- {
- j--;
- if(j != end() && (**j).GetType() == WXLO_TYPE_TEXT)
- {
- tobj = (wxLayoutObjectText *)*j;
- tobj->GetText()+=text;
- m_CursorObject = j;
- m_CursorOffset = (**j).CountPositions();
- m_CursorPos.x += text.length();
- }
- else
- {
- insert(i,new wxLayoutObjectText(text));
- m_CursorObject = i;
- m_CursorOffset = (**i).CountPositions();
- m_CursorPos.x += m_CursorOffset;
- }
+ left = m_CursorLine->Delete(m_CursorPos.x, npos);
+ if(left == 0)
+ return true;
+ // More to delete, continue on next line.
+ // First, check if line is empty:
+ if(m_CursorLine->GetLength() == 0)
+ { // in this case, updating could probably be optimised
+ m_CursorLine = m_CursorLine->DeleteLine(true);
+ left--;
}
- else // offset == 1 : cursor after linebreak
+ else
{
- j++;
- m_CursorObject = j;
- m_CursorOffset = 0;
- if(j != end() && (**j).GetType() == WXLO_TYPE_TEXT)
- {
- tobj = (wxLayoutObjectText *)*j;
- tobj->GetText()=text+tobj->GetText();
- m_CursorOffset = text.length();
- m_CursorPos.x += m_CursorOffset;
- }
+ // Need to join next line
+ if(! m_CursorLine->GetNextLine())
+ break; // cannot
else
{
- if(j == end())
- {
- push_back(new wxLayoutObjectText(text));
- m_CursorObject = tail();
- m_CursorOffset = (**m_CursorObject).CountPositions();
- m_CursorPos.x += text.length();
- }
- else
- {
- insert(j,new wxLayoutObjectText(text));
- m_CursorObject = j;
- m_CursorOffset = (**j).CountPositions();
- m_CursorPos.x += text.length();
- }
+ m_CursorLine->MergeNextLine();
+ left--;
}
}
- break;
}
- m_CursorMoved = true;
+ while(left);
+ return left == 0;
}
-CoordType
-wxLayoutList::GetLineLength(wxLayoutObjectList::iterator i, CoordType offs)
+int
+wxLayoutList::DeleteLines(int n)
{
- if(i == end())
- return 0;
-
- CoordType len = 0;
-
- if(offs == 0 && (**i).GetType() == WXLO_TYPE_LINEBREAK)
- if(i != begin())
- i--;
- else
- return 0; // at begin of buffer in front of a linebreak
-
-// search backwards for beginning of line:
- while(i != begin() && (*i)->GetType() != WXLO_TYPE_LINEBREAK)
- i--;
- if((*i)->GetType() == WXLO_TYPE_LINEBREAK)
- i++;
-// now we can start counting:
- while(i != end() && (*i)->GetType() != WXLO_TYPE_LINEBREAK)
+ wxASSERT(m_CursorLine);
+ wxLayoutLine *line;
+ while(n > 0)
{
- len += (*i)->CountPositions();
- i++;
+ if(!m_CursorLine->GetNextLine())
+ { // we cannot delete this line, but we can clear it
+ MoveCursorToBeginOfLine();
+ DeleteToEndOfLine();
+ return n-1;
+ }
+ //else:
+ line = m_CursorLine;
+ m_CursorLine = m_CursorLine->DeleteLine(true);
+ n--;
+ if(line == m_FirstLine) m_FirstLine = m_CursorLine;
+ wxASSERT(m_FirstLine);
+ wxASSERT(m_CursorLine);
}
- len++; // one extra for the linebreak
- return len;
+ m_CursorLine->RecalculatePositions(2);
+ return n;
}
void
-wxLayoutList::Clear(int family, int size, int style, int weight,
- int underline, char const *fg, char const *bg)
+wxLayoutList::Layout(wxDC &dc, CoordType bottom) const
{
- m_bModified = true;
- m_CursorMoved = true;
- m_dirty = true; // force redraw/recalc
- wxLayoutObjectList::iterator i = begin();
+ wxLayoutLine *line = m_FirstLine;
- wxBitmap bm(4,4);
- m_CursorMemDC.SelectObject(bm);
+ // first, make sure everything is calculated - this might not be
+ // needed, optimise it later
+ m_DefaultSetting->Layout(dc);
+ while(line)
+ {
+ if(line == m_CursorLine)
+ line->Layout(dc, (wxPoint *)&m_CursorScreenPos, (wxPoint *)&m_CursorSize, m_CursorPos.x);
+ else
+ line->Layout(dc);
+ // little condition to speed up redrawing:
+ if(bottom != -1 && line->GetPosition().y > bottom) break;
+ line = line->GetNextLine();
+ }
+ // can only be 0 if we are on the first line and have no next line
+ wxASSERT(m_CursorSize.x != 0 || (m_CursorLine &&
+ m_CursorLine->GetNextLine() == NULL &&
+ m_CursorLine == m_FirstLine));
+}
- while(i != end()) // == while valid
- erase(i);
+void
+wxLayoutList::Draw(wxDC &dc, wxPoint const &offset,
+ CoordType top, CoordType bottom) const
+{
+ wxLayoutLine *line = m_FirstLine;
- // set defaults
- m_FontPtSize = size;
- m_FontUnderline = false;
- m_FontFamily = family;
- m_FontStyle = style;
- m_FontWeight = weight;
- m_ColourFG = wxTheColourDatabase->FindColour(fg);
- m_ColourBG = wxTheColourDatabase->FindColour(bg);
+ Layout(dc, bottom);
+ m_DefaultSetting->Draw(dc, wxPoint(0,0));
+ while(line)
+ {
+ // only draw if between top and bottom:
+ if((top == -1 || line->GetPosition().y >= top))
+ line->Draw(dc, offset);
+ // little condition to speed up redrawing:
+ if(bottom != -1 && line->GetPosition().y > bottom) break;
+ line = line->GetNextLine();
+ }
+ // can only be 0 if we are on the first line and have no next line
+ wxASSERT(m_CursorSize.x != 0 || (m_CursorLine &&
+ m_CursorLine->GetNextLine() == NULL &&
+ m_CursorLine == m_FirstLine));
+}
- if(! m_ColourFG) m_ColourFG = wxBLACK;
- if(! m_ColourBG) m_ColourBG = wxWHITE;
-
- m_Position = wxPoint(0,0);
- m_CursorPos = wxPoint(0,0);
- m_CursorObject = iterator(NULL);
- m_CursorOffset = 0;
- m_CursorSize = wxPoint(2,(BASELINESTRETCH*m_FontPtSize)/10);
+wxLayoutObject *
+wxLayoutList::FindObject(wxPoint const pos)
+{
+ // First, find the right line:
+ wxLayoutLine *line = m_FirstLine;
+ wxPoint p;
- m_MaxLine = 0;
- m_LineHeight = (BASELINESTRETCH*m_FontPtSize)/10;
- m_MaxX = 0; m_MaxY = 0;
-
-
- m_FoundCursor = wxPoint(0,0);
- m_FoundIterator = begin();
+ while(line)
+ {
+ p = line->GetPosition();
+ if(p.y <= pos.y && p.y+line->GetHeight() >= pos.y)
+ break;
+ line = line->GetNextLine();
+ }
+ if(! line) return NULL; // not found
+ // Now, find the object in the line:
+ return line->FindObject(pos.x);
- if(m_DefaultSetting)
- delete m_DefaultSetting;
-
- m_DefaultSetting = new
- wxLayoutObjectCmd(m_FontPtSize,m_FontFamily,m_FontStyle,
- m_FontWeight,m_FontUnderline,
- m_ColourFG, m_ColourBG);
}
-
-wxLayoutObjectBase *
-wxLayoutList::Find(wxPoint coords) const
+wxPoint
+wxLayoutList::GetSize(void) const
{
- wxLayoutObjectList::iterator i = begin();
+ wxLayoutLine
+ *line = m_FirstLine,
+ *last = line;
+ if(! line)
+ return wxPoint(0,0);
- wxPoint topleft, bottomright;
+ wxPoint max(0,0);
- while(i != end()) // == while valid
+ // find last line:
+ while(line)
{
- wxLayoutObjectBase *object = *i;
- topleft = object->GetPosition();
- if(coords.y >= topleft.y && coords.x >= topleft.x)
- {
- bottomright = topleft;
- bottomright.x += object->GetSize().x;
- bottomright.y += object->GetSize().y;
- if(coords.x <= bottomright.x && coords.y <= bottomright.y)
- return *i;
- }
- i++;
+ if(line->GetWidth() > max.x) max.x = line->GetWidth();
+ last = line;
+ line = line->GetNextLine();
}
- return NULL;
-}
-
-void
-wxLayoutList::SetWrapMargin(long n)
-{
- m_WrapMargin = n;
+ max.y = last->GetPosition().y + last->GetHeight();
+ return max;
}
void
-wxLayoutList::WrapLine(void)
+wxLayoutList::DrawCursor(wxDC &dc, bool active, wxPoint const &translate)
{
- wxASSERT(m_CursorObject);
+ wxPoint coords;
+ coords = m_CursorScreenPos;
+ coords.x += translate.x;
+ coords.y += translate.y;
- iterator i = m_CursorObject;
-
- if(!DoWordWrap() || !i ) // empty list
- return;
- int cursorpos = m_CursorPos.x, cpos, offset;
+#ifdef WXLAYOUT_DEBUG
+ WXLO_DEBUG(("Drawing cursor (%ld,%ld) at %ld,%ld, size %ld,%ld, line: %ld, len %ld",
+ (long)m_CursorPos.x, (long)m_CursorPos.y,
+ (long)coords.x, (long)coords.y,
+ (long)m_CursorSize.x, (long)m_CursorSize.y,
+ (long)m_CursorLine->GetLineNumber(),
+ (long)m_CursorLine->GetLength()));
+#endif
- if(cursorpos < m_WrapMargin)
- return;
+ if(active)
+ dc.SetBrush(*wxBLACK_BRUSH);
+ dc.SetPen(wxPen(*wxBLACK,1,wxSOLID));
+ dc.SetLogicalFunction(wxXOR);
+ dc.DrawRectangle(coords.x, coords.y, m_CursorSize.x, m_CursorSize.y);
+ dc.SetLogicalFunction(wxCOPY);
+ dc.SetBrush(wxNullBrush);
+}
- // else: break line
- // find the right object to break:
- // is it the current one?
- i = m_CursorObject;
- cpos = cursorpos-m_CursorOffset;
- while(i != begin() && cpos >= m_WrapMargin)
- {
- i--;
- cpos -= (**i).CountPositions();
- }
- // now i is the object to break and cpos its position
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- offset = m_WrapMargin - cpos;
- wxASSERT(offset <= (**i).CountPositions());
+ wxLayoutPrintout
- // split it
- if((**i).GetType() == WXLO_TYPE_TEXT)
- {
- wxLayoutObjectText &t = *(wxLayoutObjectText *)*i;
- for(; offset > 0; offset--)
- if(t.GetText().c_str()[offset] == ' ' || t.GetText().c_str()[offset] == '\t')
- {
- String left = t.GetText().substr(0,offset); // get part before cursor
- t.GetText() = t.GetText().substr(offset+1,t.CountPositions()-offset-1); // keeps the right halve
- insert(i,new wxLayoutObjectLineBreak);
- insert(i,new wxLayoutObjectText(left)); // inserts before
- break;
- }
- if(offset == 0)
- {
- // only insert a line break if there isn't already one
- iterator j = i; j--;
- if(j && j != begin() && (**j).GetType() != WXLO_TYPE_LINEBREAK)
- insert(i,new wxLayoutObjectLineBreak);
- else
- return; // do nothing
- }
- }
- else
- insert(i,new wxLayoutObjectLineBreak);
- m_MaxLine++;
- m_CursorPos.y++;
- m_CursorPos.x -= offset;
- m_CursorOffset -= offset;
-}
-/******************** printing stuff ********************/
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-wxLayoutPrintout::wxLayoutPrintout(wxLayoutList &llist,
+wxLayoutPrintout::wxLayoutPrintout(wxLayoutList *llist,
wxString const & title)
:wxPrintout(title)
{
- m_llist = &llist;
+ m_llist = llist;
m_title = title;
}
+float
+wxLayoutPrintout::ScaleDC(wxDC *dc)
+{
+ // The following bit is taken from the printing sample, let's see
+ // whether it works for us.
+
+ /* You might use THIS code to set the printer DC to ROUGHLY reflect
+ * the screen text size. This page also draws lines of actual length 5cm
+ * on the page.
+ */
+ // Get the logical pixels per inch of screen and printer
+ int ppiScreenX, ppiScreenY;
+ GetPPIScreen(&ppiScreenX, &ppiScreenY);
+ int ppiPrinterX, ppiPrinterY;
+ GetPPIPrinter(&ppiPrinterX, &ppiPrinterY);
+
+ if(ppiScreenX == 0) // not yet set, need to guess
+ {
+ ppiScreenX = 100;
+ ppiScreenY = 100;
+ }
+ if(ppiPrinterX == 0) // not yet set, need to guess
+ {
+ ppiPrinterX = 72;
+ ppiPrinterY = 72;
+ }
+
+ // This scales the DC so that the printout roughly represents the
+ // the screen scaling. The text point size _should_ be the right size
+ // but in fact is too small for some reason. This is a detail that will
+ // need to be addressed at some point but can be fudged for the
+ // moment.
+ float scale = (float)((float)ppiPrinterX/(float)ppiScreenX);
+
+ // Now we have to check in case our real page size is reduced
+ // (e.g. because we're drawing to a print preview memory DC)
+ int pageWidth, pageHeight;
+ int w, h;
+ dc->GetSize(&w, &h);
+ GetPageSizePixels(&pageWidth, &pageHeight);
+ if(pageWidth != 0) // doesn't work always
+ {
+ // If printer pageWidth == current DC width, then this doesn't
+ // change. But w might be the preview bitmap width, so scale down.
+ scale = scale * (float)(w/(float)pageWidth);
+ }
+ dc->SetUserScale(scale, scale);
+ return scale;
+}
+
bool wxLayoutPrintout::OnPrintPage(int page)
{
wxDC *dc = GetDC();
+
+ ScaleDC(dc);
+
if (dc)
{
- DrawHeader(*dc,wxPoint(m_Margins.left,m_Margins.top/2),wxPoint(m_Margins.right,m_Margins.top),page);
int top, bottom;
top = (page - 1)*m_PrintoutHeight;
bottom = top + m_PrintoutHeight;
// SetDeviceOrigin() doesn't work here, so we need to manually
// translate all coordinates.
- wxPoint translate(m_Margins.left,-top+m_Margins.top);
- m_llist->Draw(*dc,top,bottom,wxLayoutObjectList::iterator(NULL),translate);
+ wxPoint translate(m_Offset.x,m_Offset.y-top);
+ m_llist->Draw(*dc, translate, top, bottom);
return true;
}
else
return false;
}
-bool wxLayoutPrintout::OnBeginDocument(int startPage, int endPage)
-{
- if (!wxPrintout::OnBeginDocument(startPage, endPage))
- return false;
-
- return true;
-}
-
-void
-wxLayoutPrintout::OnPreparePrinting(void)
-{
-
-}
-
-
void wxLayoutPrintout::GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int *selPageTo)
{
- // ugly hack to get number of pages
+ /* We allocate a temporary wxDC for printing, so that we can
+ determine the correct paper size and scaling. We don't actually
+ print anything on it. */
#ifdef __WXMSW__
wxPrinterDC psdc("","",WXLLIST_TEMPFILE,false);
#else
wxPostScriptDC psdc(WXLLIST_TEMPFILE,false);
#endif
- psdc.GetSize(&m_PageWidth, &m_PageHeight); // that's all we need it for
- // We do 5% margins on top and bottom, and a 5% high header line.
- m_Margins.top = m_PageHeight / 10 ; // 10%, half of it header
- m_Margins.bottom = m_PageHeight - m_PageHeight / 20; // 95%
- // On the sides we reserve 10% each for the margins.
- m_Margins.left = m_PageWidth / 10;
- m_Margins.right = m_PageWidth - m_PageWidth / 10;
+ float scale = ScaleDC(&psdc);
- // This is the length of the printable area.
- m_PrintoutHeight = m_PageHeight - (int) (m_PageHeight * 0.15);
-
- //FIXME this is wrong but not used at the moment
- m_PageWidth = m_Margins.right - m_Margins.left;
+ psdc.GetSize(&m_PageWidth, &m_PageHeight);
+ // This sets a left/top origin of 10% and 20%:
+ m_Offset = wxPoint(m_PageWidth/10, m_PageHeight/20);
+ // This is the length of the printable area.
+ m_PrintoutHeight = m_PageHeight - (int) (m_PageHeight * 0.1);
+ m_PrintoutHeight = (int)( m_PrintoutHeight / scale); // we want to use the real paper height
+
+
m_NumOfPages = (int)( m_llist->GetSize().y / (float)(m_PrintoutHeight) + 0.5);
+
+ // This is a crude hack to get it right for very small
+ // printouts. No idea why this is required, I thought +0.5 would do
+ // the job. :-(
+ if(m_NumOfPages == 0 && m_llist->GetSize().y > 0)
+ m_NumOfPages = 1;
*minPage = 1;
*maxPage = m_NumOfPages;
return pageNum <= m_NumOfPages;
}
-
+/*
+ Stupid wxWindows doesn't draw proper ellipses, so we comment this
+ out. It's a waste of paper anyway.
+*/
+#if 0
void
wxLayoutPrintout::DrawHeader(wxDC &dc,
wxPoint topleft, wxPoint bottomright,
dc.SetBrush(brush);
dc.SetFont(font);
}
+#endif
-wxLayoutPrintout *
-wxLayoutList::MakePrintout(wxString const &name)
-{
- return new wxLayoutPrintout(*this,name);
-}
/*-*- c++ -*-********************************************************
* wxLayoutList.h - a formatted text rendering engine for wxWindows *
* *
- * (C) 1998 by Karsten Ballüder (Ballueder@usa.net) *
+ * (C) 1999 by Karsten Ballüder (Ballueder@usa.net) *
* *
* $Id$
*******************************************************************/
#include "wx/generic/prntdlgg.h"
// skip the following defines if embedded in M application
-#ifdef M_BASEDIR
-# ifdef DEBUG
-# define WXLAYOUT_DEBUG
-# endif
-#else
- // for testing only:
-# define WXLAYOUT_DEBUG
- // The wxLayout classes can be compiled with std::string instead of wxString
- //# define USE_STD_STRING
+#ifndef M_BASEDIR
# define WXMENU_LAYOUT_LCLICK 1111
-# define WXMENU_LAYOUT_RCLICK 1112
+# define WXMENU_LAYOUT_RCLICK 1112
# define WXMENU_LAYOUT_DBLCLICK 1113
#endif
-#ifdef USE_STD_STRING
-# include <string>
- typedef std::string String;
-# define Str(str)(str.c_str())
-#else
- typedef wxString String;
-# define Str(str) str
+#ifdef __WXDEBUG__
+# define WXLAYOUT_DEBUG
#endif
-#define WXLO_DEFAULTFONTSIZE 12
+#ifndef WXLO_DEFAULTFONTSIZE
+# define WXLO_DEFAULTFONTSIZE 12
+#endif
/// Types of currently supported layout objects.
enum wxLayoutObjectType
-{ WXLO_TYPE_INVALID = 0, WXLO_TYPE_TEXT, WXLO_TYPE_CMD, WXLO_TYPE_ICON, WXLO_TYPE_LINEBREAK };
+{
+ /// illegal object type, should never appear
+ WXLO_TYPE_INVALID = 0,
+ /// text object, containing normal text
+ WXLO_TYPE_TEXT,
+ /// command object, containing font or colour changes
+ WXLO_TYPE_CMD,
+ /// icon object, any kind of image
+ WXLO_TYPE_ICON
+};
-/// Type used for coordinates in drawing.
+/// Type used for coordinates in drawing. Must be signed.
typedef long CoordType;
+// Forward declarations.
class wxLayoutList;
-class wxLayoutObjectBase;
-
+class wxLayoutObject;
class wxDC;
class wxColour;
class wxFont;
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ The wxLayout objects which make up the lines.
+
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
/** The base class defining the interface to each object which can be
part of the layout. Each object needs to draw itself and calculate
its size.
*/
-class wxLayoutObjectBase
+class wxLayoutObject
{
public:
+ /// This structure can be used to contain data associated with the object.
struct UserData
{
virtual ~UserData() { }
};
/// return the type of this object
- virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_INVALID; } ;
- /** Calculates the position etc of an object.
+ virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_INVALID; }
+ /** Calculates the size of an object.
@param dc the wxDC to draw on
- @param position where to draw the top left corner
- @param baseLine the baseline for alignment, from top of box
*/
- virtual void Layout(wxDC & dc,
- wxPoint position,
- CoordType baseLine)
- { m_Position = position; }
+ virtual void Layout(wxDC &) = 0;
/** Draws an object.
@param dc the wxDC to draw on
- @param translation to be added to coordinates
+ @param coords where to draw the baseline of the object.
*/
- virtual void Draw(wxDC & dc, wxPoint const &translate) {}
+ virtual void Draw(wxDC & /* dc */, wxPoint const & /* coords */) { }
/** Calculates and returns the size of the object.
- @param baseLine pointer where to store the baseline position of
- this object (i.e. the height from the top of the box to the
- baseline)
+ @param top where to store height above baseline
+ @param bottom where to store height below baseline
@return the size of the object's box in pixels
*/
- virtual wxPoint GetSize(CoordType * baseLine = NULL) const
- { return wxPoint(0,0); }
-
- /** Calculates and returns the position of the object.
- @return the size of the object's box in pixels
- */
- virtual wxPoint GetPosition(void) const { return m_Position; }
+ virtual wxPoint GetSize(CoordType * top, CoordType *bottom) const
+ { *top = 0; *bottom = 0; return wxPoint(0,0); }
+ /// Return just the width of the object on the screen.
+ virtual CoordType GetWidth(void) const { return 0; }
/// returns the number of cursor positions occupied by this object
- virtual CoordType CountPositions(void) const { return 1; }
+ virtual CoordType GetLength(void) const { return 1; }
/// constructor
- wxLayoutObjectBase() { m_UserData = NULL; }
+ wxLayoutObject() { m_UserData = NULL; }
/// delete the user data
- virtual ~wxLayoutObjectBase() { if(m_UserData) delete m_UserData; }
+ virtual ~wxLayoutObject() { if(m_UserData) delete m_UserData; }
#ifdef WXLAYOUT_DEBUG
virtual void Debug(void);
#endif
- /// query whether coordinates have changed since last drawing
- virtual bool IsDirty(void) const { return true; }
-
/** Tells the object about some user data. This data is associated
with the object and will be deleted at destruction time.
*/
private:
/// optional data for application's use
UserData *m_UserData;
-protected:
- wxPoint m_Position;
};
-/// Define a list type of wxLayoutObjectBase pointers.
-KBLIST_DEFINE(wxLayoutObjectList, wxLayoutObjectBase);
+/// Define a list type of wxLayoutObject pointers.
+KBLIST_DEFINE(wxLayoutObjectList, wxLayoutObject);
+/// An illegal iterator to save typing.
+#define NULLIT (wxLayoutObjectList::iterator(NULL))
+/// The iterator type.
+#define wxLOiterator wxLayoutObjectList::iterator
-/// object for text block
-class wxLayoutObjectText : public wxLayoutObjectBase
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ wxLayoutObjectText
+
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/** This class implements a wxLayoutObject holding plain text.
+ */
+class wxLayoutObjectText : public wxLayoutObject
{
public:
- wxLayoutObjectText(const String &txt);
+ wxLayoutObjectText(const wxString &txt);
virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_TEXT; }
- virtual void Layout(wxDC &dc, wxPoint position, CoordType
- baseLine);
-
- virtual void Draw(wxDC &dc, wxPoint const &translate);
- /** This returns the height and in baseLine the position of the
- text's baseline within it's box. This is needed to properly
- align text objects.
+ virtual void Layout(wxDC &dc);
+ virtual void Draw(wxDC &dc, wxPoint const &coords);
+ /** Calculates and returns the size of the object.
+ @param top where to store height above baseline
+ @param bottom where to store height below baseline
+ @return the size of the object's box in pixels
*/
- virtual wxPoint GetSize(CoordType *baseLine = NULL) const;
+ virtual wxPoint GetSize(CoordType * top, CoordType *bottom) const;
+ /// Return just the width of the object on the screen.
+ virtual CoordType GetWidth(void) const { return m_Width; }
#ifdef WXLAYOUT_DEBUG
virtual void Debug(void);
#endif
- virtual CoordType CountPositions(void) const { return strlen(m_Text.c_str()); }
- virtual bool IsDirty(void) const { return m_IsDirty; }
+ virtual CoordType GetLength(void) const { return strlen(m_Text.c_str()); }
// for editing:
- String & GetText(void) { return m_Text; }
- void SetText(String const &text) { m_Text = text; }
+ wxString & GetText(void) { return m_Text; }
+ void SetText(wxString const &text) { m_Text = text; }
private:
- String m_Text;
+ wxString m_Text;
/// size of the box containing text
long m_Width, m_Height;
- /// the position of the baseline counted from the top of the box
- long m_BaseLine;
- /// coordinates have changed
- bool m_IsDirty;
+ /// Height above baseline.
+ long m_Top;
+ /// Height below baseline.
+ long m_Bottom;
};
-/// icon/pictures:
-class wxLayoutObjectIcon : public wxLayoutObjectBase
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ wxLayoutObjectIcon
+
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/** This class implements a wxLayoutObject holding a graphic.
+ */
+class wxLayoutObjectIcon : public wxLayoutObject
{
public:
- wxLayoutObjectIcon(wxIcon *icon);
- wxLayoutObjectIcon(wxIcon const &icon);
+ wxLayoutObjectIcon(wxBitmap *icon);
+ wxLayoutObjectIcon(wxBitmap const &icon);
~wxLayoutObjectIcon() { delete m_Icon; }
virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_ICON; }
- virtual void Layout(wxDC &dc, wxPoint position, CoordType baseLine);
- virtual void Draw(wxDC &dc, wxPoint const &translate);
+ virtual void Layout(wxDC &dc);
+ virtual void Draw(wxDC &dc, wxPoint const &coords);
- virtual wxPoint GetSize(CoordType *baseLine = NULL) const;
- virtual bool IsDirty(void) const { return m_IsDirty; }
+ /** Calculates and returns the size of the object.
+ @param top where to store height above baseline
+ @param bottom where to store height below baseline
+ @return the size of the object's box in pixels
+ */
+ virtual wxPoint GetSize(CoordType * top, CoordType *bottom) const;
+ /// Return just the width of the object on the screen.
+ virtual CoordType GetWidth(void) const { return m_Icon->GetWidth(); }
private:
- wxIcon *m_Icon;
- /// coordinates have changed
- bool m_IsDirty;
+ wxBitmap *m_Icon;
};
/// for export to html:
struct wxLayoutStyleInfo
{
+ wxLayoutStyleInfo()
+ {
+ family = -1; // this marks the styleinfo as uninitialised
+ }
int size, family, style, weight;
bool underline;
unsigned fg_red, fg_green, fg_blue;
unsigned bg_red, bg_green, bg_blue;
};
-/// pseudo-object executing a formatting command in Draw()
-class wxLayoutObjectCmd : public wxLayoutObjectBase
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ wxLayoutObjectCmd
+
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/** This class implements a wxLayoutObject holding style change commands.
+ */
+class wxLayoutObjectCmd : public wxLayoutObject
{
public:
virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_CMD; }
- virtual void Draw(wxDC &dc, wxPoint const &translate);
- virtual void Layout(wxDC &dc, wxPoint position, CoordType baseLine);
+ virtual void Layout(wxDC &dc);
+ virtual void Draw(wxDC &dc, wxPoint const &coords);
wxLayoutObjectCmd(int size, int family, int style, int weight,
bool underline,
wxColour const *fg, wxColour const *bg);
~wxLayoutObjectCmd();
- /// caller must free pointer:
- wxLayoutStyleInfo *GetStyle(void) const ;
+ /** Stores the current style in the styleinfo structure */
+ void GetStyle(wxLayoutStyleInfo *si) const;
/// return the background colour for setting colour of window
wxColour const *GetBGColour(void) const { return m_ColourBG; }
private:
wxColour const *m_ColourBG;
};
-/// this object doesn't do anything at all
-class wxLayoutObjectLineBreak : public wxLayoutObjectBase
-{
-public:
- virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_LINEBREAK; }
-};
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ The wxLayoutLine object
-class wxLayoutPrintout;
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-class wxLayoutMargins
+/** This class represents a single line of objects to be displayed.
+ It knows its height and total size and whether it needs to be
+ redrawn or not.
+ It has pointers to its first and next line so it can automatically
+ update them as needed.
+*/
+class wxLayoutLine
{
public:
- wxLayoutMargins() { top = left = 0; bottom = right = -1; }
- int top;
- int left;
- int bottom;
- int right;
+ /** Constructor.
+ @param prev pointer to previous line or NULL
+ @param next pointer to following line or NULL
+ */
+ wxLayoutLine(wxLayoutLine *prev);
+ /** This function inserts a new object at cursor position xpos.
+ @param xpos where to insert new object
+ @param obj the object to insert
+ @return true if that xpos existed and the object was inserted
+ */
+ bool Insert(CoordType xpos, wxLayoutObject *obj);
+
+ /** This function inserts text at cursor position xpos.
+ @param xpos where to insert
+ @param text the text to insert
+ @return true if that xpos existed and the object was inserted
+ */
+ bool Insert(CoordType xpos, wxString text);
+
+ /** This function appends an object to the line.
+ @param obj the object to insert
+ */
+ void Append(wxLayoutObject * obj)
+ {
+ wxASSERT(obj);
+ m_ObjectList.push_back(obj);
+ m_Length += obj->GetLength();
+ }
+
+ /** This function appens the next line to this, i.e. joins the two
+ lines into one.
+ */
+ void MergeNextLine(void);
+
+ /** This function deletes npos cursor positions from position xpos.
+ @param xpos where to delete
+ @param npos how many positions
+ @return number of positions still to be deleted
+ */
+ CoordType Delete(CoordType xpos, CoordType npos);
+
+ /** This function breaks the line at a given cursor position.
+ @param xpos where to break it
+ @return pointer to the new line object replacing the old one
+ */
+ wxLayoutLine *Break(CoordType xpos);
+
+ /** Deletes the next word from this position, including leading
+ whitespace.
+ This function does not delete over font changes, i.e. a word
+ with formatting instructions in the middle of it is treated as
+ two (three actually!) words. In fact, if the cursor is on a non-text object, that
+ one is treated as a word.
+ @param xpos from where to delete
+ @return true if a word was deleted
+ */
+ bool DeleteWord(CoordType npos);
+
+ /** Finds the object which covers the cursor position xpos in this
+ line.
+ @param xpos the column number
+ @param offset where to store the difference between xpos and
+ the object's head
+ @return iterator to the object or NULLIT
+ */
+ wxLayoutObjectList::iterator FindObject(CoordType xpos, CoordType
+ *offset) const ;
+
+ /** Get the first object in the list. This is used by the wxlparser
+ functions to export the list.
+ @return iterator to the first object
+ */
+ wxLayoutObjectList::iterator GetFirstObject(void)
+ {
+ return m_ObjectList.begin();
+ }
+
+ /** Deletes this line, returns pointer to next line.
+ @param update If true, update all following lines.
+ */
+ wxLayoutLine *DeleteLine(bool update);
+
+ /**@name Cursor Management */
+ //@{
+ /** Return the line number of this line.
+ @return the line number
+ */
+ CoordType GetLineNumber(void) const { return m_LineNumber; }
+ /** Return the length of the line.
+ @return line lenght in cursor positions
+ */
+ CoordType GetLength(void) const { return m_Length; }
+ //@}
+
+ /**@name Drawing and Layout */
+ //@{
+ /** Draws the line on a wxDC.
+ @param dc the wxDC to draw on
+ @param offset an optional offset to shift printout
+ */
+ void Draw(wxDC &dc, const wxPoint &offset = wxPoint(0,0)) const;
+
+ /** Recalculates the positions of objects and the height of the
+ line.
+ @param dc the wxDC to draw on
+ @param cursorPos if not NULL, set cursor screen position in there
+ @param cursorSize if not cursorPos != NULL, set cursor size in there
+ @param cx if cursorPos != NULL, the cursor x position
+ */
+ void Layout(wxDC &dc,
+ wxPoint *cursorPos = NULL,
+ wxPoint *cursorSize = NULL,
+ int cx = 0);
+ /** This function finds an object belonging to a given cursor
+ position. It assumes that Layout() has been called before.
+ @param xpos screen x position
+ @return pointer to the object
+ */
+ wxLayoutObject * FindObject(CoordType xpos);
+ //@}
+
+ /**@name List traversal */
+ //@{
+ /// Returns pointer to next line.
+ wxLayoutLine *GetNextLine(void) const { return m_Next; }
+ /// Returns pointer to previous line.
+ wxLayoutLine *GetPreviousLine(void) const { return m_Previous; }
+ /// Sets the link to the next line.
+ void SetNext(wxLayoutLine *next)
+ { m_Next = next; if(next) next->m_Previous = this; }
+ /// Sets the link to the previous line.
+ void SetPrevious(wxLayoutLine *previous)
+ { m_Previous = previous; if(previous) previous->m_Next = this; }
+ //@}
+
+ /// Returns the position of this line on the canvas.
+ wxPoint GetPosition(void) const { return m_Position; }
+ /// Returns the height of this line.
+ CoordType GetHeight(void) const { return m_Height; }
+ /// Returns the width of this line.
+ CoordType GetWidth(void) const { return m_Width; }
+ /** This will recalculate the position and size of this line.
+ If called recursively it will abort if the position of an
+ object is unchanged, assuming that none of the following
+ objects need to move.
+ @param recurse if greater 0 then it will be used as the
+ minimum(!) recursion level, continue with all lines till the end of
+ the list or until the coordinates no longer changed.
+ */
+ void RecalculatePositions(int recurse = 0);
+private:
+ /// Destructor is private. Use DeleteLine() to remove it.
+ ~wxLayoutLine();
+
+ /**@name Functions to let the lines synchronise with each other. */
+ //@{
+ /** Sets the height of this line. Will mark following lines as
+ dirty.
+ @param height new height
+ */
+ void SetHeight(CoordType height)
+ { m_Height = height; RecalculatePositions(true); }
+ /// Recalculates the position of this line on the canvas.
+ wxPoint RecalculatePosition(void);
+
+ /** Moves the linenumbers one on, because a line has been inserted
+ or deleted.
+ @param delta either +1 or -1
+ */
+ void MoveLines(int delta)
+ {
+ m_LineNumber += delta;
+ if(m_Next) m_Next->MoveLines(delta);
+ }
+ //@}
+private:
+ /// The line number.
+ CoordType m_LineNumber;
+ /// The line length in cursor positions.
+ CoordType m_Length;
+ /// The total height of the line.
+ CoordType m_Height;
+ /// The total width of the line on screen.
+ CoordType m_Width;
+ /// The baseline for drawing objects
+ CoordType m_BaseLine;
+ /// The position on the canvas.
+ wxPoint m_Position;
+ /// The list of objects
+ wxLayoutObjectList m_ObjectList;
+ /// Have we been changed since the last layout?
+ bool m_Dirty;
+ /// Pointer to previous line if it exists.
+ wxLayoutLine *m_Previous;
+ /// Pointer to next line if it exists.
+ wxLayoutLine *m_Next;
+ /// Just to suppress gcc compiler warnings.
+ friend class dummy;
};
-/**
- This class provides a high level abstraction to the wxFText
- classes.
- It handles most of the character events with its own callback
- functions, providing an editing ability. All events which cannot be
- handled get passed to the parent window's handlers.
-*/
-class wxLayoutList : public wxLayoutObjectList
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ The wxLayoutList object
+
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/** The wxLayoutList is a list of wxLayoutLine objects. It provides a
+ higher level of abstraction for the text and can generally be considered
+ as representing "the text".
+ */
+class wxLayoutList
{
public:
+ /// Constructor.
wxLayoutList();
-
/// Destructor.
~wxLayoutList();
- /// adds an object:
- void AddObject(wxLayoutObjectBase *obj);
- /// adds a text object
- void AddText(String const &txt);
- /// adds a line break
- void LineBreak(void);
+ /// Clear the list.
+ void Clear(int family = wxROMAN,
+ int size=WXLO_DEFAULTFONTSIZE,
+ int style=wxNORMAL,
+ int weight=wxNORMAL,
+ int underline=0,
+ char const *fg="black",
+ char const *bg="white");
+
+ /**@name Cursor Management */
+ //@{
+ /** Set new cursor position.
+ @param p new position
+ @return bool if it could be set
+ */
+ bool MoveCursorTo(wxPoint const &p);
+ /** Move cursor up or down.
+ @param n
+ @return bool if it could be moved
+ */
+ bool MoveCursorVertically(int n);
+ /** Move cursor left or right.
+ @param n
+ @return bool if it could be moved
+ */
+ bool MoveCursorHorizontally(int n);
+
+ /// Move cursor to end of line.
+ void MoveCursorToEndOfLine(void)
+ {
+ wxASSERT(m_CursorLine);
+ MoveCursorHorizontally(m_CursorLine->GetLength()-m_CursorPos.x);
+ }
+
+ /// Move cursor to begin of line.
+ void MoveCursorToBeginOfLine(void)
+ { MoveCursorHorizontally(-m_CursorPos.x); }
+
+ /// Returns current cursor position.
+ wxPoint GetCursorPos(void) const { return m_CursorPos; }
+ //@}
+
+ /**@name Editing functions.
+ All of these functions return true on success and false on
+ failure. */
+ //@{
+ /// Insert text at current cursor position.
+ bool Insert(wxString const &text);
+ /// Insert some other object at current cursor position.
+ bool Insert(wxLayoutObject *obj);
+ /// Inserts a linebreak at current cursor position.
+ bool LineBreak(void);
+ /** This function deletes npos cursor positions.
+ @param npos how many positions
+ @return true if everything got deleted
+ */
+ bool Delete(CoordType npos);
+
+ /** Delete the next n lines.
+ @param n how many lines to delete
+ @return how many it could not delete
+ */
+ int DeleteLines(int n);
+
+ /// Delete to end of line.
+ void DeleteToEndOfLine(void)
+ {
+ wxASSERT(m_CursorLine);
+ Delete(m_CursorLine->GetLength()-m_CursorPos.x);
+ }
+ /// Delete to begin of line.
+ void DeleteToBeginOfLine(void)
+ {
+ wxASSERT(m_CursorLine);
+ CoordType n = m_CursorPos.x;
+#ifdef WXLAYOUT_DEBUG
+ wxASSERT(MoveCursorHorizontally(-n));
+#else
+ MoveCursorHorizontally(-n);
+#endif
+ Delete(n);
+ }
+
+ /** Delete the next word.
+ */
+ void DeleteWord(void)
+ {
+ wxASSERT(m_CursorLine);
+ m_CursorLine->DeleteWord(m_CursorPos.x);
+ }
+
+ //@}
+
+ /**@name Formatting options */
+ //@{
/// sets font parameters
void SetFont(int family, int size, int style,
int weight, int underline,
inline void SetFontUnderline(bool ul) { SetFont(-1,-1,-1,-1,(int)ul); }
/// set font colours by name
inline void SetFontColour(char const *fg, char const *bg = NULL) { SetFont(-1,-1,-1,-1,-1,fg,bg); }
-
- /** Sets the wrap margin in cursor positions.
- @param n the wrap margin, -1 to disable auto wrap
+ /**
+ Returns a pointer to the default settings.
+ This is only valid temporarily and should not be stored
+ anywhere.
+ @return the default settings of the list
*/
- void SetWrapMargin(long n = -1);
+ wxLayoutObjectCmd const *GetDefaults(void) const { return m_DefaultSetting ; }
+ //@}
- /// Wraps the current line if word wrap is enabled.
- void WrapLine(void);
-
- /** Re-layouts the list on a DC.
- @param dc the dc to layout for
- @param margins if not NULL, use these top and left margins
- */
- void Layout(wxDC &dc, wxLayoutMargins *margins = NULL);
-
- /** Draw the list on a given DC.
- @param dc the dc to layout for
- @param fromLine the first graphics line from where to draw
- @param toLine the last line at which to draw
- @param start if != iterator(NULL) start drawing from here
- */
- void Draw(wxDC &dc,
- CoordType fromLine = -1,
- CoordType toLine = -1,
- iterator start = iterator(NULL),
- wxPoint const &translate = wxPoint(0,0));
-
- /** Deletes at least to the end of line and redraws */
- void EraseAndDraw(wxDC &dc, iterator start = iterator(NULL),
- wxPoint const &translate = wxPoint(0,0));
-
- /** Finds the object occupying a certain screen position.
- @return pointer to wxLayoutObjectBase or NULL if not found
+ /**@name Drawing */
+ //@{
+ /** Draws the complete list on a wxDC.
+ @param dc the wxDC to draw on
+ @param offset an optional offset to shift printout
+ @param top optional y coordinate where to start drawing
+ @param bottom optional y coordinate where to stop drawing
*/
- wxLayoutObjectBase *Find(wxPoint coords) const;
-
-#ifdef WXLAYOUT_DEBUG
- void Debug(void);
- void ShowCurrentObject();
-#endif
+ void Draw(wxDC &dc, const wxPoint &offset = wxPoint(0,0),
+ CoordType top = -1, CoordType bottom = -1) const;
- /// dirty?
- bool IsDirty() const { return m_bModified; }
- bool CursorMoved(void) const { return m_CursorMoved; }
+ /** Calculates new layout for the list, like Draw() but does not
+ actually draw it.
+ @param dc the wxDC to draw on
+ @param bottom optional y coordinate where to stop calculating
+ */
+ void Layout(wxDC &dc, CoordType bottom = -1) const;
+ /** Returns the size of the list in screen coordinates.
+ The return value only makes sense after the list has been
+ drawn.
+ @return a wxPoint holding the maximal x/y coordinates used for
+ drawing
+ */
+ wxPoint GetSize(void) const;
- /// called after the contents is saved, for example
- void ResetDirty() { m_bModified = FALSE; }
+ /** Returns the cursor position on the screen.
+ @return cursor position in pixels
+ */
+ wxPoint GetCursorScreenPos(void) const
+ { return m_CursorScreenPos; }
+
+ /** Draws the cursor.
+ @param active If true, draw a bold cursor to mark window as
+ active.
+ @param translate optional translation of cursor coords on screen
+ */
+ void DrawCursor(wxDC &dc,
+ bool active = true,
+ const wxPoint & translate = wxPoint(0,0));
+
+ /** This function finds an object belonging to a given cursor
+ position. It assumes that Layout() has been called before.
+ @param pos screen position
+ @return pointer to the object
+ */
+ wxLayoutObject * FindObject(wxPoint const pos);
- /// for access by wxLayoutWindow:
- void GetSize(CoordType *max_x, CoordType *max_y,
- CoordType *lineHeight);
+ //@}
-
- /**@name Functionality for editing */
+ /**@name For exporting one object after another. */
//@{
- /// set list editable or read only
- void SetEditable(bool editable = true) { m_Editable = editable; }
- /// return true if list is editable
- bool IsEditable(void) const { return m_Editable; }
- /// move cursor, returns true if it could move to the desired position
- bool MoveCursor(int dx = 0, int dy = 0);
- void SetCursor(wxPoint const &p);
- void DrawCursor(wxDC &dc, bool erase = false,wxPoint const &translate = wxPoint(0,0));
- /// Get current cursor position cursor coords
- wxPoint GetCursor(void) const { return m_CursorPos; }
- /// Gets graphical coordinates of cursor
- wxPoint GetCursorCoords(void) const { return m_CursorCoords; }
+ /** Returns a pointer to the first line in the list. */
+ wxLayoutLine *GetFirstLine(void)
+ {
+ wxASSERT(m_FirstLine);
+ return m_FirstLine;
+ }
+ //@}
+private:
+ /// Clear the list.
+ void InternalClear(void);
- /// delete one or more cursor positions
- void Delete(CoordType count = 1);
- void Insert(String const &text);
- void Insert(wxLayoutObjectBase *obj);
- void Clear(int family = wxROMAN, int size=WXLO_DEFAULTFONTSIZE, int style=wxNORMAL, int weight=wxNORMAL,
- int underline=0, char const *fg="black", char const *bg="white");
-
- /// return a pointer to the default settings (dangerous, why?) FIXME:
- wxLayoutObjectCmd const *GetDefaults(void) const { return m_DefaultSetting ; }
+ /// The list of lines.
+ wxLayoutLine *m_FirstLine;
+ /**@name Cursor Management */
+ //@{
+ /// Where the text cursor (column,line) is.
+ wxPoint m_CursorPos;
+ /// The size of the cursor.
+ wxPoint m_CursorSize;
+ /// Where the cursor should be drawn.
+ wxPoint m_CursorScreenPos;
+ /// The line where the cursor is.
+ wxLayoutLine *m_CursorLine;
+ //@}
- /// returns the iterator for the object under the cursor
- wxLayoutObjectList::iterator GetCurrentObject(CoordType *offset =
- NULL)
- { if(offset) *offset = m_CursorOffset; return m_CursorObject; }
-
- // get the length of the line with the object pointed to by i, offs
- // only used to decide whether we are before or after linebreak
- CoordType GetLineLength(wxLayoutObjectList::iterator i,
- CoordType offs = 0);
- wxLayoutPrintout *MakePrintout(wxString const &name);
-
- /// Return maximum X,Y coordinates
- wxPoint GetSize(void) const { return wxPoint(m_MaxX, m_MaxY); }
-
- /// calculates current cursor coordinates, called in Layout()
- void CalculateCursor(wxDC &dc);
-
- /// toggle normal/bold cursor
- void SetBoldCursor(bool bold = true)
- { m_boldCursor = bold; m_CursorMoved = true;}
-//@}
-protected:
- /// font parameters:
+ /** @name Font parameters. */
+ //@{
int m_FontFamily, m_FontStyle, m_FontWeight;
int m_FontPtSize;
bool m_FontUnderline;
wxColour const * m_ColourBG;
/// the default setting:
wxLayoutObjectCmd *m_DefaultSetting;
-
- /// needs recalculation?
- bool m_dirty;
- /// cursor moved
- bool m_CursorMoved;
+ //@}
+};
- /// needs saving (i.e., was modified?)
- bool m_bModified;
- // the currently updated line:
- /// where do we draw next:
- wxPoint m_Position;
- /// the height of the current line:
- CoordType m_LineHeight;
- /// maximum drawn x position so far
- CoordType m_MaxX;
- /// maximum drawn y position:
- CoordType m_MaxY;
-
- //---- this is needed for editing:
- /// where is the text cursor (column,line):
- wxPoint m_CursorPos;
- /// where to draw the cursor
- wxPoint m_CursorCoords;
- /// how large to draw it
- wxPoint m_CursorSize;
- /// object iterator for current cursor position:
- iterator m_CursorObject;
- /// position of cursor within m_CursorObject:
- CoordType m_CursorOffset;
-
- /// to store content overwritten by cursor
- wxMemoryDC m_CursorMemDC;
-
- /// which is the last line
- CoordType m_MaxLine;
- /// can we edit it?
- bool m_Editable;
- /// find the object to the cursor position and returns the offset
- /// in there
- wxLayoutObjectList::iterator FindObjectCursor(wxPoint *cpos, CoordType *offset = NULL);
- /// get the wrap margin
- inline long GetWrapMargin(void) const { return m_WrapMargin; }
- /// do we do wrapping?
- inline bool DoWordWrap(void) const { return m_WrapMargin != -1; }
-private:
- /// Resets the font settings etc to default values
- void ResetSettings(wxDC &dc);
- /// remembers the last cursor position for which FindObjectCursor was called
- wxPoint m_FoundCursor;
- /// remembers the iterator to the object related to m_FoundCursor
- wxLayoutObjectList::iterator m_FoundIterator;
- /// the wrap margin
- long m_WrapMargin;
- /// draw a bold cursor?
- bool m_boldCursor;
-};
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ The wxLayoutPrintout object for printing within the wxWindows print
+ framework.
+
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/** This class implements a wxPrintout for printing a wxLayoutList within
+ the wxWindows printing framework.
+ */
class wxLayoutPrintout: public wxPrintout
{
- public:
- wxLayoutPrintout(wxLayoutList &llist, wxString const & title =
+public:
+ /** Constructor.
+ @param llist pointer to the wxLayoutList to be printed
+ @param title title for PS file or windows
+ */
+ wxLayoutPrintout(wxLayoutList *llist,
+ wxString const & title =
"wxLayout Printout");
+ /** Function which prints the n-th page.
+ @param page the page number to print
+ @return bool true if we are not at end of document yet
+ */
bool OnPrintPage(int page);
+ /** Checks whether page exists in document.
+ @param page number of page
+ @return true if page exists
+ */
bool HasPage(int page);
- bool OnBeginDocument(int startPage, int endPage);
- void GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int
- *selPageTo);
- void OnPreparePrinting(void);
+
+ /** Gets called from wxWindows to find out which pages are existing.
+ I'm not totally sure about the parameters though.
+ @param minPage the first page in the document
+ @param maxPage the last page in the document
+ @param selPageFrom the first page to be printed
+ @param selPageTo the last page to be printed
+ */
+ void GetPageInfo(int *minPage, int *maxPage,
+ int *selPageFrom, int *selPageTo);
protected:
- virtual void DrawHeader(wxDC &dc, wxPoint topleft, wxPoint bottomright, int pageno);
-
+ /** This little function scales the DC so that the printout has
+ roughly the same size as the output on screen.
+ @param dc the wxDC to scale
+ @return the scale that was applied
+ */
+ float ScaleDC(wxDC *dc);
+
+ /* no longer used
+ virtual void DrawHeader(wxDC &dc, wxPoint topleft, wxPoint bottomright, int pageno);
+ */
private:
+ /// The list to print.
wxLayoutList *m_llist;
+ /// Title for PS file or window.
wxString m_title;
+ /// The real paper size.
int m_PageHeight, m_PageWidth;
- // how much we actually print per page
+ /// How much we actually print per page.
int m_PrintoutHeight;
- wxLayoutMargins m_Margins;
+ /// How many pages we need to print.
int m_NumOfPages;
+ /// Top left corner where we start printing.
+ wxPoint m_Offset;
};
+
#endif // WXLLIST_H
(((*p == '\r') && (*(p + 1) == '\n'))||(*p == '\n'));
}
-void wxLayoutImportText(wxLayoutList &list, String const &str, int withflag)
+void wxLayoutImportText(wxLayoutList &list, wxString const &str, int withflag)
{
char * cptr = (char *)str.c_str(); // string gets changed only temporarily
const char * begin = cptr;
}
static
-String wxLayoutExportCmdAsHTML(wxLayoutObjectCmd const & cmd,
- wxLayoutStyleInfo **lastStylePtr)
+wxString wxLayoutExportCmdAsHTML(wxLayoutObjectCmd const & cmd,
+ wxLayoutStyleInfo *styleInfo)
{
static char buffer[20];
- String html;
+ wxString html;
- wxLayoutStyleInfo *si = cmd.GetStyle();
- wxLayoutStyleInfo *last_si = NULL;
+ wxLayoutStyleInfo si;
+ cmd.GetStyle(&si);
int size, sizecount;
- if(lastStylePtr != NULL)
- last_si = *lastStylePtr;
-
html += "<font ";
html +="color=";
- sprintf(buffer,"\"#%02X%02X%02X\"", si->fg_red,si->fg_green,si->fg_blue);
+ sprintf(buffer,"\"#%02X%02X%02X\"", si.fg_red,si.fg_green,si.fg_blue);
html += buffer;
html += " bgcolor=";
- sprintf(buffer,"\"#%02X%02X%02X\"", si->bg_red,si->bg_green,si->bg_blue);
+ sprintf(buffer,"\"#%02X%02X%02X\"", si.bg_red,si.bg_green,si.bg_blue);
html += buffer;
- switch(si->family)
+ switch(si.family)
{
case wxSWISS:
case wxMODERN:
}
size = BASE_SIZE; sizecount = 0;
- while(size < si->size && sizecount < 5)
+ while(size < si.size && sizecount < 5)
{
sizecount ++;
size = (size*12)/10;
}
- while(size > si->size && sizecount > -5)
+ while(size > si.size && sizecount > -5)
{
sizecount --;
size = (size*10)/12;
html +=">";
- if(last_si != NULL)
+ if(styleInfo != NULL)
html ="</font>"+html; // terminate any previous font command
- if((si->weight == wxBOLD) && ( (!last_si) || (last_si->weight != wxBOLD)))
+ if((si.weight == wxBOLD) && ( (!styleInfo) || (styleInfo->weight != wxBOLD)))
html += "<b>";
else
- if(si->weight != wxBOLD && ( last_si && (last_si->weight == wxBOLD)))
+ if(si.weight != wxBOLD && ( styleInfo && (styleInfo->weight == wxBOLD)))
html += "</b>";
- if(si->style == wxSLANT)
- si->style = wxITALIC; // the same for html
+ if(si.style == wxSLANT)
+ si.style = wxITALIC; // the same for html
- if((si->style == wxITALIC) && ( (!last_si) || (last_si->style != wxITALIC)))
+ if((si.style == wxITALIC) && ( (!styleInfo) || (styleInfo->style != wxITALIC)))
html += "<i>";
else
- if(si->style != wxITALIC && ( last_si && (last_si->style == wxITALIC)))
+ if(si.style != wxITALIC && ( styleInfo && (styleInfo->style == wxITALIC)))
html += "</i>";
- if(si->underline && ( (!last_si) || ! last_si->underline))
+ if(si.underline && ( (!styleInfo) || ! styleInfo->underline))
html += "<u>";
- else if(si->underline == false && ( last_si && last_si->underline))
+ else if(si.underline == false && ( styleInfo && styleInfo->underline))
html += "</u>";
+
+
+ *styleInfo = si; // update last style info
- if(last_si)
- delete last_si;
- *lastStylePtr = si;
return html;
}
#define WXLO_IS_TEXT(type) \
-( (type == WXLO_TYPE_TEXT || type == WXLO_TYPE_LINEBREAK) \
+( type == WXLO_TYPE_TEXT \
|| (type == WXLO_TYPE_CMD \
&& (mode & WXLO_EXPORT_AS_MASK) == WXLO_EXPORT_AS_HTML))
-wxLayoutExportObject *wxLayoutExport(wxLayoutList &list,
- wxLayoutList::iterator &from,
+wxLayoutExportObject *wxLayoutExport(wxLayoutExportStatus *status,
int mode)
{
- if(from == list.end())
- return NULL;
-
- wxLayoutObjectType type = (*from)->GetType();
- wxLayoutExportObject * export = new wxLayoutExportObject();
+ wxASSERT(status);
+ wxLayoutExportObject * export;
- static wxLayoutStyleInfo *s_si = NULL;
+ if(status->m_iterator == NULLIT) // end of line
+ {
+ if(!status->m_line || status->m_line->GetNextLine() == NULL) // reached end of list
+ return NULL;
+ else
+ {
+ status->m_line = status->m_line->GetNextLine();
+ status->m_iterator = status->m_line->GetFirstObject();
+ export = new wxLayoutExportObject();;
+ export->type = ((mode & WXLO_EXPORT_AS_MASK) == WXLO_EXPORT_AS_HTML)
+ ? WXLO_EXPORT_HTML : WXLO_EXPORT_TEXT;
+ if((mode & WXLO_EXPORT_WITH_CRLF) == WXLO_EXPORT_WITH_CRLF)
+ export->content.text = new wxString("\r\n");
+ else
+ export->content.text = new wxString("\n");
+ return export;
+ }
+ }
+ export = new wxLayoutExportObject();
+ wxLayoutObjectType type = (** status->m_iterator).GetType();
if( (mode & WXLO_EXPORT_AS_MASK) == WXLO_EXPORT_AS_OBJECTS || ! WXLO_IS_TEXT(type)) // simple case
{
export->type = WXLO_EXPORT_OBJECT;
- export->content.object = *from;
- from++;
+ export->content.object = *status->m_iterator;
+ status->m_iterator++;
return export;
}
- String *str = new String();
-
+ // else: must be text
+ wxString *str = new wxString();
// text must be concatenated
- while(from != list.end() && WXLO_IS_TEXT(type))
+ do
{
switch(type)
{
case WXLO_TYPE_TEXT:
- *str += ((wxLayoutObjectText *)*from)->GetText();
- break;
- case WXLO_TYPE_LINEBREAK:
- if((mode & WXLO_EXPORT_AS_MASK) == WXLO_EXPORT_AS_HTML)
- *str += "<br>";
- if((mode & WXLO_EXPORT_WITH_CRLF) == WXLO_EXPORT_WITH_CRLF)
- *str += "\r\n";
- else
- *str += '\n';
+ *str += ((wxLayoutObjectText *)*status->m_iterator)->GetText();
break;
case WXLO_TYPE_CMD:
wxASSERT_MSG( (mode&WXLO_EXPORT_AS_MASK) == WXLO_EXPORT_AS_HTML,
"reached cmd object in text mode" );
*str += wxLayoutExportCmdAsHTML(*(wxLayoutObjectCmd const
- *)*from, &s_si);
+ *)*status->m_iterator, & status->m_si);
break;
default: // ignore icons
;
}
- from++;
- if(from != list.end())
- type = (*from)->GetType();
+ status->m_iterator++;
+ if(status->m_iterator == NULLIT) // end of line!
+ {
+ if((mode & WXLO_EXPORT_AS_MASK) == WXLO_EXPORT_AS_HTML)
+ *str += "<br>";
+ if((mode & WXLO_EXPORT_WITH_CRLF) == WXLO_EXPORT_WITH_CRLF)
+ *str += "\r\n";
+ else
+ *str += '\n';
+ status->m_line = status->m_line->GetNextLine();
+ if(status->m_line)
+ status->m_iterator = status->m_line->GetFirstObject();
+ else
+ status->m_iterator = NULLIT;
+ }
+ if(status->m_iterator != NULLIT)
+ type = (** status->m_iterator).GetType();
+ else
+ break;
}
- export->type = ((mode & WXLO_EXPORT_AS_MASK) == WXLO_EXPORT_AS_HTML) ? WXLO_EXPORT_HTML : WXLO_EXPORT_TEXT;
+ while(WXLO_IS_TEXT(type));
+
+ export->type = ((mode & WXLO_EXPORT_AS_MASK) == WXLO_EXPORT_AS_HTML)
+ ? WXLO_EXPORT_HTML : WXLO_EXPORT_TEXT;
export->content.text = str;
return export;
}
+
wxLayoutExportType type;
union
{
- String *text;
- wxLayoutObjectBase *object;
+ wxString *text;
+ wxLayoutObject *object;
}content;
~wxLayoutExportObject()
{
}
};
+struct wxLayoutExportStatus
+{
+ wxLayoutExportStatus(wxLayoutList *list)
+ {
+ list->GetDefaults()->GetStyle(&m_si);
+ m_line = list->GetFirstLine();
+ m_iterator = m_line->GetFirstObject();
+ }
+
+ wxLayoutLine * m_line;
+ wxLOiterator m_iterator;
+ wxLayoutStyleInfo m_si;
+};
+
+
#ifdef OS_WIN
/// import text into a wxLayoutList (including linefeeds):
-void wxLayoutImportText(wxLayoutList &list, String const &str,
+void wxLayoutImportText(wxLayoutList &list, wxString const &str,
int withflag = WXLO_EXPORT_WITH_CRLF);
wxLayoutExportObject *wxLayoutExport(wxLayoutList &list,
- wxLayoutList::iterator &from,
int mode = WXLO_EXPORT_AS_TEXT|WXLO_EXPORT_WITH_CRLF);
#else
/// import text into a wxLayoutList (including linefeeds):
-void wxLayoutImportText(wxLayoutList &list, String const &str,
+void wxLayoutImportText(wxLayoutList &list, wxString const &str,
int withflag = WXLO_EXPORT_WITH_LF_ONLY);
-wxLayoutExportObject *wxLayoutExport(wxLayoutList &list,
- wxLayoutList::iterator &from,
- int mode = WXLO_EXPORT_AS_TEXT|WXLO_EXPORT_WITH_LF_ONLY);
+/// export text in a given format FIXME-MT: not thread safe, uses static variable
+wxLayoutExportObject *wxLayoutExport(wxLayoutExportStatus *status,
+ int mode = WXLO_EXPORT_AS_TEXT|WXLO_EXPORT_WITH_LF_ONLY
+ );
#endif
#endif //WXLPARSER_H
/*-*- c++ -*-********************************************************
* wxLwindow.h : a scrolled Window for displaying/entering rich text*
* *
- * (C) 1998, 1999 by Karsten Ballüder (Ballueder@usa.net) *
+ * (C) 1998, 1999 by Karsten Ballüder (Ballueder@usa.net) *
* *
* $Id$
*******************************************************************/
//#include "Mpch.h"
-#ifdef M_PREFIX
+#ifdef M_BASEDIR
# ifndef USE_PCH
# include "Mcommon.h"
# include "gui/wxMenuDefs.h"
#else
# ifdef __WXMSW__
# include <windows.h>
-
# undef FindWindow
# undef GetCharWidth
# undef StartDoc
# endif
-
# include "wxlwindow.h"
-# define TRACEMESSAGE(x)
#endif
-# define WXL_VAR(x) { wxString s; s << #x " = " << x; wxLogDebug(s); }
BEGIN_EVENT_TABLE(wxLayoutWindow,wxScrolledWindow)
EVT_PAINT (wxLayoutWindow::OnPaint)
EVT_CHAR (wxLayoutWindow::OnChar)
-
EVT_LEFT_DOWN(wxLayoutWindow::OnLeftMouseClick)
EVT_RIGHT_DOWN(wxLayoutWindow::OnRightMouseClick)
EVT_LEFT_DCLICK(wxLayoutWindow::OnMouseDblClick)
+ EVT_MENU_RANGE(WXLOWIN_MENU_FIRST, WXLOWIN_MENU_LAST, wxLayoutWindow::OnMenu)
+ EVT_SET_FOCUS(wxLayoutWindow::OnSetFocus)
+ EVT_KILL_FOCUS(wxLayoutWindow::OnKillFocus)
+END_EVENT_TABLE()
+ /*
+
EVT_MENU(WXLOWIN_MENU_LARGER, wxLayoutWindow::OnMenu)
EVT_MENU(WXLOWIN_MENU_SMALLER, wxLayoutWindow::OnMenu)
- EVT_MENU(WXLOWIN_MENU_UNDERLINE, wxLayoutWindow::OnMenu)
- EVT_MENU(WXLOWIN_MENU_BOLD, wxLayoutWindow::OnMenu)
- EVT_MENU(WXLOWIN_MENU_ITALICS, wxLayoutWindow::OnMenu)
+ EVT_MENU(WXLOWIN_MENU_UNDERLINE_ON, wxLayoutWindow::OnMenu)
+ EVT_MENU(WXLOWIN_MENU_UNDERLINE_OFF, wxLayoutWindow::OnMenu)
+ EVT_MENU(WXLOWIN_MENU_BOLD_ON, wxLayoutWindow::OnMenu)
+ EVT_MENU(WXLOWIN_MENU_BOLD_OFF, wxLayoutWindow::OnMenu)
+ EVT_MENU(WXLOWIN_MENU_ITALICS_ON, wxLayoutWindow::OnMenu)
+ EVT_MENU(WXLOWIN_MENU_ITALICS_OFF, wxLayoutWindow::OnMenu)
EVT_MENU(WXLOWIN_MENU_ROMAN, wxLayoutWindow::OnMenu)
EVT_MENU(WXLOWIN_MENU_TYPEWRITER, wxLayoutWindow::OnMenu)
EVT_MENU(WXLOWIN_MENU_SANSSERIF, wxLayoutWindow::OnMenu)
- EVT_SET_FOCUS(wxLayoutWindow::OnSetFocus)
- EVT_KILL_FOCUS(wxLayoutWindow::OnKillFocus)
-END_EVENT_TABLE()
+ */
wxLayoutWindow::wxLayoutWindow(wxWindow *parent)
: wxScrolledWindow(parent, -1, wxDefaultPosition, wxDefaultSize,
wxHSCROLL | wxVSCROLL | wxBORDER)
{
+ m_Editable = false;
m_doSendEvents = false;
m_ViewStartX = 0; m_ViewStartY = 0;
m_DoPopupMenu = true;
- m_PopupMenu = NULL;
+ m_PopupMenu = MakeFormatMenu();
m_memDC = new wxMemoryDC;
m_bitmap = new wxBitmap(4,4);
m_bitmapSize = wxPoint(4,4);
-
- CoordType
- max_x, max_y, lineHeight;
- m_llist.GetSize(&max_x, &max_y, &lineHeight);
- SetScrollbars(10, lineHeight, max_x/10+1, max_y/lineHeight+1);
+ m_llist = new wxLayoutList();
+ wxPoint max = m_llist->GetSize();
+ SetScrollbars(10, 20 /*lineHeight*/, max.x/10+1, max.y/20+1);
EnableScrolling(true,true);
- m_maxx = max_x; m_maxy = max_y; m_lineHeight = lineHeight;
+ m_maxx = max.x; m_maxy = max.y;
+ SetDirty();
}
wxLayoutWindow::~wxLayoutWindow()
{
delete m_memDC; // deletes bitmap automatically (?)
delete m_bitmap;
- if(m_PopupMenu) delete m_PopupMenu;
+ delete m_llist;
+ delete m_PopupMenu;
}
#ifdef __WXMSW__
}
#endif //MSW
-void
-wxLayoutWindow::Update(void)
-{
- if(IsDirty())
- {
- UpdateScrollbars();
- DoPaint();
- }
- else
- DoPaint(true); // only the cursor
- return;
-}
-
void
wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
{
findPos.x = dc.DeviceToLogicalX(event.GetX());
findPos.y = dc.DeviceToLogicalY(event.GetY());
- TRACEMESSAGE(("wxLayoutWindow::OnMouse: (%d, %d) -> (%d, %d)",
- event.GetX(), event.GetY(), findPos.x, findPos.y));
+#ifdef WXLAYOUT_DEBUG
+ wxLogDebug("wxLayoutWindow::OnMouse: (%d, %d) -> (%d, %d)",
+ event.GetX(), event.GetY(), findPos.x, findPos.y);
+#endif
m_ClickPosition = findPos;
- wxLayoutObjectBase *obj = m_llist.Find(findPos);
+ wxLayoutObject *obj = m_llist->FindObject(findPos);
+#ifdef WXLAYOUT_DEBUG
+ if(obj)
+ wxLogDebug("wxLayoutWindow::OnMouse: Found object of type %d.",
+ obj->GetType());
+ else
+ wxLogDebug("wxLayoutWindow::OnMouse: Found no object.");
+#endif
+
// only do the menu if activated, editable and not on a clickable object
if(eventId == WXLOWIN_MENU_RCLICK
- && m_DoPopupMenu
- && m_llist.IsEditable()
- && obj && obj->GetUserData() == NULL)
+ && IsEditable()
+ && (! obj || (obj && obj->GetUserData() == NULL))
+ )
{
- // when does this menu get freed?
- // how do we handle toggling? FIXME
- PopupMenu(MakeFormatMenu(), event.GetX(), event.GetY());
+ PopupMenu(m_PopupMenu, event.GetX(), event.GetY());
return;
}
// find the object at this position
}
}
-void
-wxLayoutWindow::DeleteToEndOfLine(void)
-{
- int help = m_llist.GetLineLength(
- m_llist.GetCurrentObject())
- - m_llist.GetCursor().x;
- m_llist.Delete(help>1 ? help-1 : 1);
-}
-
-void
-wxLayoutWindow::GotoEndOfLine(void)
-{
- wxPoint p = m_llist.GetCursor();
- p.x = m_llist.GetLineLength(m_llist.GetCurrentObject());
- if(p.x > 0) p.x --; // do not count the linebreak
- m_llist.SetCursor(p);
-}
-
-void
-wxLayoutWindow::GotoBeginOfLine(void)
-{
- wxPoint p = m_llist.GetCursor();
- p.x = 0;
- m_llist.SetCursor(p);
-}
-
-void
-wxLayoutWindow::DeleteLine(void)
-{
- GotoBeginOfLine();
- DeleteToEndOfLine();
- m_llist.Delete(1); // newline
-}
-
-void
-wxLayoutWindow::DeleteToBeginOfLine(void)
-{
- wxPoint p = m_llist.GetCursor();
- int count = p.x;
- if(count > 0)
- {
- p.x = 0;
- m_llist.SetCursor(p);
- m_llist.Delete(count);
- }
-}
-
-
-void
-wxLayoutWindow::ScrollToCursor(void)
-{
- /** Scroll so that cursor is visible! */
- int x0,y0,x1,y1,ux,uy;
- ViewStart(&x0,&y0);
- GetScrollPixelsPerUnit(&ux,&uy);
- x0*=ux; y0*=uy;
- GetClientSize(&x1,&y1);
-
- wxPoint cc = m_llist.GetCursorCoords();
-
- if(cc.x < x0 || cc.y < y0
- || cc.x >= x0+(9*x1)/10 || cc.y >= y0+(9*y1/10)) // (9*x)/10 == 90%
- {
- int nx, ny;
- nx = cc.x - (8*x1)/10; if(nx < 0) nx = 0;
- ny = cc.y - (8*y1)/10; if(ny < 0) ny = 0;
- Scroll(nx/ux,ny/uy);
- }
-}
-
/*
- * some simple keyboard handling
+ * Some simple keyboard handling.
*/
void
wxLayoutWindow::OnChar(wxKeyEvent& event)
{
- if(! m_llist.IsEditable()) // do nothing
+ if(!IsEditable()) // do nothing
{
event.Skip();
return;
long keyCode = event.KeyCode();
/* First, handle control keys */
- if(event.ControlDown())
+ if(event.ControlDown() && ! event.AltDown())
{
switch(event.KeyCode())
{
case WXK_DELETE :
- case 'k':
- DeleteToEndOfLine(); break;
case 'd':
- m_llist.Delete(1); break;
+ m_llist->Delete(1);
+ break;
case 'y':
- DeleteLine(); break;
+ m_llist->DeleteLines(1);
+ break;
case 'h': // like backspace
- if(m_llist.MoveCursor(-1))
- m_llist.Delete(1);
+ if(m_llist->MoveCursorHorizontally(-1)) m_llist->Delete(1);
break;
case 'u':
- DeleteToBeginOfLine(); break;
+ m_llist->DeleteToBeginOfLine();
+ break;
+ case 'k':
+ m_llist->DeleteToEndOfLine();
+ break;
default:
;
}
}
- else // no control keys
+ // ALT only:
+ else if( event.AltDown() && ! event.ControlDown() )
+ {
+ switch(event.KeyCode())
+ {
+ case WXK_DELETE:
+ case 'd':
+ m_llist->DeleteWord();
+ break;
+ default:
+ ;
+ }
+ }
+ // no control keys:
+ else if ( ! event.AltDown() && ! event.ControlDown())
{
switch(event.KeyCode())
{
case WXK_RIGHT:
- m_llist.MoveCursor(1);
+ m_llist->MoveCursorHorizontally(1);
break;
case WXK_LEFT:
- m_llist.MoveCursor(-1);
+ m_llist->MoveCursorHorizontally(-1);
break;
case WXK_UP:
- m_llist.MoveCursor(0,-1);
+ m_llist->MoveCursorVertically(-1);
break;
case WXK_DOWN:
- m_llist.MoveCursor(0,1);
+ m_llist->MoveCursorVertically(1);
break;
case WXK_PRIOR:
- m_llist.MoveCursor(0,-20);
+ m_llist->MoveCursorVertically(-20);
break;
case WXK_NEXT:
- m_llist.MoveCursor(0,20);
+ m_llist->MoveCursorVertically(20);
break;
case WXK_HOME:
- GotoBeginOfLine();
+ m_llist->MoveCursorToBeginOfLine();
break;
case WXK_END:
- GotoEndOfLine();
+ m_llist->MoveCursorToEndOfLine();
break;
case WXK_DELETE :
- if(event.ControlDown()) // delete to end of line
- DeleteToEndOfLine();
- else
- m_llist.Delete(1);
+ m_llist->Delete(1);
break;
case WXK_BACK: // backspace
- if(m_llist.MoveCursor(-1)) {
- m_llist.Delete(1);
- }
+ if(m_llist->MoveCursorHorizontally(-1)) m_llist->Delete(1);
break;
case WXK_RETURN:
- m_llist.LineBreak();
+ m_llist->LineBreak();
break;
-
-#ifdef WXLAYOUT_DEBUG
- case WXK_F1:
- m_llist.Debug();
- break;
- case WXK_F2:
- m_llist.WrapLine();
- break;
-#endif
-
default:
if((!(event.ControlDown() || event.AltDown() || event.MetaDown()))
&& (keyCode < 256 && keyCode >= 32)
)
{
- String tmp;
+ wxString tmp;
tmp += keyCode;
- m_llist.Insert(tmp);
- m_llist.WrapLine();
+ m_llist->Insert(tmp);
+//// m_llist->WrapLine();
}
break;
}
}
-
- ScrollToCursor();
- Update();
- ScrollToCursor();
+ SetDirty();
+ DoPaint(true); // paint and scroll to cursor
}
void
}
void
-wxLayoutWindow::DoPaint(bool cursorOnly) // or: OnDraw(wxDC& dc)
+wxLayoutWindow::DoPaint(bool scrollToCursor)
{
wxPaintDC dc( this );
PrepareDC( dc );
- // wxGTK: wxMemoryDC broken? YES!!
int x0,y0,x1,y1, dx, dy;
+
+ // Calculate where the top of the visible area is:
ViewStart(&x0,&y0);
- GetClientSize(&x1,&y1); // this is the size of the visible window
- wxASSERT(x1 > 0);
- wxASSERT(y1 > 0);
GetScrollPixelsPerUnit(&dx, &dy);
x0 *= dx; y0 *= dy;
- //FIXME: trying an offset for small border:
- wxPoint offset(-x0+4,-y0+4);
- //Blit() doesn't work on scrolled window!
- // So we have to draw the cursor on the memdc.
- //if(! cursorOnly)
+ // Get the size of the visible window:
+ GetClientSize(&x1,&y1);
+ wxASSERT(x1 > 0);
+
+ wxASSERT(y1 > 0);
+
+ // Maybe we need to change the scrollbar sizes or positions,
+ // so layout the list and check:
+ if(IsDirty() || scrollToCursor)
+ m_llist->Layout(dc);
+ if(IsDirty())
+ ResizeScrollbars();
+
+ /* Make sure that the scrollbars are at a position so that the
+ cursor is visible if we are editing. */
+ /** Scroll so that cursor is visible! */
+ if(IsEditable() && scrollToCursor)
{
- if(x1 > m_bitmapSize.x || y1 > m_bitmapSize.y)
+ wxPoint cc = m_llist->GetCursorScreenPos();
+ if(cc.x < x0 || cc.y < y0
+ || cc.x >= x0+(9*x1)/10 || cc.y >= y0+(9*y1/10)) // (9*x)/10 == 90%
{
- wxASSERT(m_bitmapSize.x > 0);
- wxASSERT(m_bitmapSize.y > 0);
-
- m_memDC->SelectObject(wxNullBitmap);
- delete m_bitmap;
- m_bitmapSize = wxPoint(x1,y1);
- m_bitmap = new wxBitmap(x1,y1);
- m_memDC->SelectObject(*m_bitmap);
+ int nx, ny;
+ nx = cc.x - x1/2; if(nx < 0) nx = 0;
+ ny = cc.y - y1/2; if(ny < 0) ny = 0;
+ Scroll(nx/dx,ny/dy); // new view start
+ x0 = nx; y0 = ny;
}
- m_memDC->SetDeviceOrigin(0,0);
- m_memDC->Clear();
- if(IsDirty() || m_llist.CursorMoved())
- m_llist.Layout(dc);
+ }
+
+ /* Check whether the window has grown, if so, we need to reallocate
+ the bitmap to be larger. */
+ if(x1 > m_bitmapSize.x || y1 > m_bitmapSize.y)
+ {
+ wxASSERT(m_bitmapSize.x > 0);
+ wxASSERT(m_bitmapSize.y > 0);
- m_llist.EraseAndDraw(*m_memDC,
- wxLayoutObjectList::iterator(NULL),offset);
- m_llist.DrawCursor(*m_memDC,false,offset);
- dc.Blit(x0,y0,x1,y1,m_memDC,0,0,wxCOPY,FALSE);
+ m_memDC->SelectObject(wxNullBitmap);
+ delete m_bitmap;
+ m_bitmapSize = wxPoint(x1,y1);
+ m_bitmap = new wxBitmap(x1,y1);
+ m_memDC->SelectObject(*m_bitmap);
}
+ // Device origins on the memDC are suspect, we translate manually
+ // with the translate parameter of Draw().
+ m_memDC->SetDeviceOrigin(0,0);
+ m_memDC->Clear();
- //FIXME obsolete? ResetDirty();
- UpdateScrollbars();
+ // The +4 give the window a tiny border on the left and top, looks nice.
+ wxPoint offset(-x0+4,-y0+4);
+ m_llist->Draw(*m_memDC,offset);
+ if(IsEditable())
+ m_llist->DrawCursor(*m_memDC,m_HaveFocus,offset);
+ // Now copy everything to the screen:
+ dc.Blit(x0,y0,x1,y1,m_memDC,0,0,wxCOPY,FALSE);
+
+
+ ResetDirty();
}
// change the range and position of scroll bars
void
-wxLayoutWindow::UpdateScrollbars(bool exact)
+wxLayoutWindow::ResizeScrollbars(bool exact)
{
- CoordType
- max_x, max_y, lineHeight;
-
- m_llist.GetSize(&max_x, &max_y, &lineHeight);
+ wxPoint max = m_llist->GetSize();
- if(max_x > m_maxx || max_y > m_maxy || exact)
+ if(max.x > m_maxx || max.y > m_maxy
+ || max.x < (7*m_maxx)/10 || max.y << (7*m_maxy)/10
+ || exact)
{
- if(! exact) // add an extra 50% to the sizes to avoid future updates
+ if(! exact) // add an extra 20% to the sizes to avoid future updates
{
- max_x = (3*max_x)/2;
- max_y = (3*max_y)/2;
+ max.x = (12*max.x)/10; // 12/20 = 120%
+ max.y = (12*max.y)/10;
}
ViewStart(&m_ViewStartX, &m_ViewStartY);
- SetScrollbars(10, 20, max_x/10+1,max_y/20+1,m_ViewStartX,m_ViewStartY,true);
- m_maxx = max_x; m_maxy = max_y;
+ SetScrollbars(10, 20, max.x/10+1,max.y/20+1,m_ViewStartX,m_ViewStartY,true);
+ m_maxx = max.x; m_maxy = max.y;
}
}
-void
-wxLayoutWindow::Print(wxDC &dc)
-{
- if (dc.Ok() && dc.StartDoc((char *)_("Printing message...")))
- {
- //dc.SetUserScale(1.0, 1.0);
- m_llist.Draw(dc);
- dc.EndDoc();
- }
-}
wxMenu *
wxLayoutWindow::MakeFormatMenu()
{
- if(m_PopupMenu)
- return m_PopupMenu;
-
- wxMenu *m = new wxMenu();
+ wxMenu *m = new wxMenu(_("Layout Menu"));
m->Append(WXLOWIN_MENU_LARGER ,_("&Larger"),_("Switch to larger font."), false);
m->Append(WXLOWIN_MENU_SMALLER ,_("&Smaller"),_("Switch to smaller font."), false);
m->AppendSeparator();
- m->Append(WXLOWIN_MENU_UNDERLINE,_("&Underline"),_("Toggle underline mode."), true);
- m->Append(WXLOWIN_MENU_BOLD ,_("&Bold"),_("Toggle bold mode."), true);
- m->Append(WXLOWIN_MENU_ITALICS ,_("&Italics"),_("Toggle italics mode."), true);
+ m->Append(WXLOWIN_MENU_UNDERLINE_ON, _("&Underline on"),_("Activate underline mode."), false);
+ m->Append(WXLOWIN_MENU_UNDERLINE_OFF,_("&Underline off"),_("Deactivate underline mode."), false);
+ m->Append(WXLOWIN_MENU_BOLD_ON ,_("&Bold on"),_("Activate bold mode."), false);
+ m->Append(WXLOWIN_MENU_BOLD_OFF ,_("&Bold off"),_("Deactivate bold mode."), false);
+ m->Append(WXLOWIN_MENU_ITALICS_ON ,_("&Italics on"),_("Activate italics mode."), false);
+ m->Append(WXLOWIN_MENU_ITALICS_OFF ,_("&Italics off"),_("Deactivate italics mode."), false);
m->AppendSeparator();
- m->Append(WXLOWIN_MENU_ROMAN ,_("&Roman"),_("Toggle underline mode."), false);
- m->Append(WXLOWIN_MENU_TYPEWRITER,_("&Typewriter"),_("Toggle bold mode."), false);
- m->Append(WXLOWIN_MENU_SANSSERIF ,_("&Sans Serif"),_("Toggle italics mode."), false);
-
- return m_PopupMenu = m;
+ m->Append(WXLOWIN_MENU_ROMAN ,_("&Roman"),_("Switch to roman font."), false);
+ m->Append(WXLOWIN_MENU_TYPEWRITER,_("&Typewriter"),_("Switch to typewriter font."), false);
+ m->Append(WXLOWIN_MENU_SANSSERIF ,_("&Sans Serif"),_("Switch to sans serif font."), false);
+ return m;
}
void wxLayoutWindow::OnMenu(wxCommandEvent& event)
{
- if(! m_llist.IsEditable())
- return;
-
switch (event.GetId())
{
case WXLOWIN_MENU_LARGER:
- m_llist.SetFontLarger();
- break;
+ m_llist->SetFontLarger(); break;
case WXLOWIN_MENU_SMALLER:
- m_llist.SetFontSmaller();
- break;
- case WXLOWIN_MENU_UNDERLINE:
- m_llist.SetFontUnderline(
- m_PopupMenu->IsChecked(WXLOWIN_MENU_UNDERLINE) ? false : true
- );
- break;
- case WXLOWIN_MENU_BOLD:
- m_llist.SetFontWeight(
- m_PopupMenu->IsChecked(WXLOWIN_MENU_BOLD) ? wxNORMAL : wxBOLD
- );
- case WXLOWIN_MENU_ITALICS:
- m_llist.SetFontStyle(
- m_PopupMenu->IsChecked(WXLOWIN_MENU_ITALICS) ? wxNORMAL : wxITALIC
- );
- break;
+ m_llist->SetFontSmaller(); break;
+ case WXLOWIN_MENU_UNDERLINE_ON:
+ m_llist->SetFontUnderline(true); break;
+ case WXLOWIN_MENU_UNDERLINE_OFF:
+ m_llist->SetFontUnderline(false); break;
+ case WXLOWIN_MENU_BOLD_ON:
+ m_llist->SetFontWeight(wxBOLD); break;
+ case WXLOWIN_MENU_BOLD_OFF:
+ m_llist->SetFontWeight(wxNORMAL); break;
+ case WXLOWIN_MENU_ITALICS_ON:
+ m_llist->SetFontStyle(wxITALIC); break;
+ case WXLOWIN_MENU_ITALICS_OFF:
+ m_llist->SetFontStyle(wxNORMAL); break;
case WXLOWIN_MENU_ROMAN:
- m_llist.SetFontFamily(wxROMAN); break;
+ m_llist->SetFontFamily(wxROMAN); break;
case WXLOWIN_MENU_TYPEWRITER:
- m_llist.SetFontFamily(wxFIXED); break;
+ m_llist->SetFontFamily(wxFIXED); break;
case WXLOWIN_MENU_SANSSERIF:
- m_llist.SetFontFamily(wxSWISS); break;
+ m_llist->SetFontFamily(wxSWISS); break;
}
}
void
wxLayoutWindow::OnSetFocus(wxFocusEvent &ev)
{
- m_llist.SetBoldCursor(true);
- DoPaint(true);
+ m_HaveFocus = true;
+ DoPaint(); // to repaint the cursor
}
void
wxLayoutWindow::OnKillFocus(wxFocusEvent &ev)
{
- m_llist.SetBoldCursor(false);
- Update();
+ m_HaveFocus = true;
+ DoPaint(); // to repaint the cursor
}
/*-*- c++ -*-********************************************************
* wxLwindow.h : a scrolled Window for displaying/entering rich text*
* *
- * (C) 1998 by Karsten Ballüder (Ballueder@usa.net) *
+ * (C) 1998,1999 by Karsten Ballüder (Ballueder@usa.net) *
* *
* $Id$
*******************************************************************/
#include "wxllist.h"
+#ifndef WXLOWIN_MENU_FIRST
+# define WXLOWIN_MENU_FIRST 12000
+#endif
+
enum
{
- WXLOWIN_MENU_LARGER = 12000,
+ WXLOWIN_MENU_LARGER = WXLOWIN_MENU_FIRST,
WXLOWIN_MENU_SMALLER,
- WXLOWIN_MENU_UNDERLINE,
- WXLOWIN_MENU_BOLD,
- WXLOWIN_MENU_ITALICS,
+ WXLOWIN_MENU_UNDERLINE_ON,
+ WXLOWIN_MENU_UNDERLINE_OFF,
+ WXLOWIN_MENU_BOLD_ON,
+ WXLOWIN_MENU_BOLD_OFF,
+ WXLOWIN_MENU_ITALICS_ON,
+ WXLOWIN_MENU_ITALICS_OFF,
WXLOWIN_MENU_ROMAN,
WXLOWIN_MENU_TYPEWRITER,
WXLOWIN_MENU_SANSSERIF,
WXLOWIN_MENU_RCLICK,
WXLOWIN_MENU_LCLICK,
- WXLOWIN_MENU_DBLCLICK
-
+ WXLOWIN_MENU_DBLCLICK,
+ WXLOWIN_MENU_LAST = WXLOWIN_MENU_DBLCLICK
};
+/**
+ This class is a rich text editing widget.
+*/
class wxLayoutWindow : public wxScrolledWindow
{
public:
/// Destructor.
virtual ~wxLayoutWindow();
-
- /* Returns a reference to the wxLayoutList object.
- @return the list
- */
- wxLayoutList & GetLayoutList(void) { return m_llist; }
- // clears the window and sets default parameters:
- void Clear(int family = wxROMAN, int size=12, int style=wxNORMAL, int weight=wxNORMAL,
- int underline=0, char const *fg="black", char const
- *bg="white")
+ /**@name Editing functionality */
+ //@{
+ /// Clears the window and sets default parameters.
+ void Clear(int family = wxROMAN,
+ int size=12,
+ int style=wxNORMAL,
+ int weight=wxNORMAL,
+ int underline=0,
+ char const *fg="black",
+ char const *bg="white")
{
- GetLayoutList().Clear(family,size,style,weight,underline,fg,bg);
- SetBackgroundColour( *GetLayoutList().GetDefaults()->GetBGColour());
- Update();
- m_bDirty = FALSE;
+ GetLayoutList()->Clear(family,size,style,weight,underline,fg,bg);
+ SetBackgroundColour(*GetLayoutList()->GetDefaults()->GetBGColour());
+ SetDirty();
+ DoPaint();
}
- // callbacks
- // NB: these functions are used as event handlers and must not be virtual
- void OnPaint(wxPaintEvent &event);
- void OnLeftMouseClick(wxMouseEvent& event)
- { OnMouse(WXLOWIN_MENU_LCLICK, event); }
- void OnRightMouseClick(wxMouseEvent& event)
- { OnMouse(WXLOWIN_MENU_RCLICK, event); }
- void OnMouseDblClick(wxMouseEvent& event)
- { OnMouse(WXLOWIN_MENU_DBLCLICK, event); }
-
- void OnChar(wxKeyEvent& event);
- void OnMenu(wxCommandEvent& event);
+ /// Enable or disable editing, i.e. processing of keystrokes.
+ void SetEditable(bool toggle) { m_Editable = toggle; }
+ /// Query whether list can be edited by user.
+ bool IsEditable(void) const { return m_Editable; }
+ //@}
+
void EnablePopup(bool enable = true) { m_DoPopupMenu = enable; }
- /// gets called by either Update() or OnPaint()
- void DoPaint(bool cursoronly = false);
+
+ /** Redraws the window.
+ @param scrollToCursor if true, scroll the window so that the
+ cursor becomes visible
+ */
+ void DoPaint(bool scrollToCursor = false);
#ifdef __WXMSW__
virtual long MSWGetDlgCode();
#endif //MSW
/// if exact == false, assume 50% extra size for the future
- void UpdateScrollbars(bool exact = false); // don't change this to true!
- void Print(wxDC &dc);
- wxMenu * MakeFormatMenu(void);
+ void ResizeScrollbars(bool exact = false); // don't change this to true!
/// if the flag is true, we send events when user clicks on embedded objects
inline void SetMouseTracking(bool doIt = true) { m_doSendEvents = doIt; }
- // dirty flag access
- bool IsDirty() const { return m_llist.IsDirty(); }
- void ResetDirty() { m_llist.ResetDirty(); }
+ /* Returns a pointer to the wxLayoutList object.
+ @return the list
+ */
+ wxLayoutList * GetLayoutList(void) { return m_llist; }
+ /**@name Callbacks */
+ //@{
+ void OnPaint(wxPaintEvent &event);
+ void OnChar(wxKeyEvent& event);
+ void OnMenu(wxCommandEvent& event);
+ void OnLeftMouseClick(wxMouseEvent& event) { OnMouse(WXLOWIN_MENU_LCLICK, event); }
+ void OnRightMouseClick(wxMouseEvent& event) { OnMouse(WXLOWIN_MENU_RCLICK, event); }
+ void OnMouseDblClick(wxMouseEvent& event) { OnMouse(WXLOWIN_MENU_DBLCLICK, event); }
void OnSetFocus(wxFocusEvent &ev);
void OnKillFocus(wxFocusEvent &ev);
+ //@}
+
+ /// Creates a wxMenu for use as a format popup.
+ static wxMenu * MakeFormatMenu(void);
+ /// Set dirty flag.
+ void SetDirty(void) { m_Dirty = true; }
protected:
- /// Deletes from cursor to end of line.
- void DeleteToEndOfLine(void);
- /// Deletes everything left of cursor.
- void DeleteToBeginOfLine(void);
- /// Goto end of line.
- void GotoEndOfLine(void);
- /// Goto begin of line.
- void GotoBeginOfLine(void);
- /// Delete Line
- void DeleteLine(void);
+ /**@name Dirty flag handling for optimisations. */
+ //@{
+ /// Query whether window needs redrawing.
+ bool IsDirty(void) const { return m_Dirty; }
+ /// Reset dirty flag.
+ void ResetDirty(void) { m_Dirty = false; }
+ //@}
+protected:
/// generic function for mouse events processing
void OnMouse(int eventId, wxMouseEvent& event);
- /// scroll to cursor
- void ScrollToCursor(void);
-
- /// repaint if needed
- void Update(void);
/// for sending events
wxWindow *m_Parent;
+ /// Shall we send events?
bool m_doSendEvents;
-
- /// the layout list to be displayed
- wxLayoutList m_llist;
-
/// Where does the current view start?
int m_ViewStartX; int m_ViewStartY;
-
- /// do we have unsaved data?
- bool m_bDirty;
-
+ /// Do we currently have the focus?
+ bool m_HaveFocus;
/// do we handle clicks of the right mouse button?
bool m_DoPopupMenu;
/// the menu
int m_maxy;
int m_lineHeight;
private:
+ /// The layout list to be displayed.
+ wxLayoutList *m_llist;
+
+ /// Can user edit the window?
+ bool m_Editable;
+ /// Is list dirty?
+ bool m_Dirty;
wxMemoryDC *m_memDC;
wxBitmap *m_bitmap;
wxPoint m_bitmapSize;