Merged in latest wxLayout code from Mahogany Mail.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1995 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Karsten Ballüder
1999-03-29 09:56:44 +00:00
parent 0a3d0d1157
commit dd59841c33
6 changed files with 218 additions and 106 deletions

View File

@@ -6,10 +6,6 @@
* $Id$ * $Id$
*******************************************************************/ *******************************************************************/
/*
*/
#ifdef __GNUG__ #ifdef __GNUG__
#pragma implementation "wxllist.h" #pragma implementation "wxllist.h"
#endif #endif
@@ -59,19 +55,35 @@
/// Use this character to estimate a cursor size when none is available. /// Use this character to estimate a cursor size when none is available.
#define WXLO_CURSORCHAR "E" #define WXLO_CURSORCHAR "E"
/** @name Helper functions */
/// Helper function, allows me to compare to wxPoints //@{
/// allows me to compare to wxPoints
bool operator ==(wxPoint const &p1, wxPoint const &p2) bool operator ==(wxPoint const &p1, wxPoint const &p2)
{ {
return p1.x == p2.x && p1.y == p2.y; return p1.x == p2.x && p1.y == p2.y;
} }
/// Helper function, allows me to compare to wxPoints /// allows me to compare to wxPoints
bool operator !=(wxPoint const &p1, wxPoint const &p2) bool operator !=(wxPoint const &p1, wxPoint const &p2)
{ {
return p1.x != p2.x || p1.y != p2.y; return p1.x != p2.x || p1.y != p2.y;
} }
/// grows a wxRect so that it includes the given point
static void GrowRect(wxRect &r, const wxPoint & p)
{
if(r.x > p.x)
r.x = p.x;
else if(r.x + r.width < p.x)
r.width = p.x - r.x;
if(r.y > p.y)
r.y = p.y;
else if(r.y + r.height < p.y)
r.height = p.y - r.y;
}
//@}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
@@ -367,7 +379,7 @@ wxLayoutObjectList::iterator
wxLayoutLine::FindObjectScreen(wxDC &dc, CoordType xpos, CoordType *cxpos) const wxLayoutLine::FindObjectScreen(wxDC &dc, CoordType xpos, CoordType *cxpos) const
{ {
wxASSERT(cxpos); wxASSERT(cxpos);
wxASSERT(xpos); wxASSERT(cxpos);
wxLayoutObjectList::iterator i; wxLayoutObjectList::iterator i;
CoordType x = 0, cx = 0, width; CoordType x = 0, cx = 0, width;
@@ -698,6 +710,7 @@ wxLayoutLine::Layout(wxDC &dc, wxPoint *cursorPos,
if(m_Next && objHeight != oldHeight) if(m_Next && objHeight != oldHeight)
m_Next->RecalculatePositions(); m_Next->RecalculatePositions();
// We need to check whether we found a valid cursor size:
if(cursorPos) if(cursorPos)
{ {
// this might be the case if the cursor is at the end of the // this might be the case if the cursor is at the end of the
@@ -814,7 +827,7 @@ wxLayoutLine::GetWrapPosition(CoordType column)
{ {
do do
{ {
if( isspace(((wxLayoutObjectText*)*i)->GetText()[offset])) if( isspace(((wxLayoutObjectText*)*i)->GetText()[(size_t)offset]))
return column; return column;
else else
{ {
@@ -867,6 +880,7 @@ wxLayoutList::wxLayoutList()
{ {
m_DefaultSetting = NULL; m_DefaultSetting = NULL;
m_FirstLine = NULL; m_FirstLine = NULL;
InvalidateUpdateRect();
Clear(); Clear();
} }
@@ -1228,10 +1242,14 @@ wxLayoutList::Layout(wxDC &dc, CoordType bottom) const
if(bottom != -1 && line->GetPosition().y > bottom) break; if(bottom != -1 && line->GetPosition().y > bottom) break;
line = line->GetNextLine(); line = line->GetNextLine();
} }
///FIXME: disabled for now
#if 0
// can only be 0 if we are on the first line and have no next line // can only be 0 if we are on the first line and have no next line
wxASSERT(m_CursorSize.x != 0 || (m_CursorLine && wxASSERT(m_CursorSize.x != 0 || (m_CursorLine &&
m_CursorLine->GetNextLine() == NULL && m_CursorLine->GetNextLine() == NULL &&
m_CursorLine == m_FirstLine)); m_CursorLine == m_FirstLine));
#endif
} }
void void
@@ -1242,13 +1260,17 @@ wxLayoutList::Draw(wxDC &dc, wxPoint const &offset,
Layout(dc, bottom); Layout(dc, bottom);
m_DefaultSetting->Draw(dc, wxPoint(0,0)); m_DefaultSetting->Draw(dc, wxPoint(0,0));
wxBrush *brush = new wxBrush(*m_ColourBG, wxSOLID);
dc.SetBrush(*brush);
delete brush;
while(line) while(line)
{ {
// only draw if between top and bottom: // only draw if between top and bottom:
if((top == -1 || line->GetPosition().y >= top)) if((top == -1 || line->GetPosition().y >= top))
line->Draw(dc, offset); line->Draw(dc, offset);
// little condition to speed up redrawing: // little condition to speed up redrawing:
if(bottom != -1 && line->GetPosition().y > bottom) break; if(bottom != -1 && line->GetPosition().y + line->GetHeight() > bottom) break;
line = line->GetNextLine(); line = line->GetNextLine();
} }
// can only be 0 if we are on the first line and have no next line // can only be 0 if we are on the first line and have no next line
@@ -1291,18 +1313,19 @@ wxLayoutList::GetSize(void) const
if(! line) if(! line)
return wxPoint(0,0); return wxPoint(0,0);
wxPoint max(0,0); wxPoint maxPoint(0,0);
// find last line: // find last line:
while(line) while(line)
{ {
if(line->GetWidth() > max.x) max.x = line->GetWidth(); if(line->GetWidth() > maxPoint.x)
maxPoint.x = line->GetWidth();
last = line; last = line;
line = line->GetNextLine(); line = line->GetNextLine();
} }
max.y = last->GetPosition().y + last->GetHeight(); maxPoint.y = last->GetPosition().y + last->GetHeight();
return max; return maxPoint;
} }
void void
@@ -1325,7 +1348,6 @@ wxLayoutList::DrawCursor(wxDC &dc, bool active, wxPoint const &translate)
dc.SetBrush(*wxBLACK_BRUSH); dc.SetBrush(*wxBLACK_BRUSH);
dc.SetLogicalFunction(wxXOR); dc.SetLogicalFunction(wxXOR);
dc.SetPen(wxPen(*wxBLACK,1,wxSOLID)); dc.SetPen(wxPen(*wxBLACK,1,wxSOLID));
dc.SetLogicalFunction(wxXOR);
if(active) if(active)
dc.DrawRectangle(coords.x, coords.y, m_CursorSize.x, dc.DrawRectangle(coords.x, coords.y, m_CursorSize.x,
m_CursorSize.y); m_CursorSize.y);
@@ -1333,9 +1355,26 @@ wxLayoutList::DrawCursor(wxDC &dc, bool active, wxPoint const &translate)
dc.DrawLine(coords.x, coords.y+m_CursorSize.y-1, dc.DrawLine(coords.x, coords.y+m_CursorSize.y-1,
coords.x+m_CursorSize.x, coords.y+m_CursorSize.y-1); coords.x+m_CursorSize.x, coords.y+m_CursorSize.y-1);
dc.SetLogicalFunction(wxCOPY); dc.SetLogicalFunction(wxCOPY);
dc.SetBrush(wxNullBrush); //dc.SetBrush(wxNullBrush);
} }
/** Called by the objects to update the update rectangle.
@param p a point to include in it
*/
void
wxLayoutList::SetUpdateRect(const wxPoint &p)
{
if(m_UpdateRectValid)
GrowRect(m_UpdateRect, p);
else
{
m_UpdateRect.x = p.x;
m_UpdateRect.y = p.y;
m_UpdateRect.width = 4; // large enough to avoid surprises from
m_UpdateRect.height = 4;// wxGTK :-)
m_UpdateRectValid = true;
}
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
@@ -1445,13 +1484,9 @@ void wxLayoutPrintout::GetPageInfo(int *minPage, int *maxPage, int *selPageFrom,
m_PrintoutHeight = (int)( m_PrintoutHeight / scale); // we want to use the real paper height 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); m_NumOfPages = 1 +
(int)( m_llist->GetSize().y / (float)(m_PrintoutHeight));
// 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; *minPage = 1;
*maxPage = m_NumOfPages; *maxPage = m_NumOfPages;

View File

@@ -160,7 +160,7 @@ public:
/** Makes a copy of this object. /** Makes a copy of this object.
*/ */
virtual wxLayoutObject *Copy(void) = 0; virtual wxLayoutObject *Copy(void) = 0;
private: protected:
/// optional data for application's use /// optional data for application's use
UserData *m_UserData; UserData *m_UserData;
}; };
@@ -762,6 +762,14 @@ public:
wxPoint const pos, wxPoint const pos,
wxPoint *cursorPos = NULL); wxPoint *cursorPos = NULL);
/** Called by the objects to update the update rectangle.
@param p a point to include in it
*/
void SetUpdateRect(const wxPoint &p);
/// Invalidates the update rectangle.
void InvalidateUpdateRect(void) { m_UpdateRectValid = false; }
/// Returns the update rectangle.
const wxRect *GetUpdateRect(void) const { return &m_UpdateRect; }
//@} //@}
/**@name For exporting one object after another. */ /**@name For exporting one object after another. */
@@ -779,6 +787,10 @@ private:
/// The list of lines. /// The list of lines.
wxLayoutLine *m_FirstLine; wxLayoutLine *m_FirstLine;
/// The update rectangle which needs to be refreshed:
wxRect m_UpdateRect;
/// Is the update rectangle valid?
bool m_UpdateRectValid;
/**@name Cursor Management */ /**@name Cursor Management */
//@{ //@{
/// Where the text cursor (column,line) is. /// Where the text cursor (column,line) is.

View File

@@ -26,7 +26,7 @@ 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
((mode & WXLO_EXPORT_WITH_MASK) == WXLO_EXPORT_WITH_CRLF) ? (mode == WXLO_EXPORT_WITH_CRLF) ?
((*p == '\r') && (*(p + 1) == '\n')) ((*p == '\r') && (*(p + 1) == '\n'))
: :
(((*p == '\r') && (*(p + 1) == '\n'))||(*p == '\n')); (((*p == '\r') && (*(p + 1) == '\n'))||(*p == '\n'));
@@ -149,65 +149,82 @@ wxString wxLayoutExportCmdAsHTML(wxLayoutObjectCmd const & cmd,
#define WXLO_IS_TEXT(type) \ #define WXLO_IS_TEXT(type) \
( type == WXLO_TYPE_TEXT \ ( 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_HTML))
wxLayoutExportObject *wxLayoutExport(wxLayoutExportStatus *status, wxLayoutExportObject *wxLayoutExport(wxLayoutExportStatus *status,
int mode) int mode, int flags)
{ {
wxASSERT(status); wxASSERT(status);
wxLayoutExportObject * export; wxLayoutExportObject * export;
if(status->m_iterator == NULLIT) // end of line if(status->m_iterator == NULLIT) // end of line
{ {
if(!status->m_line || status->m_line->GetNextLine() == NULL) // reached end of list if(!status->m_line || status->m_line->GetNextLine() == NULL)
// reached end of list
return NULL; return NULL;
else }
export = new wxLayoutExportObject();
wxLayoutObjectType type;
if(status->m_iterator != NULLIT)
{
type = (** status->m_iterator).GetType();
if( mode == WXLO_EXPORT_AS_OBJECTS || ! WXLO_IS_TEXT(type)) // simple case
{ {
status->m_line = status->m_line->GetNextLine(); export->type = WXLO_EXPORT_OBJECT;
status->m_iterator = status->m_line->GetFirstObject(); export->content.object = *status->m_iterator;
export = new wxLayoutExportObject();; status->m_iterator++;
if( (mode & WXLO_EXPORT_AS_MASK) == WXLO_EXPORT_AS_OBJECTS) // simple case
{
export->type = WXLO_EXPORT_OBJECT;
export->content.object = *status->m_iterator;
status->m_iterator++;
return export;
}
//else: text object:
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; return export;
} }
} }
else
export = new wxLayoutExportObject(); { // iterator == NULLIT
wxLayoutObjectType type = (** status->m_iterator).GetType(); if(mode == WXLO_EXPORT_AS_OBJECTS)
if( (mode & WXLO_EXPORT_AS_MASK) == WXLO_EXPORT_AS_OBJECTS || ! WXLO_IS_TEXT(type)) // simple case {
{ export->type = WXLO_EXPORT_EMPTYLINE;
export->type = WXLO_EXPORT_OBJECT; export->content.object = NULL; //empty line
export->content.object = *status->m_iterator; status->m_line = status->m_line->GetNextLine();
status->m_iterator++; if(status->m_line)
return export; status->m_iterator = status->m_line->GetFirstObject();
return export;
}
else
type = WXLO_TYPE_TEXT;
} }
// else: must be text
wxString *str = new wxString(); wxString *str = new wxString();
// text must be concatenated // text must be concatenated
do int testf = WXLO_EXPORT_WITH_CRLF;
for(;;)
{ {
while(status->m_iterator == NULLIT)
{
if(flags & WXLO_EXPORT_AS_HTML)
*str += "<br>";
if(flags & 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
break; // end of list
}
if(! status->m_line) // reached end of list, fall through
break;
type = (** status->m_iterator).GetType();
if(type == WXLO_TYPE_ICON)
break;
switch(type) switch(type)
{ {
case WXLO_TYPE_TEXT: case WXLO_TYPE_TEXT:
*str += ((wxLayoutObjectText *)*status->m_iterator)->GetText(); *str += ((wxLayoutObjectText *)*status->m_iterator)->GetText();
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_HTML,
"reached cmd object in text mode" ); "reached cmd object in text mode" );
*str += wxLayoutExportCmdAsHTML(*(wxLayoutObjectCmd const *str += wxLayoutExportCmdAsHTML(*(wxLayoutObjectCmd const
@@ -217,28 +234,9 @@ wxLayoutExportObject *wxLayoutExport(wxLayoutExportStatus *status,
; ;
} }
status->m_iterator++; 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;
} }
while(WXLO_IS_TEXT(type));
export->type = ((mode & WXLO_EXPORT_AS_MASK) == WXLO_EXPORT_AS_HTML) export->type = (mode == WXLO_EXPORT_AS_HTML)
? WXLO_EXPORT_HTML : WXLO_EXPORT_TEXT; ? WXLO_EXPORT_HTML : WXLO_EXPORT_TEXT;
export->content.text = str; export->content.text = str;
return export; return export;

View File

@@ -20,20 +20,21 @@ enum wxLayoutExportType
{ {
WXLO_EXPORT_TEXT, WXLO_EXPORT_TEXT,
WXLO_EXPORT_HTML, WXLO_EXPORT_HTML,
WXLO_EXPORT_OBJECT WXLO_EXPORT_OBJECT,
// this can be caused by empty lines:
WXLO_EXPORT_EMPTYLINE
}; };
enum wxLayoutExportMode enum wxLayoutExportMode
{ {
WXLO_EXPORT_AS_MASK = 0x0f,
WXLO_EXPORT_AS_TEXT = 0x00, WXLO_EXPORT_AS_TEXT = 0x00,
WXLO_EXPORT_AS_TEXT_AND_COMMANDS = 0x01, WXLO_EXPORT_AS_TEXT_AND_COMMANDS = 0x01,
WXLO_EXPORT_AS_HTML = 0x02, WXLO_EXPORT_AS_HTML = 0x02,
WXLO_EXPORT_AS_OBJECTS = 0x03, WXLO_EXPORT_AS_OBJECTS = 0x03,
WXLO_EXPORT_WITH_MASK = 0xf0, // non 0:
WXLO_EXPORT_WITH_CRLF = 0x00, WXLO_EXPORT_WITH_CRLF = 0x10,
WXLO_EXPORT_WITH_LF_ONLY = 0x10 WXLO_EXPORT_WITH_LF_ONLY = 0x20
}; };
struct wxLayoutExportObject struct wxLayoutExportObject
@@ -72,15 +73,17 @@ void wxLayoutImportText(wxLayoutList *list, wxString const &str,
int withflag = WXLO_EXPORT_WITH_CRLF); int withflag = WXLO_EXPORT_WITH_CRLF);
wxLayoutExportObject *wxLayoutExport(wxLayoutExportStatus *status, wxLayoutExportObject *wxLayoutExport(wxLayoutExportStatus *status,
int mode = WXLO_EXPORT_AS_TEXT|WXLO_EXPORT_WITH_CRLF); int mode = WXLO_EXPORT_AS_TEXT,
int flags = WXLO_EXPORT_WITH_CRLF);
#else #else
/// import text into a wxLayoutList (including linefeeds): /// import text into a wxLayoutList (including linefeeds):
void wxLayoutImportText(wxLayoutList *list, wxString const &str, void wxLayoutImportText(wxLayoutList *list, wxString const &str,
int withflag = WXLO_EXPORT_WITH_LF_ONLY); int withflag = WXLO_EXPORT_WITH_LF_ONLY);
/// export text in a given format FIXME-MT: not thread safe, uses static variable /// export text in a given format
wxLayoutExportObject *wxLayoutExport(wxLayoutExportStatus *status, wxLayoutExportObject *wxLayoutExport(wxLayoutExportStatus *status,
int mode = WXLO_EXPORT_AS_TEXT|WXLO_EXPORT_WITH_LF_ONLY int mode = WXLO_EXPORT_AS_TEXT,
int flags = WXLO_EXPORT_WITH_LF_ONLY
); );
#endif #endif

View File

@@ -18,7 +18,9 @@
# include "gui/wxMenuDefs.h" # include "gui/wxMenuDefs.h"
# include "gui/wxMApp.h" # include "gui/wxMApp.h"
# endif // USE_PCH # endif // USE_PCH
# include "gui/wxlwindow.h" # include "gui/wxlwindow.h"
# include "gui/wxlparser.h"
#else #else
# ifdef __WXMSW__ # ifdef __WXMSW__
# include <windows.h> # include <windows.h>
@@ -26,16 +28,24 @@
# undef GetCharWidth # undef GetCharWidth
# undef StartDoc # undef StartDoc
# endif # endif
# include "wxlwindow.h" # include "wxlwindow.h"
# include "wxlparser.h" # include "wxlparser.h"
#endif #endif
#include <ctype.h>
#include <wx/clipbrd.h> #include <wx/clipbrd.h>
#include <wx/dataobj.h>
#include <ctype.h>
/// offsets to put a nice frame around text
#define WXLO_XOFFSET 4 #define WXLO_XOFFSET 4
#define WXLO_YOFFSET 4 #define WXLO_YOFFSET 4
/// offset to the right and bottom for when to redraw scrollbars
#define WXLO_ROFFSET 20
#define WXLO_BOFFSET 20
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)
@@ -61,6 +71,7 @@ wxLayoutWindow::wxLayoutWindow(wxWindow *parent)
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(); m_llist = new wxLayoutList();
m_BGbitmap = NULL;
SetWrapMargin(0); SetWrapMargin(0);
wxPoint max = m_llist->GetSize(); wxPoint max = m_llist->GetSize();
SetScrollbars(10, 20 /*lineHeight*/, max.x/10+1, max.y/20+1); SetScrollbars(10, 20 /*lineHeight*/, max.x/10+1, max.y/20+1);
@@ -75,7 +86,8 @@ wxLayoutWindow::~wxLayoutWindow()
delete m_memDC; // deletes bitmap automatically (?) delete m_memDC; // deletes bitmap automatically (?)
delete m_bitmap; delete m_bitmap;
delete m_llist; delete m_llist;
delete m_PopupMenu; delete m_PopupMenu;
SetBackgroundBitmap(NULL);
} }
#ifdef __WXMSW__ #ifdef __WXMSW__
@@ -93,6 +105,7 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
wxPaintDC dc( this ); wxPaintDC dc( this );
PrepareDC( dc ); PrepareDC( dc );
SetFocus(); SetFocus();
wxPoint findPos; wxPoint findPos;
findPos.x = dc.DeviceToLogicalX(event.GetX()); findPos.x = dc.DeviceToLogicalX(event.GetX());
@@ -103,13 +116,13 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
if(findPos.x < 0) findPos.x = 0; if(findPos.x < 0) findPos.x = 0;
if(findPos.y < 0) findPos.y = 0; if(findPos.y < 0) findPos.y = 0;
m_ClickPosition = wxPoint(event.GetX(), event.GetY());
#ifdef WXLAYOUT_DEBUG #ifdef WXLAYOUT_DEBUG
wxLogDebug("wxLayoutWindow::OnMouse: (%d, %d) -> (%d, %d)", wxLogDebug("wxLayoutWindow::OnMouse: (%d, %d) -> (%d, %d)",
event.GetX(), event.GetY(), findPos.x, findPos.y); event.GetX(), event.GetY(), findPos.x, findPos.y);
#endif #endif
m_ClickPosition = findPos;
wxPoint cursorPos; wxPoint cursorPos;
wxLayoutObject *obj = m_llist->FindObjectScreen(dc, findPos, &cursorPos); wxLayoutObject *obj = m_llist->FindObjectScreen(dc, findPos, &cursorPos);
@@ -136,7 +149,7 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
&& (! obj || (obj && obj->GetUserData() == NULL)) && (! obj || (obj && obj->GetUserData() == NULL))
) )
{ {
PopupMenu(m_PopupMenu, event.GetX(), event.GetY()); PopupMenu(m_PopupMenu, m_ClickPosition.x, m_ClickPosition.y);
return; return;
} }
// find the object at this position // find the object at this position
@@ -261,6 +274,7 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
} }
} }
SetDirty(); SetDirty();
SetModified();
DoPaint(true); // paint and scroll to cursor DoPaint(true); // paint and scroll to cursor
} }
@@ -278,7 +292,7 @@ wxLayoutWindow::DoPaint(bool scrollToCursor)
#ifdef __WXGTK__ #ifdef __WXGTK__
InternalPaint(); InternalPaint();
#else #else
Refresh(); Refresh(FALSE); // Causes bad flicker under wxGTK!!!
#endif #endif
} }
@@ -298,8 +312,11 @@ wxLayoutWindow::InternalPaint(void)
// Get the size of the visible window: // Get the size of the visible window:
GetClientSize(&x1,&y1); GetClientSize(&x1,&y1);
wxASSERT(x1 > 0); wxASSERT(x1 > 0);
wxASSERT(y1 > 0); wxASSERT(y1 > 0);
// As we have the values anyway, use them to avoid unnecessary
// scrollbar updates.
if(x1 > m_maxx) m_maxx = x1;
if(y1 > m_maxy) m_maxy = y1;
// Maybe we need to change the scrollbar sizes or positions, // Maybe we need to change the scrollbar sizes or positions,
// so layout the list and check: // so layout the list and check:
@@ -344,17 +361,46 @@ wxLayoutWindow::InternalPaint(void)
// Device origins on the memDC are suspect, we translate manually // Device origins on the memDC are suspect, we translate manually
// with the translate parameter of Draw(). // with the translate parameter of Draw().
m_memDC->SetDeviceOrigin(0,0); m_memDC->SetDeviceOrigin(0,0);
m_memDC->Clear(); m_memDC->SetBackgroundMode(wxTRANSPARENT);
m_memDC->SetBrush(wxBrush(*m_llist->GetDefaults()->GetBGColour(), wxSOLID));
m_memDC->SetPen(wxPen(*m_llist->GetDefaults()->GetBGColour(),0,wxTRANSPARENT));
m_memDC->SetLogicalFunction(wxCOPY);
if(m_BGbitmap)
{
CoordType
y, x,
w = m_BGbitmap->GetWidth(),
h = m_BGbitmap->GetHeight();
for(y = 0; y < y1; y+=h)
for(x = 0; x < x1; x+=w)
m_memDC->DrawBitmap(*m_BGbitmap, x, y);
}
else
m_memDC->DrawRectangle(0,0,x1, y1);
// The offsets give the window a tiny border on the left and top, looks nice. // The offsets give the window a tiny border on the left and top, looks nice.
wxPoint offset(-x0+WXLO_XOFFSET,-y0+WXLO_YOFFSET); wxPoint offset(-x0+WXLO_XOFFSET,-y0+WXLO_YOFFSET);
m_llist->Draw(*m_memDC,offset); m_llist->Draw(*m_memDC,offset);
if(IsEditable()) if(IsEditable())
m_llist->DrawCursor(*m_memDC,m_HaveFocus,offset); 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);
// Now copy everything to the screen:
wxRegionIterator ri ( GetUpdateRegion() );
if(ri)
while(ri)
{
dc.Blit(x0+ri.GetX(),y0+ri.GetY(),ri.GetW(),ri.GetH(),
m_memDC,ri.GetX(),ri.GetY(),wxCOPY,FALSE);
ri++;
}
else
// If there are no update rectangles, we got called to reflect
// a change in the list. Currently there is no mechanism to
// easily find out which bits need updating, so we update
// all. The wxLayoutList could handle this, creating a list or
// at least one large rectangle of changes. FIXME
dc.Blit(x0,y0,x1,y1,m_memDC,0,0,wxCOPY,FALSE);
ResetDirty(); ResetDirty();
} }
@@ -363,15 +409,16 @@ void
wxLayoutWindow::ResizeScrollbars(bool exact) wxLayoutWindow::ResizeScrollbars(bool exact)
{ {
wxPoint max = m_llist->GetSize(); wxPoint max = m_llist->GetSize();
if(max.x > m_maxx || max.y > m_maxy if(max.x > m_maxx || max.y > m_maxy
|| max.x < (7*m_maxx)/10 || max.y << (7*m_maxy)/10 || max.x > m_maxx-WXLO_ROFFSET || max.y > m_maxy-WXLO_BOFFSET
|| exact) || exact)
{ {
if(! exact) // add an extra 20% to the sizes to avoid future updates if(! exact)
{ {
max.x = (12*max.x)/10; // 12/20 = 120% // add an extra bit to the sizes to avoid future updates
max.y = (12*max.y)/10; max.x = max.x+WXLO_ROFFSET;
max.y = max.y+WXLO_BOFFSET;
} }
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);

View File

@@ -68,10 +68,19 @@ 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());
ResizeScrollbars(true);
SetDirty(); SetDirty();
SetModified(false);
DoPaint(); DoPaint();
} }
/** Sets a background image, only used on screen, not on printouts.
@param bitmap a pointer to a wxBitmap or NULL to remove it
*/
void SetBackgroundBitmap(wxBitmap *bitmap = NULL)
{
if(m_BGbitmap) delete m_BGbitmap;
m_BGbitmap = bitmap;
}
/// Enable or disable editing, i.e. processing of keystrokes. /// Enable or disable editing, i.e. processing of keystrokes.
void SetEditable(bool toggle) { m_Editable = toggle; } void SetEditable(bool toggle) { m_Editable = toggle; }
/// Query whether list can be edited by user. /// Query whether list can be edited by user.
@@ -136,6 +145,12 @@ public:
//@} //@}
/// Redraws the window, used by DoPaint() or OnPaint(). /// Redraws the window, used by DoPaint() or OnPaint().
void InternalPaint(void); void InternalPaint(void);
/// Has list been modified/edited?
bool IsModified(void) const { return m_Modified; }
/// Mark list as modified or unchanged.
void SetModified(bool modified = true) { m_Modified = modified; }
protected: protected:
/// generic function for mouse events processing /// generic function for mouse events processing
void OnMouse(int eventId, wxMouseEvent& event); void OnMouse(int eventId, wxMouseEvent& event);
@@ -163,17 +178,19 @@ protected:
private: private:
/// The layout list to be displayed. /// The layout list to be displayed.
wxLayoutList *m_llist; wxLayoutList *m_llist;
/// Can user edit the window? /// Can user edit the window?
bool m_Editable; bool m_Editable;
/// wrap margin /// wrap margin
CoordType m_WrapMargin; CoordType m_WrapMargin;
/// Is list dirty? /// Is list dirty (for redraws, internal use)?
bool m_Dirty; bool m_Dirty;
/// Has list been edited?
bool m_Modified;
wxMemoryDC *m_memDC; wxMemoryDC *m_memDC;
wxBitmap *m_bitmap; wxBitmap *m_bitmap;
wxPoint m_bitmapSize; wxPoint m_bitmapSize;
/// a pointer to a bitmap for the background
wxBitmap *m_BGbitmap;
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
}; };