updated wxLayout

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1645 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Karsten Ballüder
1999-02-08 15:20:38 +00:00
parent eebb848a85
commit b38142f370
7 changed files with 463 additions and 252 deletions

View File

@@ -223,7 +223,15 @@ void MyFrame::OnCommand( wxCommandEvent &event )
Close( TRUE ); Close( TRUE );
break; break;
case ID_PRINT: case ID_PRINT:
m_lwin->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; break;
case ID_NOWRAP: case ID_NOWRAP:
case ID_WRAP: case ID_WRAP:

View File

@@ -20,12 +20,15 @@
is four cursor positions long. This makes sure that cursor is four cursor positions long. This makes sure that cursor
positions are "as expected", i.e. in "abc\ndef" the 'd' would be positions are "as expected", i.e. in "abc\ndef" the 'd' would be
at positions (x=0,y=1). 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: TODO:
- cursor redraw problems
- blinking cursor - blinking cursor
- mouse click positions cursor - mouse click positions cursor
- selection (SetMark(), GetSelection()) - selection (SetMark(), GetSelection())
@@ -33,18 +36,13 @@
- wxlwindow: formatting menu: problem with checked/unchecked consistency gtk bug? - wxlwindow: formatting menu: problem with checked/unchecked consistency gtk bug?
*/ */
/*
Known wxGTK bugs:
- MaxX()/MaxY() don't get set
*/
#ifdef __GNUG__ #ifdef __GNUG__
#pragma implementation "wxllist.h" #pragma implementation "wxllist.h"
#endif #endif
//#include "Mpch.h" //#include "Mpch.h"
#ifdef M_BASEDIR #ifdef M_PREFIX
# include "gui/wxllist.h" # include "gui/wxllist.h"
#else #else
# include "wxllist.h" # include "wxllist.h"
@@ -244,7 +242,8 @@ wxLayoutList::wxLayoutList()
m_DefaultSetting = NULL; m_DefaultSetting = NULL;
m_WrapMargin = -1; m_WrapMargin = -1;
m_Editable = FALSE; m_Editable = FALSE;
m_boldCursor = FALSE;
Clear(); Clear();
} }
@@ -259,7 +258,6 @@ void
wxLayoutList::LineBreak(void) wxLayoutList::LineBreak(void)
{ {
Insert(new wxLayoutObjectLineBreak); Insert(new wxLayoutObjectLineBreak);
// m_CursorPos.x = 0; m_CursorPos.y++;
} }
void void
@@ -420,7 +418,7 @@ wxLayoutList::Draw(wxDC &dc,
iterator start, iterator start,
wxPoint const &translate) wxPoint const &translate)
{ {
Layout(dc); // FIXME just for now //Layout(dc); // FIXME just for now
ResetSettings(dc); ResetSettings(dc);
@@ -449,7 +447,7 @@ wxLayoutList::Draw(wxDC &dc,
/** Erase at least to end of line */ /** Erase at least to end of line */
void void
wxLayoutList::EraseAndDraw(wxDC &dc, iterator start) wxLayoutList::EraseAndDraw(wxDC &dc, iterator start, wxPoint const &translate)
{ {
//look for begin of line //look for begin of line
while(start != end() && start != begin() && (**start).GetType() != while(start != end() && start != begin() && (**start).GetType() !=
@@ -468,7 +466,7 @@ wxLayoutList::EraseAndDraw(wxDC &dc, iterator start)
dc.SetBrush(wxBrush(*m_ColourBG, wxSOLID)); dc.SetBrush(wxBrush(*m_ColourBG, wxSOLID));
dc.SetPen(wxPen(*m_ColourBG,0,wxTRANSPARENT)); dc.SetPen(wxPen(*m_ColourBG,0,wxTRANSPARENT));
dc.DrawRectangle(p.x,p.y,2000,2000); //dc.MaxX(),dc.MaxY()); dc.DrawRectangle(p.x,p.y,2000,2000); //dc.MaxX(),dc.MaxY());
Draw(dc,-1,-1,start,wxPoint(0,0)); Draw(dc,-1,-1,start,translate);
//dc.DrawRectangle(p.x,p.y,2000,2000); //dc.MaxX(),dc.MaxY()); //dc.DrawRectangle(p.x,p.y,2000,2000); //dc.MaxX(),dc.MaxY());
} }
@@ -476,13 +474,18 @@ wxLayoutList::EraseAndDraw(wxDC &dc, iterator start)
void void
wxLayoutList::CalculateCursor(wxDC &dc) wxLayoutList::CalculateCursor(wxDC &dc)
{ {
if(! m_CursorMoved)
return;
CoordType width, height, descent; CoordType width, height, descent;
CoordType baseLineSkip = 20; //FIXME CoordType baseLineSkip = 20; //FIXME
int cursorWidth = m_boldCursor ? 4 : 2;
if( m_CursorObject == iterator(NULL)) // empty list if( m_CursorObject == iterator(NULL)) // empty list
{ {
m_CursorCoords = wxPoint(0,0); m_CursorCoords = wxPoint(0,0);
m_CursorSize = wxPoint(2,baseLineSkip); m_CursorSize = wxPoint(cursorWidth,baseLineSkip);
m_CursorMoved = false; // coords are valid m_CursorMoved = false; // coords are valid
return; return;
} }
@@ -497,14 +500,14 @@ wxLayoutList::CalculateCursor(wxDC &dc)
dc.GetTextExtent(sstr,&width,&height,&descent); dc.GetTextExtent(sstr,&width,&height,&descent);
m_CursorCoords = wxPoint(m_CursorCoords.x+width, m_CursorCoords = wxPoint(m_CursorCoords.x+width,
m_CursorCoords.y); m_CursorCoords.y);
m_CursorSize = wxPoint(2,height); m_CursorSize = wxPoint(cursorWidth,height);
} }
else if(obj.GetType() == WXLO_TYPE_LINEBREAK) else if(obj.GetType() == WXLO_TYPE_LINEBREAK)
{ {
if(m_CursorOffset == 1) // behind linebreak if(m_CursorOffset == 1) // behind linebreak
m_CursorCoords = wxPoint(0, m_CursorCoords.y + baseLineSkip); m_CursorCoords = wxPoint(0, m_CursorCoords.y + baseLineSkip);
//m_CursorCoords = wxPoint(0, m_CursorCoords.y); //m_CursorCoords = wxPoint(0, m_CursorCoords.y);
m_CursorSize = wxPoint(2,baseLineSkip); m_CursorSize = wxPoint(cursorWidth,baseLineSkip);
} }
else else
{ {
@@ -512,43 +515,52 @@ wxLayoutList::CalculateCursor(wxDC &dc)
//cursorPosition = wxPoint(position.x, position.y); //cursorPosition = wxPoint(position.x, position.y);
//cursorSize = wxPoint(size.x > 0 ? size.x : 1,size.y > 0 ? size.y : baseLineSkip); //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_CursorCoords = wxPoint(m_CursorCoords.x+obj.GetSize().x, m_CursorCoords.y);
m_CursorSize = wxPoint(2, obj.GetSize().y); m_CursorSize = wxPoint(cursorWidth, obj.GetSize().y);
if(m_CursorSize.y < 1) m_CursorSize.y = baseLineSkip; if(m_CursorSize.y < 1) m_CursorSize.y = baseLineSkip;
} }
m_CursorMoved = false; // coords are valid m_CursorMoved = false; // coords are valid
} }
void void
wxLayoutList::DrawCursor(wxDC &dc, bool erase) wxLayoutList::DrawCursor(wxDC &dc, bool erase, wxPoint const &translate)
{ {
if(! m_Editable) if(! m_Editable)
return; return;
if(erase) if(erase)
{ ;
//dc.SetBrush(*wxWHITE_BRUSH); #if 0
//dc.SetPen(wxPen(*wxWHITE,1,wxSOLID)); dc.Blit(m_CursorCoords.x+translate.x,
//dc.DrawRectangle(m_CursorCoords.x, m_CursorCoords.y, m_CursorSize.x, m_CursorSize.y); m_CursorCoords.y+translate.y,
dc.Blit(m_CursorCoords.x, m_CursorCoords.y, m_CursorSize.x, m_CursorSize.x,m_CursorSize.y,
m_CursorSize.y, &m_CursorMemDC, &m_CursorMemDC,
0, 0, 0, 0); 0, 0, 0, 0);
} #endif
else else
{ {
// erase it at the old position:
if(IsDirty() || CursorMoved()) if(IsDirty() || CursorMoved())
{ {
DrawCursor(dc,true); // 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); Layout(dc);
} }
// Save background: #if 0
// Save background:
wxBitmap bm(m_CursorSize.x+1,m_CursorSize.y+1); wxBitmap bm(m_CursorSize.x+1,m_CursorSize.y+1);
m_CursorMemDC.SelectObject(bm); m_CursorMemDC.SelectObject(bm);
m_CursorMemDC.Blit(0, 0, m_CursorSize.x, m_CursorSize.y, m_CursorMemDC.Blit(0, 0,
&dc, m_CursorCoords.x, m_CursorSize.x, m_CursorSize.y,
m_CursorCoords.y, 0, 0); &dc,
m_CursorCoords.x+translate.x,
m_CursorCoords.y+translate.y, 0, 0);
#endif
// draw it:
dc.SetBrush(*wxBLACK_BRUSH); dc.SetBrush(*wxBLACK_BRUSH);
dc.SetPen(wxPen(*wxBLACK,1,wxSOLID)); dc.SetPen(wxPen(*wxBLACK,1,wxSOLID));
dc.DrawRectangle(m_CursorCoords.x, m_CursorCoords.y, dc.DrawRectangle(m_CursorCoords.x+translate.x, m_CursorCoords.y+translate.y,
m_CursorSize.x, m_CursorSize.y); m_CursorSize.x, m_CursorSize.y);
} }
} }
@@ -713,6 +725,11 @@ wxLayoutList::MoveCursor(int dx, int dy)
if(newPos.y < 0) newPos.y = 0; if(newPos.y < 0) newPos.y = 0;
else if(newPos.y > m_MaxLine) newPos.y = m_MaxLine; 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;
if(newPos.y > m_CursorPos.y || if(newPos.y > m_CursorPos.y ||
newPos.y == m_CursorPos.y && newPos.y == m_CursorPos.y &&
newPos.x >= m_CursorPos.x) newPos.x >= m_CursorPos.x)
@@ -720,7 +737,12 @@ wxLayoutList::MoveCursor(int dx, int dy)
else else
direction = up; direction = up;
wxASSERT(m_CursorObject); if ( !m_CursorObject )
{
// list is empty
return FALSE;
}
// now move cursor forwards until at the new position: // now move cursor forwards until at the new position:
// first, go to the right line: // first, go to the right line:
@@ -758,6 +780,12 @@ wxLayoutList::MoveCursor(int dx, int dy)
newPos.y = m_CursorPos.y; // exited by break newPos.y = m_CursorPos.y; // exited by break
// now line is right, go to right column: // now line is right, go to right column:
if(dx == 0) // we are moving up or down only
{
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
}
direction = newPos.x >= m_CursorPos.x ? down : up; direction = newPos.x >= m_CursorPos.x ? down : up;
while(newPos.x != m_CursorPos.x) while(newPos.x != m_CursorPos.x)
{ {
@@ -819,8 +847,16 @@ wxLayoutList::MoveCursor(int dx, int dy)
} }
} }
} }
return true; // FIXME: when return what? return true; // FIXME: when return what?
} }
void
wxLayoutList::SetCursor(wxPoint const &p)
{
m_CursorPos = p;
m_CursorObject = FindObjectCursor(&m_CursorPos, &m_CursorOffset);
m_CursorMoved = true;
}
void void
wxLayoutList::Delete(CoordType count) wxLayoutList::Delete(CoordType count)
@@ -842,8 +878,8 @@ wxLayoutList::Delete(CoordType count)
if(i == end()) if(i == end())
return; // we cannot delete anything more return; // we cannot delete anything more
/* Here we need to treat linebreaks differently. /* Here we need to treat linebreaks differently.
If m_CursorOffset==0 we are before the linebreak, otherwise behind. */ If m_CursorOffset==0 we are before the linebreak, otherwise behind. */
if((*i)->GetType() == WXLO_TYPE_LINEBREAK) if((*i)->GetType() == WXLO_TYPE_LINEBREAK)
{ {
if(m_CursorOffset == 0) if(m_CursorOffset == 0)
@@ -866,26 +902,32 @@ wxLayoutList::Delete(CoordType count)
{ {
wxLayoutObjectText *tobj = (wxLayoutObjectText *)*i; wxLayoutObjectText *tobj = (wxLayoutObjectText *)*i;
CoordType len = tobj->CountPositions(); CoordType len = tobj->CountPositions();
// If we find the end of a text object, this means that we /* If we find the end of a text object, this means that we
// have to delete from the object following it. have to delete from the object following it. */
if(len == m_CursorOffset) if(len == m_CursorOffset)
{ {
i++; i++;
m_CursorOffset = 0; m_CursorOffset = 0;
goto startover; goto startover;
} }
else if(len <= count) // delete this object
{
count -= len;
erase(i);
m_CursorObject = i;
m_CursorOffset = 0;
continue;
}
else else
{ {
len = count; if(m_CursorOffset == 0 && len <= count) // delete this object
tobj->GetText().erase(m_CursorOffset,len); {
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 // cursor unchanged
return; // we are done return; // we are done
} }
@@ -915,6 +957,7 @@ wxLayoutList::Delete(CoordType count)
while(count && i != end()); while(count && i != end());
} }
void void
wxLayoutList::Insert(wxLayoutObjectBase *obj) wxLayoutList::Insert(wxLayoutObjectBase *obj)
{ {
@@ -1074,7 +1117,10 @@ wxLayoutList::GetLineLength(wxLayoutObjectList::iterator i, CoordType offs)
CoordType len = 0; CoordType len = 0;
if(offs == 0 && (**i).GetType() == WXLO_TYPE_LINEBREAK) if(offs == 0 && (**i).GetType() == WXLO_TYPE_LINEBREAK)
i--; if(i != begin())
i--;
else
return 0; // at begin of buffer in front of a linebreak
// search backwards for beginning of line: // search backwards for beginning of line:
while(i != begin() && (*i)->GetType() != WXLO_TYPE_LINEBREAK) while(i != begin() && (*i)->GetType() != WXLO_TYPE_LINEBREAK)
@@ -1100,7 +1146,7 @@ wxLayoutList::Clear(int family, int size, int style, int weight,
m_dirty = true; // force redraw/recalc m_dirty = true; // force redraw/recalc
wxLayoutObjectList::iterator i = begin(); wxLayoutObjectList::iterator i = begin();
wxBitmap bm(1,1); wxBitmap bm(4,4);
m_CursorMemDC.SelectObject(bm); m_CursorMemDC.SelectObject(bm);
while(i != end()) // == while valid while(i != end()) // == while valid
@@ -1124,7 +1170,7 @@ wxLayoutList::Clear(int family, int size, int style, int weight,
m_CursorOffset = 0; m_CursorOffset = 0;
m_CursorSize = wxPoint(2,(BASELINESTRETCH*m_FontPtSize)/10); m_CursorSize = wxPoint(2,(BASELINESTRETCH*m_FontPtSize)/10);
m_MaxLine = 1; m_MaxLine = 0;
m_LineHeight = (BASELINESTRETCH*m_FontPtSize)/10; m_LineHeight = (BASELINESTRETCH*m_FontPtSize)/10;
m_MaxX = 0; m_MaxY = 0; m_MaxX = 0; m_MaxY = 0;
@@ -1211,8 +1257,8 @@ wxLayoutList::WrapLine(void)
for(; offset > 0; offset--) for(; offset > 0; offset--)
if(t.GetText().c_str()[offset] == ' ' || t.GetText().c_str()[offset] == '\t') if(t.GetText().c_str()[offset] == ' ' || t.GetText().c_str()[offset] == '\t')
{ {
String left = t.GetText().substr(0,offset-1); // get part before cursor String left = t.GetText().substr(0,offset); // get part before cursor
t.GetText() = t.GetText().substr(offset,t.CountPositions()-offset); // keeps the right halve t.GetText() = t.GetText().substr(offset+1,t.CountPositions()-offset-1); // keeps the right halve
insert(i,new wxLayoutObjectLineBreak); insert(i,new wxLayoutObjectLineBreak);
insert(i,new wxLayoutObjectText(left)); // inserts before insert(i,new wxLayoutObjectText(left)); // inserts before
break; break;
@@ -1322,10 +1368,9 @@ wxLayoutPrintout::DrawHeader(wxDC &dc,
int pageno) int pageno)
{ {
// make backups of all essential parameters // make backups of all essential parameters
wxBrush &brush = dc.GetBrush(); const wxBrush& brush = dc.GetBrush();
wxPen &pen = dc.GetPen(); const wxPen& pen = dc.GetPen();
wxFont &font = dc.GetFont(), const wxFont& font = dc.GetFont();
*myfont;
dc.SetBrush(*wxWHITE_BRUSH); dc.SetBrush(*wxWHITE_BRUSH);
dc.SetPen(wxPen(*wxBLACK,0,wxSOLID)); dc.SetPen(wxPen(*wxBLACK,0,wxSOLID));
@@ -1333,8 +1378,9 @@ wxLayoutPrintout::DrawHeader(wxDC &dc,
topleft.y,bottomright.x-topleft.x, topleft.y,bottomright.x-topleft.x,
bottomright.y-topleft.y); bottomright.y-topleft.y);
dc.SetBrush(*wxBLACK_BRUSH); dc.SetBrush(*wxBLACK_BRUSH);
myfont = new wxFont((WXLO_DEFAULTFONTSIZE*12)/10,wxSWISS,wxNORMAL,wxBOLD,false,"Helvetica"); wxFont myfont = wxFont((WXLO_DEFAULTFONTSIZE*12)/10,
dc.SetFont(*myfont); wxSWISS,wxNORMAL,wxBOLD,false,"Helvetica");
dc.SetFont(myfont);
wxString page; wxString page;
page = "9999/9999 "; // many pages... page = "9999/9999 "; // many pages...
@@ -1349,8 +1395,6 @@ wxLayoutPrintout::DrawHeader(wxDC &dc,
dc.SetPen(pen); dc.SetPen(pen);
dc.SetBrush(brush); dc.SetBrush(brush);
dc.SetFont(font); dc.SetFont(font);
delete myfont;
} }

View File

@@ -5,6 +5,8 @@
* * * *
* $Id$ * $Id$
*******************************************************************/ *******************************************************************/
#ifndef WXLLIST_H #ifndef WXLLIST_H
#define WXLLIST_H #define WXLLIST_H
@@ -23,7 +25,7 @@
// skip the following defines if embedded in M application // skip the following defines if embedded in M application
#ifdef M_BASEDIR #ifdef M_BASEDIR
# ifdef DEBUG # ifdef DEBUG
//# define WXLAYOUT_DEBUG # define WXLAYOUT_DEBUG
# endif # endif
#else #else
// for testing only: // for testing only:
@@ -328,7 +330,8 @@ public:
wxPoint const &translate = wxPoint(0,0)); wxPoint const &translate = wxPoint(0,0));
/** Deletes at least to the end of line and redraws */ /** Deletes at least to the end of line and redraws */
void EraseAndDraw(wxDC &dc, iterator start = iterator(NULL)); void EraseAndDraw(wxDC &dc, iterator start = iterator(NULL),
wxPoint const &translate = wxPoint(0,0));
/** Finds the object occupying a certain screen position. /** Finds the object occupying a certain screen position.
@return pointer to wxLayoutObjectBase or NULL if not found @return pointer to wxLayoutObjectBase or NULL if not found
@@ -360,9 +363,8 @@ public:
bool IsEditable(void) const { return m_Editable; } bool IsEditable(void) const { return m_Editable; }
/// move cursor, returns true if it could move to the desired position /// move cursor, returns true if it could move to the desired position
bool MoveCursor(int dx = 0, int dy = 0); bool MoveCursor(int dx = 0, int dy = 0);
void SetCursor(wxPoint const &p) { m_CursorPos = p; } void SetCursor(wxPoint const &p);
void DrawCursor(wxDC &dc, bool erase = false); void DrawCursor(wxDC &dc, bool erase = false,wxPoint const &translate = wxPoint(0,0));
/// Get current cursor position cursor coords /// Get current cursor position cursor coords
wxPoint GetCursor(void) const { return m_CursorPos; } wxPoint GetCursor(void) const { return m_CursorPos; }
/// Gets graphical coordinates of cursor /// Gets graphical coordinates of cursor
@@ -391,6 +393,13 @@ public:
/// Return maximum X,Y coordinates /// Return maximum X,Y coordinates
wxPoint GetSize(void) const { return wxPoint(m_MaxX, m_MaxY); } 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: protected:
/// font parameters: /// font parameters:
@@ -431,7 +440,7 @@ protected:
/// object iterator for current cursor position: /// object iterator for current cursor position:
iterator m_CursorObject; iterator m_CursorObject;
/// position of cursor within m_CursorObject: /// position of cursor within m_CursorObject:
int m_CursorOffset; CoordType m_CursorOffset;
/// to store content overwritten by cursor /// to store content overwritten by cursor
wxMemoryDC m_CursorMemDC; wxMemoryDC m_CursorMemDC;
@@ -450,14 +459,14 @@ protected:
private: private:
/// Resets the font settings etc to default values /// Resets the font settings etc to default values
void ResetSettings(wxDC &dc); void ResetSettings(wxDC &dc);
/// calculates current cursor coordinates, called in Layout()
void CalculateCursor(wxDC &dc);
/// remembers the last cursor position for which FindObjectCursor was called /// remembers the last cursor position for which FindObjectCursor was called
wxPoint m_FoundCursor; wxPoint m_FoundCursor;
/// remembers the iterator to the object related to m_FoundCursor /// remembers the iterator to the object related to m_FoundCursor
wxLayoutObjectList::iterator m_FoundIterator; wxLayoutObjectList::iterator m_FoundIterator;
/// the wrap margin /// the wrap margin
long m_WrapMargin; long m_WrapMargin;
/// draw a bold cursor?
bool m_boldCursor;
}; };
class wxLayoutPrintout: public wxPrintout class wxLayoutPrintout: public wxPrintout

View File

@@ -1,7 +1,7 @@
/*-*- c++ -*-******************************************************** /*-*- c++ -*-********************************************************
* wxlparser.h : parsers, import/export for wxLayoutList * * wxlparser.h : parsers, import/export for wxLayoutList *
* * * *
* (C) 1998 by Karsten Ball<6C>der (Ballueder@usa.net) * * (C) 1998,1999 by Karsten Ball<6C>der (Ballueder@usa.net) *
* * * *
* $Id$ * $Id$
*******************************************************************/ *******************************************************************/
@@ -11,7 +11,7 @@
#endif #endif
//#include "Mpch.h" //#include "Mpch.h"
#ifdef M_BASEDIR #ifdef M_PREFIX
# include "gui/wxllist.h" # include "gui/wxllist.h"
# include "gui/wxlparser.h" # include "gui/wxlparser.h"
#else #else
@@ -21,18 +21,18 @@
#define BASE_SIZE 12 #define BASE_SIZE 12
inline static bool IsEndOfLine(const char *p) inline static bool IsEndOfLine(const char *p, int mode)
{ {
// in addition to Unix EOL convention we also (but not instead) understand // in addition to Unix EOL convention we also (but not instead) understand
// the DOS one under Windows // the DOS one under Windows
return return
#ifdef OS_WIN ((mode & WXLO_EXPORT_WITH_MASK) == WXLO_EXPORT_WITH_CRLF) ?
((*p == '\r') && (*(p + 1) == '\n')) || ((*p == '\r') && (*(p + 1) == '\n'))
#endif :
(*p == '\n'); (((*p == '\r') && (*(p + 1) == '\n'))||(*p == '\n'));
} }
void wxLayoutImportText(wxLayoutList &list, String const &str) void wxLayoutImportText(wxLayoutList &list, String 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;
@@ -41,7 +41,7 @@ void wxLayoutImportText(wxLayoutList &list, String const &str)
for(;;) for(;;)
{ {
begin = cptr; begin = cptr;
while( *cptr && !IsEndOfLine(cptr) ) while( *cptr && !IsEndOfLine(cptr, withflag) )
cptr++; cptr++;
backup = *cptr; backup = *cptr;
*cptr = '\0'; *cptr = '\0';
@@ -49,7 +49,7 @@ void wxLayoutImportText(wxLayoutList &list, String const &str)
*cptr = backup; *cptr = backup;
// check if it's the end of this line // check if it's the end of this line
if ( IsEndOfLine(cptr) ) if ( IsEndOfLine(cptr, withflag) )
{ {
// if it was "\r\n", skip the following '\n' // if it was "\r\n", skip the following '\n'
if ( *cptr == '\r' ) if ( *cptr == '\r' )
@@ -64,7 +64,7 @@ void wxLayoutImportText(wxLayoutList &list, String const &str)
static static
String wxLayoutExportCmdAsHTML(wxLayoutObjectCmd const & cmd, String wxLayoutExportCmdAsHTML(wxLayoutObjectCmd const & cmd,
wxLayoutStyleInfo **lastStylePtr) wxLayoutStyleInfo **lastStylePtr)
{ {
static char buffer[20]; static char buffer[20];
String html; String html;
@@ -152,13 +152,13 @@ String wxLayoutExportCmdAsHTML(wxLayoutObjectCmd const & cmd,
#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_LINEBREAK) \
|| (type == WXLO_TYPE_CMD \ || (type == WXLO_TYPE_CMD \
&& mode == WXLO_EXPORT_AS_HTML)) && (mode & WXLO_EXPORT_AS_MASK) == WXLO_EXPORT_AS_HTML))
wxLayoutExportObject *wxLayoutExport(wxLayoutList &list, wxLayoutExportObject *wxLayoutExport(wxLayoutList &list,
wxLayoutList::iterator &from, wxLayoutList::iterator &from,
wxLayoutExportMode mode) int mode)
{ {
if(from == list.end()) if(from == list.end())
return NULL; return NULL;
@@ -168,7 +168,7 @@ String wxLayoutExportCmdAsHTML(wxLayoutObjectCmd const & cmd,
static wxLayoutStyleInfo *s_si = NULL; static wxLayoutStyleInfo *s_si = NULL;
if( mode == 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 = *from;
@@ -187,12 +187,15 @@ String wxLayoutExportCmdAsHTML(wxLayoutObjectCmd const & cmd,
*str += ((wxLayoutObjectText *)*from)->GetText(); *str += ((wxLayoutObjectText *)*from)->GetText();
break; break;
case WXLO_TYPE_LINEBREAK: case WXLO_TYPE_LINEBREAK:
if(mode == WXLO_EXPORT_AS_HTML) if((mode & WXLO_EXPORT_AS_MASK) == WXLO_EXPORT_AS_HTML)
*str += "<br>"; *str += "<br>";
*str += '\n'; 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_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
@@ -205,7 +208,7 @@ String wxLayoutExportCmdAsHTML(wxLayoutObjectCmd const & cmd,
if(from != list.end()) if(from != list.end())
type = (*from)->GetType(); type = (*from)->GetType();
} }
export->type = (mode == WXLO_EXPORT_AS_HTML) ? WXLO_EXPORT_HTML : WXLO_EXPORT_TEXT; 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

@@ -25,10 +25,15 @@ enum wxLayoutExportType
enum wxLayoutExportMode enum wxLayoutExportMode
{ {
WXLO_EXPORT_AS_TEXT, WXLO_EXPORT_AS_MASK = 0x0f,
WXLO_EXPORT_AS_TEXT_AND_COMMANDS, WXLO_EXPORT_AS_TEXT = 0x00,
WXLO_EXPORT_AS_HTML, WXLO_EXPORT_AS_TEXT_AND_COMMANDS = 0x01,
WXLO_EXPORT_AS_OBJECTS WXLO_EXPORT_AS_HTML = 0x02,
WXLO_EXPORT_AS_OBJECTS = 0x03,
WXLO_EXPORT_WITH_MASK = 0xf0,
WXLO_EXPORT_WITH_CRLF = 0x00,
WXLO_EXPORT_WITH_LF_ONLY = 0x10
}; };
struct wxLayoutExportObject struct wxLayoutExportObject
@@ -46,12 +51,22 @@ struct wxLayoutExportObject
} }
}; };
#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, String const &str,
int withflag = WXLO_EXPORT_WITH_CRLF);
wxLayoutExportObject *wxLayoutExport(wxLayoutList &list, wxLayoutExportObject *wxLayoutExport(wxLayoutList &list,
wxLayoutList::iterator &from, wxLayoutList::iterator &from,
wxLayoutExportMode WXLO_EXPORT_AS_TEXT); 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,
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);
#endif
#endif //WXLPARSER_H #endif //WXLPARSER_H

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$
*******************************************************************/ *******************************************************************/
@@ -12,10 +12,11 @@
//#include "Mpch.h" //#include "Mpch.h"
#ifdef M_BASEDIR #ifdef M_PREFIX
# ifndef USE_PCH # ifndef USE_PCH
# include "Mcommon.h" # include "Mcommon.h"
# include "gui/wxMenuDefs.h" # include "gui/wxMenuDefs.h"
# include "gui/wxMApp.h"
# endif // USE_PCH # endif // USE_PCH
# include "gui/wxlwindow.h" # include "gui/wxlwindow.h"
#else #else
@@ -30,7 +31,7 @@
# include "wxlwindow.h" # include "wxlwindow.h"
# define TRACEMESSAGE(x) # define TRACEMESSAGE(x)
#endif #endif
# define WXL_VAR(x) cerr << #x " = " << x ; # 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)
@@ -47,6 +48,8 @@ BEGIN_EVENT_TABLE(wxLayoutWindow,wxScrolledWindow)
EVT_MENU(WXLOWIN_MENU_ROMAN, wxLayoutWindow::OnMenu) EVT_MENU(WXLOWIN_MENU_ROMAN, wxLayoutWindow::OnMenu)
EVT_MENU(WXLOWIN_MENU_TYPEWRITER, wxLayoutWindow::OnMenu) EVT_MENU(WXLOWIN_MENU_TYPEWRITER, wxLayoutWindow::OnMenu)
EVT_MENU(WXLOWIN_MENU_SANSSERIF, wxLayoutWindow::OnMenu) EVT_MENU(WXLOWIN_MENU_SANSSERIF, wxLayoutWindow::OnMenu)
EVT_SET_FOCUS(wxLayoutWindow::OnSetFocus)
EVT_KILL_FOCUS(wxLayoutWindow::OnKillFocus)
END_EVENT_TABLE() END_EVENT_TABLE()
wxLayoutWindow::wxLayoutWindow(wxWindow *parent) wxLayoutWindow::wxLayoutWindow(wxWindow *parent)
@@ -54,24 +57,34 @@ wxLayoutWindow::wxLayoutWindow(wxWindow *parent)
wxHSCROLL | wxVSCROLL | wxBORDER) wxHSCROLL | wxVSCROLL | wxBORDER)
{ {
m_ScrollbarsSet = 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 = NULL;
m_memDC = new wxMemoryDC;
m_bitmap = new wxBitmap(4,4);
m_bitmapSize = wxPoint(4,4);
CoordType CoordType
max_x, max_y, lineHeight; max_x, max_y, lineHeight;
m_llist.GetSize(&max_x, &max_y, &lineHeight); m_llist.GetSize(&max_x, &max_y, &lineHeight);
SetScrollbars(10, lineHeight, max_x/10+1, max_y/lineHeight+1); 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;
}
wxLayoutWindow::~wxLayoutWindow()
{
delete m_memDC; // deletes bitmap automatically (?)
delete m_bitmap;
if(m_PopupMenu) delete m_PopupMenu;
} }
#ifdef __WXMSW__ #ifdef __WXMSW__
long long
wxLayoutWindow::MSWGetDlgCode() wxLayoutWindow::MSWGetDlgCode()
{ {
// if we don't return this, we won't get OnChar() events // if we don't return this, we won't get OnChar() events for TABs and ENTER
return DLGC_WANTCHARS | DLGC_WANTARROWS | DLGC_WANTMESSAGE; return DLGC_WANTCHARS | DLGC_WANTARROWS | DLGC_WANTMESSAGE;
} }
#endif //MSW #endif //MSW
@@ -79,15 +92,14 @@ wxLayoutWindow::MSWGetDlgCode()
void void
wxLayoutWindow::Update(void) wxLayoutWindow::Update(void)
{ {
wxClientDC dc(this);
PrepareDC(dc);
if(IsDirty()) if(IsDirty())
{ {
DoPaint(dc);
UpdateScrollbars(); UpdateScrollbars();
ResetDirty(); DoPaint();
} }
m_llist.DrawCursor(dc); else
DoPaint(true); // only the cursor
return;
} }
void void
@@ -107,7 +119,14 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
TRACEMESSAGE(("wxLayoutWindow::OnMouse: (%d, %d) -> (%d, %d)", TRACEMESSAGE(("wxLayoutWindow::OnMouse: (%d, %d) -> (%d, %d)",
event.GetX(), event.GetY(), findPos.x, findPos.y)); event.GetX(), event.GetY(), findPos.x, findPos.y));
if(eventId == WXLOWIN_MENU_RCLICK && m_DoPopupMenu && m_llist.IsEditable()) m_ClickPosition = findPos;
wxLayoutObjectBase *obj = m_llist.Find(findPos);
// 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)
{ {
// when does this menu get freed? // when does this menu get freed?
// how do we handle toggling? FIXME // how do we handle toggling? FIXME
@@ -115,16 +134,85 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
return; return;
} }
// find the object at this position // find the object at this position
wxLayoutObjectBase *obj = m_llist.Find(findPos);
if(obj) if(obj)
{ {
wxCommandEvent commandEvent(wxEVENT_TYPE_MENU_COMMAND, eventId); wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, eventId);
commandEvent.SetEventObject( this ); commandEvent.SetEventObject( this );
commandEvent.SetClientData((char *)obj); commandEvent.SetClientData((char *)obj);
GetEventHandler()->ProcessEvent(commandEvent); GetEventHandler()->ProcessEvent(commandEvent);
} }
} }
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
*/ */
@@ -138,171 +226,178 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
} }
long keyCode = event.KeyCode(); long keyCode = event.KeyCode();
wxPoint p;
CoordType help; /* First, handle control keys */
if(event.ControlDown())
switch(event.KeyCode())
{ {
case WXK_RIGHT: switch(event.KeyCode())
m_llist.MoveCursor(1);
break;
case WXK_LEFT:
m_llist.MoveCursor(-1);
break;
case WXK_UP:
m_llist.MoveCursor(0,-1);
break;
case WXK_DOWN:
m_llist.MoveCursor(0,1);
break;
case WXK_PRIOR:
m_llist.MoveCursor(0,-20);
break;
case WXK_NEXT:
m_llist.MoveCursor(0,20);
break;
case WXK_HOME:
p = m_llist.GetCursor();
p.x = 0;
m_llist.SetCursor(p);
break;
case WXK_END:
p = m_llist.GetCursor();
p.x = m_llist.GetLineLength(m_llist.GetCurrentObject());
m_llist.SetCursor(p);
break;
case WXK_DELETE :
if(event.ControlDown()) // delete to end of line
{ {
help = m_llist.GetLineLength( case WXK_DELETE :
m_llist.GetCurrentObject()) case 'k':
- m_llist.GetCursor().x; DeleteToEndOfLine(); break;
m_llist.Delete(help ? help : 1); case 'd':
m_llist.Delete(1); break;
case 'y':
DeleteLine(); break;
case 'h': // like backspace
if(m_llist.MoveCursor(-1))
m_llist.Delete(1);
break;
case 'u':
DeleteToBeginOfLine(); break;
default:
;
} }
else }
m_llist.Delete(1); else // no control keys
break; {
case WXK_BACK: // backspace switch(event.KeyCode())
if(m_llist.MoveCursor(-1)) { {
m_llist.Delete(1); case WXK_RIGHT:
} m_llist.MoveCursor(1);
break; break;
case WXK_RETURN: case WXK_LEFT:
m_llist.LineBreak(); m_llist.MoveCursor(-1);
break; break;
case WXK_UP:
m_llist.MoveCursor(0,-1);
break;
case WXK_DOWN:
m_llist.MoveCursor(0,1);
break;
case WXK_PRIOR:
m_llist.MoveCursor(0,-20);
break;
case WXK_NEXT:
m_llist.MoveCursor(0,20);
break;
case WXK_HOME:
GotoBeginOfLine();
break;
case WXK_END:
GotoEndOfLine();
break;
case WXK_DELETE :
if(event.ControlDown()) // delete to end of line
DeleteToEndOfLine();
else
m_llist.Delete(1);
break;
case WXK_BACK: // backspace
if(m_llist.MoveCursor(-1)) {
m_llist.Delete(1);
}
break;
case WXK_RETURN:
m_llist.LineBreak();
break;
#ifdef WXLAYOUT_DEBUG #ifdef WXLAYOUT_DEBUG
case WXK_F1: case WXK_F1:
m_llist.Debug(); m_llist.Debug();
break; break;
case WXK_F2: case WXK_F2:
m_llist.WrapLine(); m_llist.WrapLine();
break; break;
#endif #endif
default: default:
if(keyCode < 256 && keyCode >= 32) if((!(event.ControlDown() || event.AltDown() || event.MetaDown()))
{ && (keyCode < 256 && keyCode >= 32)
String tmp; )
tmp += keyCode; {
m_llist.Insert(tmp); String tmp;
m_llist.WrapLine(); tmp += keyCode;
m_llist.Insert(tmp);
m_llist.WrapLine();
}
break;
} }
break;
} }
/** Scroll so that cursor is visible! */ ScrollToCursor();
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();
int nx = x0, ny = y0;
// when within 10% of borders, scroll to center
if(cc.y > y0+(9*y1)/10)
ny = cc.y - y1/5;
else if (cc.y < y0+y1/10)
{
ny = cc.y-y1/2;
if(ny < 0) ny = 0;
}
if(cc.x > x0+(9*x1)/10)
nx = cc.x - x1/5;
else if (cc.x < x0+x1/10)
{
nx = cc.x-x1/2;
if(nx < 0) nx = 0;
}
Scroll(nx,ny);
Update(); Update();
ScrollToCursor();
} }
void void
wxLayoutWindow::OnPaint( wxPaintEvent &WXUNUSED(event)) // or: OnDraw(wxDC& dc) wxLayoutWindow::OnPaint( wxPaintEvent &WXUNUSED(event)) // or: OnDraw(wxDC& dc)
{
DoPaint();
}
void
wxLayoutWindow::DoPaint(bool cursorOnly) // or: OnDraw(wxDC& dc)
{ {
wxPaintDC dc( this ); wxPaintDC dc( this );
PrepareDC( dc ); PrepareDC( dc );
DoPaint(dc); // wxGTK: wxMemoryDC broken? YES!!
int x0,y0,x1,y1, dx, dy;
// wxGTK: wxMemoryDC broken?
#if 0
int x0,y0,x1,y1;
ViewStart(&x0,&y0); ViewStart(&x0,&y0);
GetSize(&x1,&y1); GetClientSize(&x1,&y1); // this is the size of the visible window
WXL_VAR(x0); WXL_VAR(y0); wxASSERT(x1 > 0);
WXL_VAR(x1); WXL_VAR(y1); wxASSERT(y1 > 0);
GetScrollPixelsPerUnit(&dx, &dy);
wxMemoryDC(memdc); x0 *= dx; y0 *= dy;
wxBitmap bm(x1,y1); //FIXME: trying an offset for small border:
memdc.SelectObject(bm); wxPoint offset(-x0+4,-y0+4);
// make temporary copy and edit this //Blit() doesn't work on scrolled window!
memdc.SetDeviceOrigin(x0,y0); // So we have to draw the cursor on the memdc.
memdc.Blit(x0,y0,x1,y1,&dc,x0,y0,wxCOPY,FALSE); //if(! cursorOnly)
DoPaint(memdc); {
// blit it back if(x1 > m_bitmapSize.x || y1 > m_bitmapSize.y)
dc.Blit(x0,y0,x1,y1,&memdc,x0,y0,wxCOPY,FALSE); {
#endif 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);
}
m_memDC->SetDeviceOrigin(0,0);
m_memDC->Clear();
if(IsDirty() || m_llist.CursorMoved())
m_llist.Layout(dc);
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);
}
//FIXME obsolete? ResetDirty();
UpdateScrollbars();
} }
// does the actual painting // change the range and position of scroll bars
void void
wxLayoutWindow::DoPaint(wxDC &dc) wxLayoutWindow::UpdateScrollbars(bool exact)
{ {
m_llist.EraseAndDraw(dc); CoordType
m_llist.DrawCursor(dc); max_x, max_y, lineHeight;
// FIXME: not strictly correct, this does only work for changes behind
// the cursor position, not complete redraws m_llist.GetSize(&max_x, &max_y, &lineHeight);
if(! m_ScrollbarsSet) if(max_x > m_maxx || max_y > m_maxy || exact)
{ {
m_ScrollbarsSet = true; // avoid recursion if(! exact) // add an extra 50% to the sizes to avoid future updates
UpdateScrollbars(); {
max_x = (3*max_x)/2;
max_y = (3*max_y)/2;
}
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;
} }
} }
void void
wxLayoutWindow::UpdateScrollbars(void) wxLayoutWindow::Print(wxDC &dc)
{ {
CoordType
max_x, max_y, lineHeight;
ViewStart(&m_ViewStartX, &m_ViewStartY);
m_llist.GetSize(&max_x, &max_y, &lineHeight);
SetScrollbars(10, lineHeight, max_x/10+1, max_y/lineHeight+1,m_ViewStartX,m_ViewStartY,true);
//EnableScrolling(true,true);
//Scroll(m_ViewStartX, m_ViewStartY);
}
void
wxLayoutWindow::Print(void)
{
wxPostScriptDC dc("layout.ps",true,this);
if (dc.Ok() && dc.StartDoc((char *)_("Printing message..."))) if (dc.Ok() && dc.StartDoc((char *)_("Printing message...")))
{ {
//dc.SetUserScale(1.0, 1.0); //dc.SetUserScale(1.0, 1.0);
@@ -368,3 +463,17 @@ void wxLayoutWindow::OnMenu(wxCommandEvent& event)
m_llist.SetFontFamily(wxSWISS); break; m_llist.SetFontFamily(wxSWISS); break;
} }
} }
void
wxLayoutWindow::OnSetFocus(wxFocusEvent &ev)
{
m_llist.SetBoldCursor(true);
DoPaint(true);
}
void
wxLayoutWindow::OnKillFocus(wxFocusEvent &ev)
{
m_llist.SetBoldCursor(false);
Update();
}

View File

@@ -42,6 +42,9 @@ public:
*/ */
wxLayoutWindow(wxWindow *parent); wxLayoutWindow(wxWindow *parent);
/// Destructor.
virtual ~wxLayoutWindow();
/* Returns a reference to the wxLayoutList object. /* Returns a reference to the wxLayoutList object.
@return the list @return the list
*/ */
@@ -54,14 +57,13 @@ public:
{ {
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();
m_bDirty = FALSE; m_bDirty = FALSE;
} }
// callbacks // callbacks
// NB: these functions are used as event handlers and must not be virtual // NB: these functions are used as event handlers and must not be virtual
void OnPaint(wxPaintEvent &event); void OnPaint(wxPaintEvent &event);
void OnLeftMouseClick(wxMouseEvent& event) void OnLeftMouseClick(wxMouseEvent& event)
{ OnMouse(WXLOWIN_MENU_LCLICK, event); } { OnMouse(WXLOWIN_MENU_LCLICK, event); }
void OnRightMouseClick(wxMouseEvent& event) void OnRightMouseClick(wxMouseEvent& event)
@@ -74,29 +76,42 @@ public:
void EnablePopup(bool enable = true) { m_DoPopupMenu = enable; } void EnablePopup(bool enable = true) { m_DoPopupMenu = enable; }
/// gets called by either Update() or OnPaint() /// gets called by either Update() or OnPaint()
void DoPaint(wxDC &dc); void DoPaint(bool cursoronly = false);
#ifdef __WXMSW__ #ifdef __WXMSW__
virtual long MSWGetDlgCode(); virtual long MSWGetDlgCode();
#endif //MSW #endif //MSW
void UpdateScrollbars(void); /// if exact == false, assume 50% extra size for the future
void Print(void); void UpdateScrollbars(bool exact = false); // don't change this to true!
wxMenu * wxLayoutWindow::MakeFormatMenu(void); 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; }
virtual ~wxLayoutWindow() { if(m_PopupMenu) delete m_PopupMenu; }
// dirty flag access // dirty flag access
bool IsDirty() const { return m_llist.IsDirty(); } bool IsDirty() const { return m_llist.IsDirty(); }
void ResetDirty() { m_llist.ResetDirty(); } void ResetDirty() { m_llist.ResetDirty(); }
void OnSetFocus(wxFocusEvent &ev);
void OnKillFocus(wxFocusEvent &ev);
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 /// repaint if needed
void Update(void); void Update(void);
@@ -107,8 +122,6 @@ protected:
/// the layout list to be displayed /// the layout list to be displayed
wxLayoutList m_llist; wxLayoutList m_llist;
/// have we already set the scrollbars?
bool m_ScrollbarsSet;
/// Where does the current view start? /// Where does the current view start?
int m_ViewStartX; int m_ViewStartY; int m_ViewStartX; int m_ViewStartY;
@@ -119,7 +132,17 @@ protected:
bool m_DoPopupMenu; bool m_DoPopupMenu;
/// the menu /// the menu
wxMenu * m_PopupMenu; wxMenu * m_PopupMenu;
/// for derived classes, set when mouse is clicked
wxPoint m_ClickPosition;
/// for scrollbar calculations:
int m_maxx;
int m_maxy;
int m_lineHeight;
private: private:
wxMemoryDC *m_memDC;
wxBitmap *m_bitmap;
wxPoint m_bitmapSize;
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
}; };