New, rewritten, wxLayout. Almost complete.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1873 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Karsten Ballüder
1999-03-07 21:38:50 +00:00
parent f5ee2e5f8f
commit 43e916c33e
10 changed files with 2152 additions and 1980 deletions

25
user/wxLayout/TODO Normal file
View File

@@ -0,0 +1,25 @@
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

View File

@@ -311,5 +311,5 @@ protected: \
/// define the most commonly used list type once: /// define the most commonly used list type once:
KBLIST_DEFINE(kbStringList, String); KBLIST_DEFINE(kbStringList, String);
#endif #endif
//@}
#endif // KBLIST_H #endif // KBLIST_H

View File

@@ -30,10 +30,10 @@ IMPLEMENT_APP(MyApp)
// MyFrame // 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, ID_PAGE_SETUP, ID_PREVIEW, ID_PRINT_PS,
ID_PRINT_SETUP_PS, ID_PAGE_SETUP_PS,ID_PREVIEW_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 }; ID_WXLAYOUT_DEBUG, ID_QUIT, ID_CLICK, ID_HTML, ID_TEXT, ID_TEST };
@@ -54,7 +54,7 @@ IMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame )
END_EVENT_TABLE() END_EVENT_TABLE()
int orientation = wxPORTRAIT; int orientation = wxPORTRAIT;
MyFrame::MyFrame(void) : 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) )
@@ -66,8 +66,6 @@ MyFrame::MyFrame(void) :
wxMenu *file_menu = new wxMenu; wxMenu *file_menu = new wxMenu;
file_menu->Append( ID_CLEAR, "Clear"); file_menu->Append( ID_CLEAR, "Clear");
file_menu->Append( ID_ADD_SAMPLE, "Example"); 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, "&Print...", "Print");
file_menu->Append(ID_PRINT_SETUP, "Print &Setup...","Setup printer properties"); file_menu->Append(ID_PRINT_SETUP, "Print &Setup...","Setup printer properties");
@@ -85,10 +83,8 @@ MyFrame::MyFrame(void) :
file_menu->Append(ID_NOWRAP, "No-wrap mode", "Deactivate wrapping."); file_menu->Append(ID_NOWRAP, "No-wrap mode", "Deactivate wrapping.");
file_menu->AppendSeparator(); file_menu->AppendSeparator();
// file_menu->Append( ID_DPRINT, "Direct Print");
file_menu->Append( ID_TEXT, "Export Text"); file_menu->Append( ID_TEXT, "Export Text");
file_menu->Append( ID_HTML, "Export HTML"); file_menu->Append( ID_HTML, "Export HTML");
// file_menu->Append( ID_TEST, "Test");
file_menu->Append( ID_QUIT, "Exit"); file_menu->Append( ID_QUIT, "Exit");
wxMenuBar *menu_bar = new wxMenuBar(); wxMenuBar *menu_bar = new wxMenuBar();
@@ -102,75 +98,74 @@ MyFrame::MyFrame(void) :
m_lwin = new wxLayoutWindow(this); m_lwin = new wxLayoutWindow(this);
m_lwin->SetMouseTracking(true); m_lwin->SetMouseTracking(true);
m_lwin->GetLayoutList().SetEditable(true); m_lwin->SetEditable(true);
m_lwin->Clear(wxROMAN,16,wxNORMAL,wxNORMAL, false); m_lwin->Clear(wxROMAN,16,wxNORMAL,wxNORMAL, false);
m_lwin->SetFocus(); m_lwin->SetFocus();
}; };
void void
MyFrame::AddSampleText(wxLayoutList &llist) MyFrame::AddSampleText(wxLayoutList *llist)
{ {
llist.SetFont(wxROMAN,16,wxNORMAL,wxNORMAL, false); llist->SetFont(wxROMAN,16,wxNORMAL,wxNORMAL, false);
llist.Insert("--"); llist->Insert("--");
llist.LineBreak(); llist->LineBreak();
llist.SetFont(wxROMAN); llist->SetFont(wxROMAN);
llist.Insert("The quick brown fox jumps over the lazy dog."); llist->Insert("The quick brown fox jumps over the lazy dog.");
llist.LineBreak(); llist->LineBreak();
llist.Insert("Hello "); llist->Insert("Hello ");
llist.Insert(new wxLayoutObjectIcon(new wxICON(Micon))); llist->Insert(new wxLayoutObjectIcon(new wxICON(Micon)));
llist.LineBreak(); llist->SetFontWeight(wxBOLD);
llist.SetFontWeight(wxBOLD); llist->Insert("World! ");
llist.Insert("World! "); llist->SetFontWeight(wxNORMAL);
llist.SetFontWeight(wxNORMAL); llist->Insert("The quick brown fox jumps...");
llist.Insert("The quick brown fox jumps..."); llist->LineBreak();
llist.LineBreak();
llist.Insert("over the lazy dog."); llist->Insert("over the lazy dog.");
llist.SetFont(-1,-1,-1,-1,true); llist->SetFont(-1,-1,-1,-1,true);
llist.Insert("underlined"); llist->Insert("underlined");
llist.SetFont(-1,-1,-1,-1,false); llist->SetFont(-1,-1,-1,-1,false);
llist.SetFont(wxROMAN); llist->SetFont(wxROMAN);
llist.Insert("This is "); llist->Insert("This is ");
llist.SetFont(-1,-1,-1,wxBOLD); llist.Insert("BOLD "); llist.SetFont(-1,-1,-1,wxNORMAL); llist->SetFont(-1,-1,-1,wxBOLD); llist->Insert("BOLD "); llist->SetFont(-1,-1,-1,wxNORMAL);
llist.Insert("and "); llist->Insert("and ");
llist.SetFont(-1,-1,wxITALIC); llist->SetFont(-1,-1,wxITALIC);
llist.Insert("italics "); llist->Insert("italics ");
llist.SetFont(-1,-1,wxNORMAL); llist->SetFont(-1,-1,wxNORMAL);
llist.LineBreak(); llist->LineBreak();
llist.Insert("and "); llist->Insert("and ");
llist.SetFont(-1,-1,wxSLANT); llist->SetFont(-1,-1,wxSLANT);
llist.Insert("slanted"); llist->Insert("slanted");
llist.SetFont(-1,-1,wxNORMAL); llist->SetFont(-1,-1,wxNORMAL);
llist.Insert(" text."); llist->Insert(" text.");
llist.LineBreak(); llist->LineBreak();
llist.Insert("and "); llist->Insert("and ");
llist.SetFont(-1,-1,-1,-1,-1,"blue"); llist->SetFont(-1,-1,-1,-1,-1,"blue");
llist.Insert("blue"); llist->Insert("blue");
llist.SetFont(-1,-1,-1,-1,-1,"black"); llist->SetFont(-1,-1,-1,-1,-1,"black");
llist.Insert(" and "); llist->Insert(" and ");
llist.SetFont(-1,-1,-1,-1,-1,"green","black"); llist->SetFont(-1,-1,-1,-1,-1,"green","black");
llist.Insert("green on black"); llist->Insert("green on black");
llist.SetFont(-1,-1,-1,-1,-1,"black","white"); llist->SetFont(-1,-1,-1,-1,-1,"black","white");
llist.Insert(" text."); llist->Insert(" text.");
llist.LineBreak(); llist->LineBreak();
llist.SetFont(-1,-1,wxSLANT); llist->SetFont(-1,-1,wxSLANT);
llist.Insert("Slanted"); llist->Insert("Slanted");
llist.SetFont(-1,-1,wxNORMAL); llist->SetFont(-1,-1,wxNORMAL);
llist.Insert(" and normal text and "); llist->Insert(" and normal text and ");
llist.SetFont(-1,-1,wxSLANT); llist->SetFont(-1,-1,wxSLANT);
llist.Insert("slanted"); llist->Insert("slanted");
llist.SetFont(-1,-1,wxNORMAL); llist->SetFont(-1,-1,wxNORMAL);
llist.Insert(" again."); llist->Insert(" again.");
llist.LineBreak(); llist->LineBreak();
// add some more text for testing: // add some more text for testing:
llist.Insert("And here the source for the test program:"); llist->Insert("And here the source for the test program:");
llist.LineBreak(); llist->LineBreak();
llist.SetFont(wxTELETYPE,16); llist->SetFont(wxTELETYPE,16);
char buffer[1024]; char buffer[1024];
FILE *in = fopen("wxLayout.cpp","r"); FILE *in = fopen("wxLayout.cpp","r");
if(in) if(in)
@@ -180,50 +175,31 @@ MyFrame::AddSampleText(wxLayoutList &llist)
fgets(buffer,1024,in); fgets(buffer,1024,in);
if(feof(in)) if(feof(in))
break; break;
llist.Insert(buffer); llist->Insert(buffer);
llist.LineBreak(); llist->LineBreak();
} }
} }
llist->MoveCursorTo(wxPoint(0,0));
m_lwin->SetDirty();
m_lwin->Refresh(); m_lwin->Refresh();
m_lwin->UpdateScrollbars();
llist.SetEditable();
llist.SetCursor(wxPoint(0,0));
} }
void void
MyFrame::Clear(void) MyFrame::Clear(void)
{ {
m_lwin->Clear(wxROMAN,16,wxNORMAL,wxNORMAL, false); 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 ) void MyFrame::OnCommand( wxCommandEvent &event )
{ {
cerr << "id:" << event.GetId() << endl;
switch (event.GetId()) switch (event.GetId())
{ {
case ID_QUIT: case ID_QUIT:
Close( TRUE ); Close( TRUE );
break; break;
case ID_PRINT: case ID_PRINT:
{ {
wxPrinter printer; wxPrinter printer;
wxLayoutPrintout printout(m_lwin->GetLayoutList(),_("M: Printout")); wxLayoutPrintout printout(m_lwin->GetLayoutList(),_("M: Printout"));
if (! printer.Print(this, &printout, TRUE)) if (! printer.Print(this, &printout, TRUE))
@@ -231,28 +207,12 @@ void MyFrame::OnCommand( wxCommandEvent &event )
_("There was a problem with printing the message:\n" _("There was a problem with printing the message:\n"
"perhaps your current printer is not set up correctly?"), "perhaps your current printer is not set up correctly?"),
_("Printing"), wxOK); _("Printing"), wxOK);
} }
break; break;
case ID_NOWRAP: case ID_NOWRAP:
case ID_WRAP: case ID_WRAP:
m_lwin->GetLayoutList().SetWrapMargin( //// m_lwin->GetLayoutList()->SetWrapMargin(
event.GetId() == ID_NOWRAP ? -1 : 40); //// 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();
}
}
break;
case ID_EDIT:
Edit();
break; break;
case ID_ADD_SAMPLE: case ID_ADD_SAMPLE:
AddSampleText(m_lwin->GetLayoutList()); AddSampleText(m_lwin->GetLayoutList());
@@ -260,19 +220,15 @@ void MyFrame::OnCommand( wxCommandEvent &event )
case ID_CLEAR: case ID_CLEAR:
Clear(); Clear();
break; break;
case ID_WXLAYOUT_DEBUG:
m_lwin->GetLayoutList().Debug();
break;
case ID_CLICK: case ID_CLICK:
cerr << "Received click event." << endl; cerr << "Received click event." << endl;
break; break;
case ID_HTML: case ID_HTML:
{ {
wxLayoutExportObject *export; wxLayoutExportObject *export;
wxLayoutList::iterator i = m_lwin->GetLayoutList().begin(); wxLayoutExportStatus status(m_lwin->GetLayoutList());
while((export = wxLayoutExport(m_lwin->GetLayoutList(), while((export = wxLayoutExport( &status, WXLO_EXPORT_AS_HTML)) != NULL)
i,WXLO_EXPORT_AS_HTML)) != NULL)
{ {
if(export->type == WXLO_EXPORT_HTML) if(export->type == WXLO_EXPORT_HTML)
cout << *(export->content.text); cout << *(export->content.text);
@@ -285,10 +241,9 @@ void MyFrame::OnCommand( wxCommandEvent &event )
case ID_TEXT: case ID_TEXT:
{ {
wxLayoutExportObject *export; wxLayoutExportObject *export;
wxLayoutList::iterator i = m_lwin->GetLayoutList().begin(); wxLayoutExportStatus status(m_lwin->GetLayoutList());
while((export = wxLayoutExport(m_lwin->GetLayoutList(), while((export = wxLayoutExport( &status, WXLO_EXPORT_AS_TEXT)) != NULL)
i,WXLO_EXPORT_AS_TEXT)) != NULL)
{ {
if(export->type == WXLO_EXPORT_TEXT) if(export->type == WXLO_EXPORT_TEXT)
cout << *(export->content.text); cout << *(export->content.text);

View File

@@ -31,8 +31,7 @@ class MyFrame: public wxFrame
public: public:
MyFrame(void); MyFrame(void);
void Edit(void); void AddSampleText(wxLayoutList *llist);
void AddSampleText(wxLayoutList &llist);
void Clear(void); void Clear(void);
void OnCommand( wxCommandEvent &event ); void OnCommand( wxCommandEvent &event );

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -32,7 +32,7 @@ inline static bool IsEndOfLine(const char *p, int mode)
(((*p == '\r') && (*(p + 1) == '\n'))||(*p == '\n')); (((*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 char * cptr = (char *)str.c_str(); // string gets changed only temporarily
const char * begin = cptr; const char * begin = cptr;
@@ -63,32 +63,29 @@ void wxLayoutImportText(wxLayoutList &list, String const &str, int withflag)
} }
static static
String wxLayoutExportCmdAsHTML(wxLayoutObjectCmd const & cmd, wxString wxLayoutExportCmdAsHTML(wxLayoutObjectCmd const & cmd,
wxLayoutStyleInfo **lastStylePtr) wxLayoutStyleInfo *styleInfo)
{ {
static char buffer[20]; static char buffer[20];
String html; wxString html;
wxLayoutStyleInfo *si = cmd.GetStyle(); wxLayoutStyleInfo si;
wxLayoutStyleInfo *last_si = NULL; cmd.GetStyle(&si);
int size, sizecount; int size, sizecount;
if(lastStylePtr != NULL)
last_si = *lastStylePtr;
html += "<font "; html += "<font ";
html +="color="; 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 += buffer;
html += " bgcolor="; 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; html += buffer;
switch(si->family) switch(si.family)
{ {
case wxSWISS: case wxSWISS:
case wxMODERN: case wxMODERN:
@@ -102,12 +99,12 @@ String wxLayoutExportCmdAsHTML(wxLayoutObjectCmd const & cmd,
} }
size = BASE_SIZE; sizecount = 0; size = BASE_SIZE; sizecount = 0;
while(size < si->size && sizecount < 5) while(size < si.size && sizecount < 5)
{ {
sizecount ++; sizecount ++;
size = (size*12)/10; size = (size*12)/10;
} }
while(size > si->size && sizecount > -5) while(size > si.size && sizecount > -5)
{ {
sizecount --; sizecount --;
size = (size*10)/12; size = (size*10)/12;
@@ -118,97 +115,124 @@ String wxLayoutExportCmdAsHTML(wxLayoutObjectCmd const & cmd,
html +=">"; html +=">";
if(last_si != NULL) if(styleInfo != NULL)
html ="</font>"+html; // terminate any previous font command 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>"; html += "<b>";
else else
if(si->weight != wxBOLD && ( last_si && (last_si->weight == wxBOLD))) if(si.weight != wxBOLD && ( styleInfo && (styleInfo->weight == wxBOLD)))
html += "</b>"; html += "</b>";
if(si->style == wxSLANT) if(si.style == wxSLANT)
si->style = wxITALIC; // the same for html 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>"; html += "<i>";
else else
if(si->style != wxITALIC && ( last_si && (last_si->style == wxITALIC))) if(si.style != wxITALIC && ( styleInfo && (styleInfo->style == wxITALIC)))
html += "</i>"; html += "</i>";
if(si->underline && ( (!last_si) || ! last_si->underline)) if(si.underline && ( (!styleInfo) || ! styleInfo->underline))
html += "<u>"; html += "<u>";
else if(si->underline == false && ( last_si && last_si->underline)) else if(si.underline == false && ( styleInfo && styleInfo->underline))
html += "</u>"; html += "</u>";
if(last_si)
delete last_si; *styleInfo = si; // update last style info
*lastStylePtr = si;
return html; return html;
} }
#define WXLO_IS_TEXT(type) \ #define WXLO_IS_TEXT(type) \
( (type == WXLO_TYPE_TEXT || type == WXLO_TYPE_LINEBREAK) \ ( type == WXLO_TYPE_TEXT \
|| (type == WXLO_TYPE_CMD \ || (type == WXLO_TYPE_CMD \
&& (mode & WXLO_EXPORT_AS_MASK) == WXLO_EXPORT_AS_HTML)) && (mode & WXLO_EXPORT_AS_MASK) == WXLO_EXPORT_AS_HTML))
wxLayoutExportObject *wxLayoutExport(wxLayoutList &list, wxLayoutExportObject *wxLayoutExport(wxLayoutExportStatus *status,
wxLayoutList::iterator &from,
int mode) int mode)
{ {
if(from == list.end()) wxASSERT(status);
wxLayoutExportObject * export;
if(status->m_iterator == NULLIT) // end of line
{
if(!status->m_line || status->m_line->GetNextLine() == NULL) // reached end of list
return NULL; 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;
}
}
wxLayoutObjectType type = (*from)->GetType(); export = new wxLayoutExportObject();
wxLayoutExportObject * export = new wxLayoutExportObject(); wxLayoutObjectType type = (** status->m_iterator).GetType();
static wxLayoutStyleInfo *s_si = NULL;
if( (mode & WXLO_EXPORT_AS_MASK) == WXLO_EXPORT_AS_OBJECTS || ! WXLO_IS_TEXT(type)) // simple case if( (mode & WXLO_EXPORT_AS_MASK) == WXLO_EXPORT_AS_OBJECTS || ! WXLO_IS_TEXT(type)) // simple case
{ {
export->type = WXLO_EXPORT_OBJECT; export->type = WXLO_EXPORT_OBJECT;
export->content.object = *from; export->content.object = *status->m_iterator;
from++; status->m_iterator++;
return export; return export;
} }
String *str = new String(); // else: must be text
wxString *str = new wxString();
// text must be concatenated // text must be concatenated
while(from != list.end() && WXLO_IS_TEXT(type)) do
{ {
switch(type) switch(type)
{ {
case WXLO_TYPE_TEXT: case WXLO_TYPE_TEXT:
*str += ((wxLayoutObjectText *)*from)->GetText(); *str += ((wxLayoutObjectText *)*status->m_iterator)->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';
break; break;
case WXLO_TYPE_CMD: case WXLO_TYPE_CMD:
wxASSERT_MSG( (mode&WXLO_EXPORT_AS_MASK) == WXLO_EXPORT_AS_HTML, wxASSERT_MSG( (mode&WXLO_EXPORT_AS_MASK) == WXLO_EXPORT_AS_HTML,
"reached cmd object in text mode" ); "reached cmd object in text mode" );
*str += wxLayoutExportCmdAsHTML(*(wxLayoutObjectCmd const *str += wxLayoutExportCmdAsHTML(*(wxLayoutObjectCmd const
*)*from, &s_si); *)*status->m_iterator, & status->m_si);
break; break;
default: // ignore icons default: // ignore icons
; ;
} }
from++; status->m_iterator++;
if(from != list.end()) if(status->m_iterator == NULLIT) // end of line!
type = (*from)->GetType(); {
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;
} }
export->type = ((mode & WXLO_EXPORT_AS_MASK) == WXLO_EXPORT_AS_HTML) ? WXLO_EXPORT_HTML : WXLO_EXPORT_TEXT; if(status->m_iterator != NULLIT)
type = (** status->m_iterator).GetType();
else
break;
}
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; export->content.text = str;
return export; return export;
} }

View File

@@ -41,8 +41,8 @@ struct wxLayoutExportObject
wxLayoutExportType type; wxLayoutExportType type;
union union
{ {
String *text; wxString *text;
wxLayoutObjectBase *object; wxLayoutObject *object;
}content; }content;
~wxLayoutExportObject() ~wxLayoutExportObject()
{ {
@@ -51,22 +51,37 @@ struct 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 #ifdef OS_WIN
/// import text into a wxLayoutList (including linefeeds): /// 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); int withflag = WXLO_EXPORT_WITH_CRLF);
wxLayoutExportObject *wxLayoutExport(wxLayoutList &list, wxLayoutExportObject *wxLayoutExport(wxLayoutList &list,
wxLayoutList::iterator &from,
int mode = WXLO_EXPORT_AS_TEXT|WXLO_EXPORT_WITH_CRLF); int mode = WXLO_EXPORT_AS_TEXT|WXLO_EXPORT_WITH_CRLF);
#else #else
/// import text into a wxLayoutList (including linefeeds): /// 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); int withflag = WXLO_EXPORT_WITH_LF_ONLY);
wxLayoutExportObject *wxLayoutExport(wxLayoutList &list, /// export text in a given format FIXME-MT: not thread safe, uses static variable
wxLayoutList::iterator &from, wxLayoutExportObject *wxLayoutExport(wxLayoutExportStatus *status,
int mode = WXLO_EXPORT_AS_TEXT|WXLO_EXPORT_WITH_LF_ONLY); int mode = WXLO_EXPORT_AS_TEXT|WXLO_EXPORT_WITH_LF_ONLY
);
#endif #endif
#endif //WXLPARSER_H #endif //WXLPARSER_H

View File

@@ -12,7 +12,7 @@
//#include "Mpch.h" //#include "Mpch.h"
#ifdef M_PREFIX #ifdef M_BASEDIR
# ifndef USE_PCH # ifndef USE_PCH
# include "Mcommon.h" # include "Mcommon.h"
# include "gui/wxMenuDefs.h" # include "gui/wxMenuDefs.h"
@@ -22,62 +22,65 @@
#else #else
# ifdef __WXMSW__ # ifdef __WXMSW__
# include <windows.h> # include <windows.h>
# undef FindWindow # undef FindWindow
# undef GetCharWidth # undef GetCharWidth
# undef StartDoc # undef StartDoc
# endif # endif
# include "wxlwindow.h" # include "wxlwindow.h"
# define TRACEMESSAGE(x)
#endif #endif
# define WXL_VAR(x) { wxString s; s << #x " = " << x; wxLogDebug(s); }
BEGIN_EVENT_TABLE(wxLayoutWindow,wxScrolledWindow) BEGIN_EVENT_TABLE(wxLayoutWindow,wxScrolledWindow)
EVT_PAINT (wxLayoutWindow::OnPaint) EVT_PAINT (wxLayoutWindow::OnPaint)
EVT_CHAR (wxLayoutWindow::OnChar) EVT_CHAR (wxLayoutWindow::OnChar)
EVT_LEFT_DOWN(wxLayoutWindow::OnLeftMouseClick) EVT_LEFT_DOWN(wxLayoutWindow::OnLeftMouseClick)
EVT_RIGHT_DOWN(wxLayoutWindow::OnRightMouseClick) EVT_RIGHT_DOWN(wxLayoutWindow::OnRightMouseClick)
EVT_LEFT_DCLICK(wxLayoutWindow::OnMouseDblClick) EVT_LEFT_DCLICK(wxLayoutWindow::OnMouseDblClick)
EVT_MENU(WXLOWIN_MENU_LARGER, wxLayoutWindow::OnMenu) EVT_MENU_RANGE(WXLOWIN_MENU_FIRST, WXLOWIN_MENU_LAST, 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_ROMAN, wxLayoutWindow::OnMenu)
EVT_MENU(WXLOWIN_MENU_TYPEWRITER, wxLayoutWindow::OnMenu)
EVT_MENU(WXLOWIN_MENU_SANSSERIF, wxLayoutWindow::OnMenu)
EVT_SET_FOCUS(wxLayoutWindow::OnSetFocus) EVT_SET_FOCUS(wxLayoutWindow::OnSetFocus)
EVT_KILL_FOCUS(wxLayoutWindow::OnKillFocus) EVT_KILL_FOCUS(wxLayoutWindow::OnKillFocus)
END_EVENT_TABLE() END_EVENT_TABLE()
/*
EVT_MENU(WXLOWIN_MENU_LARGER, wxLayoutWindow::OnMenu)
EVT_MENU(WXLOWIN_MENU_SMALLER, 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)
*/
wxLayoutWindow::wxLayoutWindow(wxWindow *parent) wxLayoutWindow::wxLayoutWindow(wxWindow *parent)
: wxScrolledWindow(parent, -1, wxDefaultPosition, wxDefaultSize, : wxScrolledWindow(parent, -1, wxDefaultPosition, wxDefaultSize,
wxHSCROLL | wxVSCROLL | wxBORDER) wxHSCROLL | wxVSCROLL | wxBORDER)
{ {
m_Editable = false;
m_doSendEvents = false; m_doSendEvents = false;
m_ViewStartX = 0; m_ViewStartY = 0; m_ViewStartX = 0; m_ViewStartY = 0;
m_DoPopupMenu = true; m_DoPopupMenu = true;
m_PopupMenu = NULL; m_PopupMenu = MakeFormatMenu();
m_memDC = new wxMemoryDC; m_memDC = new wxMemoryDC;
m_bitmap = new wxBitmap(4,4); m_bitmap = new wxBitmap(4,4);
m_bitmapSize = wxPoint(4,4); m_bitmapSize = wxPoint(4,4);
m_llist = new wxLayoutList();
CoordType wxPoint max = m_llist->GetSize();
max_x, max_y, lineHeight; SetScrollbars(10, 20 /*lineHeight*/, max.x/10+1, max.y/20+1);
m_llist.GetSize(&max_x, &max_y, &lineHeight);
SetScrollbars(10, lineHeight, max_x/10+1, max_y/lineHeight+1);
EnableScrolling(true,true); 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() wxLayoutWindow::~wxLayoutWindow()
{ {
delete m_memDC; // deletes bitmap automatically (?) delete m_memDC; // deletes bitmap automatically (?)
delete m_bitmap; delete m_bitmap;
if(m_PopupMenu) delete m_PopupMenu; delete m_llist;
delete m_PopupMenu;
} }
#ifdef __WXMSW__ #ifdef __WXMSW__
@@ -89,19 +92,6 @@ wxLayoutWindow::MSWGetDlgCode()
} }
#endif //MSW #endif //MSW
void
wxLayoutWindow::Update(void)
{
if(IsDirty())
{
UpdateScrollbars();
DoPaint();
}
else
DoPaint(true); // only the cursor
return;
}
void void
wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event) wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
{ {
@@ -116,21 +106,29 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
findPos.x = dc.DeviceToLogicalX(event.GetX()); findPos.x = dc.DeviceToLogicalX(event.GetX());
findPos.y = dc.DeviceToLogicalY(event.GetY()); findPos.y = dc.DeviceToLogicalY(event.GetY());
TRACEMESSAGE(("wxLayoutWindow::OnMouse: (%d, %d) -> (%d, %d)", #ifdef WXLAYOUT_DEBUG
event.GetX(), event.GetY(), findPos.x, findPos.y)); wxLogDebug("wxLayoutWindow::OnMouse: (%d, %d) -> (%d, %d)",
event.GetX(), event.GetY(), findPos.x, findPos.y);
#endif
m_ClickPosition = findPos; 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 // only do the menu if activated, editable and not on a clickable object
if(eventId == WXLOWIN_MENU_RCLICK if(eventId == WXLOWIN_MENU_RCLICK
&& m_DoPopupMenu && IsEditable()
&& m_llist.IsEditable() && (! obj || (obj && obj->GetUserData() == NULL))
&& obj && obj->GetUserData() == NULL) )
{ {
// when does this menu get freed? PopupMenu(m_PopupMenu, event.GetX(), event.GetY());
// how do we handle toggling? FIXME
PopupMenu(MakeFormatMenu(), event.GetX(), event.GetY());
return; return;
} }
// find the object at this position // find the object at this position
@@ -143,83 +141,13 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
} }
} }
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 void
wxLayoutWindow::OnChar(wxKeyEvent& event) wxLayoutWindow::OnChar(wxKeyEvent& event)
{ {
if(! m_llist.IsEditable()) // do nothing if(!IsEditable()) // do nothing
{ {
event.Skip(); event.Skip();
return; return;
@@ -228,96 +156,96 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
long keyCode = event.KeyCode(); long keyCode = event.KeyCode();
/* First, handle control keys */ /* First, handle control keys */
if(event.ControlDown()) if(event.ControlDown() && ! event.AltDown())
{ {
switch(event.KeyCode()) switch(event.KeyCode())
{ {
case WXK_DELETE : case WXK_DELETE :
case 'k':
DeleteToEndOfLine(); break;
case 'd': case 'd':
m_llist.Delete(1); break; m_llist->Delete(1);
break;
case 'y': case 'y':
DeleteLine(); break; m_llist->DeleteLines(1);
break;
case 'h': // like backspace case 'h': // like backspace
if(m_llist.MoveCursor(-1)) if(m_llist->MoveCursorHorizontally(-1)) m_llist->Delete(1);
m_llist.Delete(1);
break; break;
case 'u': case 'u':
DeleteToBeginOfLine(); break; m_llist->DeleteToBeginOfLine();
break;
case 'k':
m_llist->DeleteToEndOfLine();
break;
default: 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()) switch(event.KeyCode())
{ {
case WXK_RIGHT: case WXK_RIGHT:
m_llist.MoveCursor(1); m_llist->MoveCursorHorizontally(1);
break; break;
case WXK_LEFT: case WXK_LEFT:
m_llist.MoveCursor(-1); m_llist->MoveCursorHorizontally(-1);
break; break;
case WXK_UP: case WXK_UP:
m_llist.MoveCursor(0,-1); m_llist->MoveCursorVertically(-1);
break; break;
case WXK_DOWN: case WXK_DOWN:
m_llist.MoveCursor(0,1); m_llist->MoveCursorVertically(1);
break; break;
case WXK_PRIOR: case WXK_PRIOR:
m_llist.MoveCursor(0,-20); m_llist->MoveCursorVertically(-20);
break; break;
case WXK_NEXT: case WXK_NEXT:
m_llist.MoveCursor(0,20); m_llist->MoveCursorVertically(20);
break; break;
case WXK_HOME: case WXK_HOME:
GotoBeginOfLine(); m_llist->MoveCursorToBeginOfLine();
break; break;
case WXK_END: case WXK_END:
GotoEndOfLine(); m_llist->MoveCursorToEndOfLine();
break; break;
case WXK_DELETE : case WXK_DELETE :
if(event.ControlDown()) // delete to end of line m_llist->Delete(1);
DeleteToEndOfLine();
else
m_llist.Delete(1);
break; break;
case WXK_BACK: // backspace case WXK_BACK: // backspace
if(m_llist.MoveCursor(-1)) { if(m_llist->MoveCursorHorizontally(-1)) m_llist->Delete(1);
m_llist.Delete(1);
}
break; break;
case WXK_RETURN: case WXK_RETURN:
m_llist.LineBreak(); m_llist->LineBreak();
break; break;
#ifdef WXLAYOUT_DEBUG
case WXK_F1:
m_llist.Debug();
break;
case WXK_F2:
m_llist.WrapLine();
break;
#endif
default: default:
if((!(event.ControlDown() || event.AltDown() || event.MetaDown())) if((!(event.ControlDown() || event.AltDown() || event.MetaDown()))
&& (keyCode < 256 && keyCode >= 32) && (keyCode < 256 && keyCode >= 32)
) )
{ {
String tmp; wxString tmp;
tmp += keyCode; tmp += keyCode;
m_llist.Insert(tmp); m_llist->Insert(tmp);
m_llist.WrapLine(); //// m_llist->WrapLine();
} }
break; break;
} }
} }
SetDirty();
ScrollToCursor(); DoPaint(true); // paint and scroll to cursor
Update();
ScrollToCursor();
} }
void void
@@ -327,26 +255,50 @@ wxLayoutWindow::OnPaint( wxPaintEvent &WXUNUSED(event)) // or: OnDraw(wxDC& dc)
} }
void void
wxLayoutWindow::DoPaint(bool cursorOnly) // or: OnDraw(wxDC& dc) wxLayoutWindow::DoPaint(bool scrollToCursor)
{ {
wxPaintDC dc( this ); wxPaintDC dc( this );
PrepareDC( dc ); PrepareDC( dc );
// wxGTK: wxMemoryDC broken? YES!!
int x0,y0,x1,y1, dx, dy; int x0,y0,x1,y1, dx, dy;
// Calculate where the top of the visible area is:
ViewStart(&x0,&y0); ViewStart(&x0,&y0);
GetClientSize(&x1,&y1); // this is the size of the visible window
wxASSERT(x1 > 0);
wxASSERT(y1 > 0);
GetScrollPixelsPerUnit(&dx, &dy); GetScrollPixelsPerUnit(&dx, &dy);
x0 *= dx; y0 *= 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! // Get the size of the visible window:
// So we have to draw the cursor on the memdc. GetClientSize(&x1,&y1);
//if(! cursorOnly) 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)
{ {
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%
{
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;
}
}
/* 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) if(x1 > m_bitmapSize.x || y1 > m_bitmapSize.y)
{ {
wxASSERT(m_bitmapSize.x > 0); wxASSERT(m_bitmapSize.x > 0);
@@ -358,122 +310,105 @@ wxLayoutWindow::DoPaint(bool cursorOnly) // or: OnDraw(wxDC& dc)
m_bitmap = new wxBitmap(x1,y1); m_bitmap = new wxBitmap(x1,y1);
m_memDC->SelectObject(*m_bitmap); 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->SetDeviceOrigin(0,0);
m_memDC->Clear(); m_memDC->Clear();
if(IsDirty() || m_llist.CursorMoved())
m_llist.Layout(dc);
m_llist.EraseAndDraw(*m_memDC, // The +4 give the window a tiny border on the left and top, looks nice.
wxLayoutObjectList::iterator(NULL),offset); wxPoint offset(-x0+4,-y0+4);
m_llist.DrawCursor(*m_memDC,false,offset); 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); dc.Blit(x0,y0,x1,y1,m_memDC,0,0,wxCOPY,FALSE);
}
//FIXME obsolete? ResetDirty();
UpdateScrollbars(); ResetDirty();
} }
// change the range and position of scroll bars // change the range and position of scroll bars
void void
wxLayoutWindow::UpdateScrollbars(bool exact) wxLayoutWindow::ResizeScrollbars(bool exact)
{ {
CoordType wxPoint max = m_llist->GetSize();
max_x, max_y, lineHeight;
m_llist.GetSize(&max_x, &max_y, &lineHeight); if(max.x > m_maxx || max.y > m_maxy
|| max.x < (7*m_maxx)/10 || max.y << (7*m_maxy)/10
if(max_x > m_maxx || max_y > m_maxy || exact) || 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.x = (12*max.x)/10; // 12/20 = 120%
max_y = (3*max_y)/2; max.y = (12*max.y)/10;
} }
ViewStart(&m_ViewStartX, &m_ViewStartY); ViewStart(&m_ViewStartX, &m_ViewStartY);
SetScrollbars(10, 20, max_x/10+1,max_y/20+1,m_ViewStartX,m_ViewStartY,true); SetScrollbars(10, 20, max.x/10+1,max.y/20+1,m_ViewStartX,m_ViewStartY,true);
m_maxx = max_x; m_maxy = max_y; 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 * wxMenu *
wxLayoutWindow::MakeFormatMenu() wxLayoutWindow::MakeFormatMenu()
{ {
if(m_PopupMenu) wxMenu *m = new wxMenu(_("Layout Menu"));
return m_PopupMenu;
wxMenu *m = new wxMenu();
m->Append(WXLOWIN_MENU_LARGER ,_("&Larger"),_("Switch to larger font."), false); m->Append(WXLOWIN_MENU_LARGER ,_("&Larger"),_("Switch to larger font."), false);
m->Append(WXLOWIN_MENU_SMALLER ,_("&Smaller"),_("Switch to smaller font."), false); m->Append(WXLOWIN_MENU_SMALLER ,_("&Smaller"),_("Switch to smaller font."), false);
m->AppendSeparator(); m->AppendSeparator();
m->Append(WXLOWIN_MENU_UNDERLINE,_("&Underline"),_("Toggle underline mode."), true); m->Append(WXLOWIN_MENU_UNDERLINE_ON, _("&Underline on"),_("Activate underline mode."), false);
m->Append(WXLOWIN_MENU_BOLD ,_("&Bold"),_("Toggle bold mode."), true); m->Append(WXLOWIN_MENU_UNDERLINE_OFF,_("&Underline off"),_("Deactivate underline mode."), false);
m->Append(WXLOWIN_MENU_ITALICS ,_("&Italics"),_("Toggle italics mode."), true); 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->AppendSeparator();
m->Append(WXLOWIN_MENU_ROMAN ,_("&Roman"),_("Toggle underline mode."), false); m->Append(WXLOWIN_MENU_ROMAN ,_("&Roman"),_("Switch to roman font."), false);
m->Append(WXLOWIN_MENU_TYPEWRITER,_("&Typewriter"),_("Toggle bold mode."), false); m->Append(WXLOWIN_MENU_TYPEWRITER,_("&Typewriter"),_("Switch to typewriter font."), false);
m->Append(WXLOWIN_MENU_SANSSERIF ,_("&Sans Serif"),_("Toggle italics mode."), false); m->Append(WXLOWIN_MENU_SANSSERIF ,_("&Sans Serif"),_("Switch to sans serif font."), false);
return m;
return m_PopupMenu = m;
} }
void wxLayoutWindow::OnMenu(wxCommandEvent& event) void wxLayoutWindow::OnMenu(wxCommandEvent& event)
{ {
if(! m_llist.IsEditable())
return;
switch (event.GetId()) switch (event.GetId())
{ {
case WXLOWIN_MENU_LARGER: case WXLOWIN_MENU_LARGER:
m_llist.SetFontLarger(); m_llist->SetFontLarger(); break;
break;
case WXLOWIN_MENU_SMALLER: case WXLOWIN_MENU_SMALLER:
m_llist.SetFontSmaller(); m_llist->SetFontSmaller(); break;
break; case WXLOWIN_MENU_UNDERLINE_ON:
case WXLOWIN_MENU_UNDERLINE: m_llist->SetFontUnderline(true); break;
m_llist.SetFontUnderline( case WXLOWIN_MENU_UNDERLINE_OFF:
m_PopupMenu->IsChecked(WXLOWIN_MENU_UNDERLINE) ? false : true m_llist->SetFontUnderline(false); break;
); case WXLOWIN_MENU_BOLD_ON:
break; m_llist->SetFontWeight(wxBOLD); break;
case WXLOWIN_MENU_BOLD: case WXLOWIN_MENU_BOLD_OFF:
m_llist.SetFontWeight( m_llist->SetFontWeight(wxNORMAL); break;
m_PopupMenu->IsChecked(WXLOWIN_MENU_BOLD) ? wxNORMAL : wxBOLD case WXLOWIN_MENU_ITALICS_ON:
); m_llist->SetFontStyle(wxITALIC); break;
case WXLOWIN_MENU_ITALICS: case WXLOWIN_MENU_ITALICS_OFF:
m_llist.SetFontStyle( m_llist->SetFontStyle(wxNORMAL); break;
m_PopupMenu->IsChecked(WXLOWIN_MENU_ITALICS) ? wxNORMAL : wxITALIC
);
break;
case WXLOWIN_MENU_ROMAN: case WXLOWIN_MENU_ROMAN:
m_llist.SetFontFamily(wxROMAN); break; m_llist->SetFontFamily(wxROMAN); break;
case WXLOWIN_MENU_TYPEWRITER: case WXLOWIN_MENU_TYPEWRITER:
m_llist.SetFontFamily(wxFIXED); break; m_llist->SetFontFamily(wxFIXED); break;
case WXLOWIN_MENU_SANSSERIF: case WXLOWIN_MENU_SANSSERIF:
m_llist.SetFontFamily(wxSWISS); break; m_llist->SetFontFamily(wxSWISS); break;
} }
} }
void void
wxLayoutWindow::OnSetFocus(wxFocusEvent &ev) wxLayoutWindow::OnSetFocus(wxFocusEvent &ev)
{ {
m_llist.SetBoldCursor(true); m_HaveFocus = true;
DoPaint(true); DoPaint(); // to repaint the cursor
} }
void void
wxLayoutWindow::OnKillFocus(wxFocusEvent &ev) wxLayoutWindow::OnKillFocus(wxFocusEvent &ev)
{ {
m_llist.SetBoldCursor(false); m_HaveFocus = true;
Update(); DoPaint(); // to repaint the cursor
} }

View File

@@ -1,7 +1,7 @@
/*-*- c++ -*-******************************************************** /*-*- c++ -*-********************************************************
* wxLwindow.h : a scrolled Window for displaying/entering rich text* * wxLwindow.h : a scrolled Window for displaying/entering rich text*
* * * *
* (C) 1998 by Karsten Ball<6C>der (Ballueder@usa.net) * * (C) 1998,1999 by Karsten Ball<6C>der (Ballueder@usa.net) *
* * * *
* $Id$ * $Id$
*******************************************************************/ *******************************************************************/
@@ -18,22 +18,32 @@
#include "wxllist.h" #include "wxllist.h"
#ifndef WXLOWIN_MENU_FIRST
# define WXLOWIN_MENU_FIRST 12000
#endif
enum enum
{ {
WXLOWIN_MENU_LARGER = 12000, WXLOWIN_MENU_LARGER = WXLOWIN_MENU_FIRST,
WXLOWIN_MENU_SMALLER, WXLOWIN_MENU_SMALLER,
WXLOWIN_MENU_UNDERLINE, WXLOWIN_MENU_UNDERLINE_ON,
WXLOWIN_MENU_BOLD, WXLOWIN_MENU_UNDERLINE_OFF,
WXLOWIN_MENU_ITALICS, WXLOWIN_MENU_BOLD_ON,
WXLOWIN_MENU_BOLD_OFF,
WXLOWIN_MENU_ITALICS_ON,
WXLOWIN_MENU_ITALICS_OFF,
WXLOWIN_MENU_ROMAN, WXLOWIN_MENU_ROMAN,
WXLOWIN_MENU_TYPEWRITER, WXLOWIN_MENU_TYPEWRITER,
WXLOWIN_MENU_SANSSERIF, WXLOWIN_MENU_SANSSERIF,
WXLOWIN_MENU_RCLICK, WXLOWIN_MENU_RCLICK,
WXLOWIN_MENU_LCLICK, 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 class wxLayoutWindow : public wxScrolledWindow
{ {
public: public:
@@ -45,89 +55,89 @@ public:
/// Destructor. /// Destructor.
virtual ~wxLayoutWindow(); virtual ~wxLayoutWindow();
/* Returns a reference to the wxLayoutList object. /**@name Editing functionality */
@return the list //@{
*/ /// Clears the window and sets default parameters.
wxLayoutList & GetLayoutList(void) { return m_llist; } void Clear(int family = wxROMAN,
int size=12,
// clears the window and sets default parameters: int style=wxNORMAL,
void Clear(int family = wxROMAN, int size=12, int style=wxNORMAL, int weight=wxNORMAL, int weight=wxNORMAL,
int underline=0, char const *fg="black", char const int underline=0,
*bg="white") char const *fg="black",
char const *bg="white")
{ {
GetLayoutList().Clear(family,size,style,weight,underline,fg,bg); GetLayoutList()->Clear(family,size,style,weight,underline,fg,bg);
SetBackgroundColour( *GetLayoutList().GetDefaults()->GetBGColour()); SetBackgroundColour(*GetLayoutList()->GetDefaults()->GetBGColour());
Update(); SetDirty();
m_bDirty = FALSE; DoPaint();
} }
// callbacks /// Enable or disable editing, i.e. processing of keystrokes.
// NB: these functions are used as event handlers and must not be virtual void SetEditable(bool toggle) { m_Editable = toggle; }
void OnPaint(wxPaintEvent &event); /// Query whether list can be edited by user.
void OnLeftMouseClick(wxMouseEvent& event) bool IsEditable(void) const { return m_Editable; }
{ 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);
void EnablePopup(bool enable = true) { m_DoPopupMenu = enable; } 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__ #ifdef __WXMSW__
virtual long MSWGetDlgCode(); virtual long MSWGetDlgCode();
#endif //MSW #endif //MSW
/// if exact == false, assume 50% extra size for the future /// if exact == false, assume 50% extra size for the future
void UpdateScrollbars(bool exact = false); // don't change this to true! void ResizeScrollbars(bool exact = false); // don't change this to true!
void Print(wxDC &dc);
wxMenu * MakeFormatMenu(void);
/// if the flag is true, we send events when user clicks on embedded objects /// if the flag is true, we send events when user clicks on embedded objects
inline void SetMouseTracking(bool doIt = true) { m_doSendEvents = doIt; } inline void SetMouseTracking(bool doIt = true) { m_doSendEvents = doIt; }
// dirty flag access /* Returns a pointer to the wxLayoutList object.
bool IsDirty() const { return m_llist.IsDirty(); } @return the list
void ResetDirty() { m_llist.ResetDirty(); } */
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 OnSetFocus(wxFocusEvent &ev);
void OnKillFocus(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:
/**@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: 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);
/// generic function for mouse events processing /// generic function for mouse events processing
void OnMouse(int eventId, wxMouseEvent& event); void OnMouse(int eventId, wxMouseEvent& event);
/// scroll to cursor
void ScrollToCursor(void);
/// repaint if needed
void Update(void);
/// for sending events /// for sending events
wxWindow *m_Parent; wxWindow *m_Parent;
/// Shall we send events?
bool m_doSendEvents; bool m_doSendEvents;
/// the layout list to be displayed
wxLayoutList m_llist;
/// Where does the current view start? /// Where does the current view start?
int m_ViewStartX; int m_ViewStartY; int m_ViewStartX; int m_ViewStartY;
/// Do we currently have the focus?
/// do we have unsaved data? bool m_HaveFocus;
bool m_bDirty;
/// do we handle clicks of the right mouse button? /// do we handle clicks of the right mouse button?
bool m_DoPopupMenu; bool m_DoPopupMenu;
/// the menu /// the menu
@@ -139,6 +149,13 @@ protected:
int m_maxy; int m_maxy;
int m_lineHeight; int m_lineHeight;
private: 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; wxMemoryDC *m_memDC;
wxBitmap *m_bitmap; wxBitmap *m_bitmap;
wxPoint m_bitmapSize; wxPoint m_bitmapSize;