First part of fixes to make this work under MSW.
1. letters actually appear on the screen 2. Clear() works 3. Backspace/Delete in one line works too 4. breaking lines works 5. cursor is now a wxCaret 6. tons of other fixes git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2652 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -61,7 +61,7 @@ IMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame )
|
||||
MyFrame::MyFrame(void) :
|
||||
wxFrame( (wxFrame *) NULL, -1, (char *) "wxLayout", wxPoint(20,20), wxSize(600,360) )
|
||||
{
|
||||
CreateStatusBar( 1 );
|
||||
CreateStatusBar( 2 );
|
||||
|
||||
SetStatusText( "wxLayout by Karsten Ball<6C>der." );
|
||||
|
||||
@@ -106,6 +106,7 @@ MyFrame::MyFrame(void) :
|
||||
SetMenuBar( menu_bar );
|
||||
|
||||
m_lwin = new wxLayoutWindow(this);
|
||||
m_lwin->SetStatusBar(GetStatusBar(), 0, 1);
|
||||
m_lwin->SetMouseTracking(true);
|
||||
m_lwin->SetEditable(true);
|
||||
m_lwin->SetWrapMargin(40);
|
||||
|
@@ -14,14 +14,14 @@
|
||||
#pragma implementation "wxllist.h"
|
||||
#endif
|
||||
|
||||
#include "Mpch.h"
|
||||
#include <wx/wxprec.h>
|
||||
|
||||
|
||||
#include "wx/wxprec.h"
|
||||
#ifdef __BORLANDC__
|
||||
# pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include "Mpch.h"
|
||||
|
||||
#ifdef M_BASEDIR
|
||||
# include "gui/wxllist.h"
|
||||
# include "gui/wxlparser.h"
|
||||
@@ -33,7 +33,8 @@
|
||||
#endif
|
||||
|
||||
#ifndef USE_PCH
|
||||
# include "iostream.h"
|
||||
# include <iostream.h>
|
||||
|
||||
# include <wx/dc.h>
|
||||
# include <wx/dcps.h>
|
||||
# include <wx/print.h>
|
||||
@@ -41,6 +42,10 @@
|
||||
# include <wx/filefn.h>
|
||||
#endif
|
||||
|
||||
#ifdef WXLAYOUT_USE_CARET
|
||||
# include <wx/caret.h>
|
||||
#endif // WXLAYOUT_USE_CARET
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
/// This should never really get created
|
||||
@@ -48,23 +53,32 @@
|
||||
|
||||
#ifdef WXLAYOUT_DEBUG
|
||||
|
||||
# define TypewxString(t) g_aTypewxStrings[t]
|
||||
# define TypeString(t) g_aTypeStrings[t]
|
||||
# define WXLO_DEBUG(x) wxLogDebug x
|
||||
|
||||
static const char *g_aTypewxStrings[] =
|
||||
static const char *g_aTypeStrings[] =
|
||||
{
|
||||
"invalid", "text", "cmd", "icon"
|
||||
};
|
||||
void
|
||||
wxLayoutObject::Debug(void)
|
||||
{
|
||||
WXLO_DEBUG(("%s",g_aTypewxStrings[GetType()]));
|
||||
WXLO_DEBUG(("%s",g_aTypeStrings[GetType()]));
|
||||
}
|
||||
#else
|
||||
# define TypewxString(t) ""
|
||||
# define TypeString(t) ""
|
||||
# define WXLO_DEBUG(x)
|
||||
#endif
|
||||
|
||||
// FIXME under MSW, this constant is needed to make the thing properly redraw
|
||||
// itself - I don't know where the size calculation error is and I can't
|
||||
// waste time looking for it right now. Search for occurences of
|
||||
// MSW_CORRECTION to find all the places where I did it.
|
||||
#ifdef __WXMSW__
|
||||
static const int MSW_CORRECTION = 10;
|
||||
#else
|
||||
static const int MSW_CORRECTION = 0;
|
||||
#endif
|
||||
|
||||
/// Cursors smaller than this disappear in XOR drawing mode
|
||||
#define WXLO_MINIMUM_CURSOR_WIDTH 4
|
||||
@@ -73,18 +87,6 @@
|
||||
#define WXLO_CURSORCHAR "E"
|
||||
/** @name Helper functions */
|
||||
//@{
|
||||
/// allows me to compare to wxPoints
|
||||
bool operator ==(wxPoint const &p1, wxPoint const &p2)
|
||||
{
|
||||
return p1.x == p2.x && p1.y == p2.y;
|
||||
}
|
||||
|
||||
/// allows me to compare to wxPoints
|
||||
bool operator !=(wxPoint const &p1, wxPoint const &p2)
|
||||
{
|
||||
return p1.x != p2.x || p1.y != p2.y;
|
||||
}
|
||||
|
||||
/// allows me to compare to wxPoints
|
||||
bool operator <=(wxPoint const &p1, wxPoint const &p2)
|
||||
{
|
||||
@@ -272,11 +274,35 @@ wxLayoutObjectText::GetOffsetScreen(wxDC &dc, CoordType xpos) const
|
||||
}
|
||||
|
||||
void
|
||||
wxLayoutObjectText::Layout(wxDC &dc, class wxLayoutList * )
|
||||
wxLayoutObjectText::Layout(wxDC &dc, class wxLayoutList *llist)
|
||||
{
|
||||
long descent = 0l;
|
||||
|
||||
CoordType widthOld = m_Width,
|
||||
heightOld = m_Height;
|
||||
dc.GetTextExtent(m_Text, &m_Width, &m_Height, &descent);
|
||||
|
||||
if ( widthOld != m_Width || heightOld != m_Height )
|
||||
{
|
||||
// as the text length changed, it must be refreshed
|
||||
wxLayoutLine *line = GetLine();
|
||||
|
||||
wxCHECK_RET( line, "wxLayoutObjectText can't refresh itself" );
|
||||
|
||||
// as our size changed, we need to repaint the part which was appended
|
||||
wxPoint position(line->GetPosition());
|
||||
|
||||
// this is not the most efficient way (we repaint the whole line), but
|
||||
// it's not too slow and is *simple*
|
||||
if ( widthOld < m_Width )
|
||||
widthOld = m_Width;
|
||||
if ( heightOld < m_Height )
|
||||
heightOld = m_Height;
|
||||
|
||||
llist->SetUpdateRect(position.x + widthOld + MSW_CORRECTION,
|
||||
position.y + heightOld + MSW_CORRECTION);
|
||||
}
|
||||
|
||||
m_Bottom = descent;
|
||||
m_Top = m_Height - m_Bottom;
|
||||
}
|
||||
@@ -389,7 +415,7 @@ wxLayoutStyleInfo::wxLayoutStyleInfo(int ifamily,
|
||||
{
|
||||
family = ifamily; size = isize;
|
||||
style = istyle; weight = iweight;
|
||||
underline = iul;
|
||||
underline = iul != 0;
|
||||
if(fg)
|
||||
{
|
||||
m_fg = *fg;
|
||||
@@ -713,6 +739,10 @@ wxLayoutLine::Insert(CoordType xpos, wxLayoutObject *obj)
|
||||
{
|
||||
wxASSERT(xpos >= 0);
|
||||
wxASSERT(obj != NULL);
|
||||
|
||||
// in any case, the object is going to belong to this line
|
||||
obj->AttachToLine(this);
|
||||
|
||||
//FIXME: this could be optimised, for now be prudent:
|
||||
m_Dirty = true;
|
||||
CoordType offset;
|
||||
@@ -839,6 +869,7 @@ wxLayoutLine::Delete(CoordType xpos, CoordType npos)
|
||||
((wxLayoutObjectText *)(*i))->GetText().Remove(offset,max);
|
||||
}
|
||||
}
|
||||
|
||||
return npos;
|
||||
}
|
||||
|
||||
@@ -954,6 +985,7 @@ wxLayoutLine::Layout(wxDC &dc,
|
||||
wxLayoutObjectList::iterator i;
|
||||
|
||||
CoordType
|
||||
oldWidth = m_Width,
|
||||
oldHeight = m_Height;
|
||||
CoordType
|
||||
topHeight, bottomHeight; // above and below baseline
|
||||
@@ -1031,8 +1063,19 @@ wxLayoutLine::Layout(wxDC &dc,
|
||||
if(objTopHeight > topHeight) topHeight = objTopHeight;
|
||||
if(objBottomHeight > bottomHeight) bottomHeight = objBottomHeight;
|
||||
}
|
||||
if(topHeight + bottomHeight > m_Height) m_Height =
|
||||
topHeight+bottomHeight;
|
||||
|
||||
// special case of a line which becomes empty (after deletion, for example):
|
||||
// we should invalidate the screen space it occupied (usually this happens
|
||||
// from wxLayoutObject::Layout called in the loop above)
|
||||
if ( m_ObjectList.empty() )
|
||||
{
|
||||
wxPoint position(GetPosition());
|
||||
llist->SetUpdateRect(position.x + oldWidth + MSW_CORRECTION,
|
||||
position.y + oldHeight + MSW_CORRECTION);
|
||||
}
|
||||
|
||||
if(topHeight + bottomHeight > m_Height)
|
||||
m_Height = topHeight+bottomHeight;
|
||||
m_BaseLine = topHeight;
|
||||
|
||||
if(m_Height == 0)
|
||||
@@ -1138,17 +1181,43 @@ wxLayoutLine::MergeNextLine(wxLayoutList *llist)
|
||||
//FIXME: this could be optimised, for now be prudent:
|
||||
m_Dirty = true;
|
||||
|
||||
wxLayoutObject *last = NULL;
|
||||
for(i = list.begin(); i != list.end();)
|
||||
{
|
||||
Append(*i);
|
||||
wxLayoutObject *current = *i;
|
||||
|
||||
// merge text objects together for efficiency
|
||||
if ( last && last->GetType() == WXLO_TYPE_TEXT &&
|
||||
current->GetType() == WXLO_TYPE_TEXT )
|
||||
{
|
||||
wxLayoutObjectText *textObj = (wxLayoutObjectText *)last;
|
||||
wxString text(textObj->GetText());
|
||||
text += ((wxLayoutObjectText *)current)->GetText();
|
||||
textObj->SetText(text);
|
||||
|
||||
list.erase(i); // remove and delete it
|
||||
}
|
||||
else
|
||||
{
|
||||
// just append the object "as was"
|
||||
current->UnattachFromLine();
|
||||
Append(current);
|
||||
|
||||
list.remove(i); // remove without deleting it
|
||||
}
|
||||
}
|
||||
wxASSERT(list.empty());
|
||||
|
||||
wxLayoutLine *oldnext = GetNextLine();
|
||||
SetNext(GetNextLine()->GetNextLine());
|
||||
wxLayoutLine *nextLine = oldnext->GetNextLine();
|
||||
SetNext(nextLine);
|
||||
delete oldnext;
|
||||
GetNextLine()->MoveLines(-1);
|
||||
RecalculatePositions(1, llist);
|
||||
if ( nextLine )
|
||||
{
|
||||
nextLine->MoveLines(-1);
|
||||
}
|
||||
|
||||
// no RecalculatePositions needed - called from Delete() anyhow
|
||||
}
|
||||
|
||||
CoordType
|
||||
@@ -1297,6 +1366,10 @@ wxLayoutLine::Copy(wxLayoutList *llist,
|
||||
|
||||
wxLayoutList::wxLayoutList()
|
||||
{
|
||||
#ifdef WXLAYOUT_USE_CARET
|
||||
m_caret = NULL;
|
||||
#endif // WXLAYOUT_USE_CARET
|
||||
|
||||
m_FirstLine = NULL;
|
||||
InvalidateUpdateRect();
|
||||
Clear();
|
||||
@@ -1418,8 +1491,8 @@ wxLayoutList::FindText(const wxString &needle, const wxPoint &cpos) const
|
||||
bool
|
||||
wxLayoutList::MoveCursorTo(wxPoint const &p)
|
||||
{
|
||||
SetUpdateRect(m_CursorScreenPos);
|
||||
SetUpdateRect(m_CursorScreenPos+m_CursorSize);
|
||||
AddCursorPosToUpdateRect();
|
||||
|
||||
wxLayoutLine *line = m_FirstLine;
|
||||
while(line && line->GetLineNumber() != p.y)
|
||||
line = line->GetNextLine();
|
||||
@@ -1445,8 +1518,8 @@ wxLayoutList::MoveCursorTo(wxPoint const &p)
|
||||
bool
|
||||
wxLayoutList::MoveCursorVertically(int n)
|
||||
{
|
||||
SetUpdateRect(m_CursorScreenPos);
|
||||
SetUpdateRect(m_CursorScreenPos+m_CursorSize);
|
||||
AddCursorPosToUpdateRect();
|
||||
|
||||
bool rc;
|
||||
if(n < 0) // move up
|
||||
{
|
||||
@@ -1499,8 +1572,8 @@ wxLayoutList::MoveCursorVertically(int n)
|
||||
bool
|
||||
wxLayoutList::MoveCursorHorizontally(int n)
|
||||
{
|
||||
SetUpdateRect(m_CursorScreenPos);
|
||||
SetUpdateRect(m_CursorScreenPos+m_CursorSize);
|
||||
AddCursorPosToUpdateRect();
|
||||
|
||||
int move;
|
||||
while(n < 0)
|
||||
{
|
||||
@@ -1540,8 +1613,9 @@ bool
|
||||
wxLayoutList::Insert(wxString const &text)
|
||||
{
|
||||
wxASSERT(m_CursorLine);
|
||||
SetUpdateRect(m_CursorScreenPos);
|
||||
SetUpdateRect(m_CursorScreenPos+m_CursorSize);
|
||||
|
||||
AddCursorPosToUpdateRect();
|
||||
|
||||
m_CursorLine->Insert(m_CursorPos.x, text);
|
||||
m_CursorPos.x += text.Length();
|
||||
m_CursorLine->RecalculatePositions(true, this); //FIXME needed?
|
||||
@@ -1552,9 +1626,12 @@ bool
|
||||
wxLayoutList::Insert(wxLayoutObject *obj)
|
||||
{
|
||||
wxASSERT(m_CursorLine);
|
||||
if(! m_CursorLine) m_CursorLine = GetFirstLine();
|
||||
SetUpdateRect(m_CursorScreenPos);
|
||||
SetUpdateRect(m_CursorScreenPos+m_CursorSize);
|
||||
|
||||
if(! m_CursorLine)
|
||||
m_CursorLine = GetFirstLine();
|
||||
|
||||
AddCursorPosToUpdateRect();
|
||||
|
||||
m_CursorLine->Insert(m_CursorPos.x, obj);
|
||||
m_CursorPos.x += obj->GetLength();
|
||||
m_CursorLine->RecalculatePositions(true, this); //FIXME needed?
|
||||
@@ -1581,16 +1658,19 @@ wxLayoutList::Insert(wxLayoutList *llist)
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool
|
||||
wxLayoutList::LineBreak(void)
|
||||
{
|
||||
wxASSERT(m_CursorLine);
|
||||
bool setFirst = (m_CursorLine == m_FirstLine && m_CursorPos.x == 0);
|
||||
SetUpdateRect(m_CursorScreenPos);
|
||||
SetUpdateRect(m_CursorScreenPos+m_CursorSize);
|
||||
|
||||
AddCursorPosToUpdateRect();
|
||||
|
||||
wxPoint position(m_CursorLine->GetPosition());
|
||||
|
||||
wxCoord width = m_CursorLine->GetWidth(),
|
||||
height = m_CursorLine->GetHeight();
|
||||
|
||||
m_CursorLine = m_CursorLine->Break(m_CursorPos.x, this);
|
||||
if(setFirst) // we were at beginning of first line
|
||||
m_FirstLine = m_CursorLine->GetPreviousLine();
|
||||
@@ -1598,7 +1678,16 @@ wxLayoutList::LineBreak(void)
|
||||
m_CursorPos.y++;
|
||||
m_CursorPos.x = 0;
|
||||
// doesn't help m_CursorLine.MarkDirty();
|
||||
m_CursorLine->RecalculatePositions(true, this); //FIXME needed?
|
||||
|
||||
wxLayoutLine *prev = m_CursorLine->GetPreviousLine();
|
||||
wxCHECK_MSG(prev, false, "just broke the line, where is the previous one?");
|
||||
|
||||
height += prev->GetHeight();
|
||||
|
||||
SetUpdateRect(position);
|
||||
SetUpdateRect(position.x + width + MSW_CORRECTION,
|
||||
position.y + height + MSW_CORRECTION);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1615,8 +1704,9 @@ wxLayoutList::WrapLine(CoordType column)
|
||||
//else:
|
||||
CoordType newpos = m_CursorPos.x - xpos - 1;
|
||||
m_CursorPos.x = xpos;
|
||||
SetUpdateRect(m_CursorScreenPos);
|
||||
SetUpdateRect(m_CursorScreenPos+m_CursorSize);
|
||||
|
||||
AddCursorPosToUpdateRect();
|
||||
|
||||
LineBreak();
|
||||
Delete(1); // delete the space
|
||||
m_CursorPos.x = newpos;
|
||||
@@ -1628,19 +1718,32 @@ wxLayoutList::WrapLine(CoordType column)
|
||||
bool
|
||||
wxLayoutList::Delete(CoordType npos)
|
||||
{
|
||||
wxASSERT(m_CursorLine);
|
||||
SetUpdateRect(m_CursorScreenPos);
|
||||
SetUpdateRect(m_CursorScreenPos+m_CursorSize);
|
||||
wxCHECK_MSG(m_CursorLine, false, "can't delete in non existing line");
|
||||
wxASSERT_MSG(npos > 0, "nothing to delete?");
|
||||
|
||||
AddCursorPosToUpdateRect();
|
||||
|
||||
// were other lines appended to this one (this is important to know because
|
||||
// this means that our width _increased_ as the result of deletion)
|
||||
bool wasMerged = false;
|
||||
|
||||
// the size of the region to update
|
||||
CoordType totalHeight = m_CursorLine->GetHeight(),
|
||||
totalWidth = m_CursorLine->GetWidth();
|
||||
|
||||
CoordType left;
|
||||
do
|
||||
{
|
||||
left = m_CursorLine->Delete(m_CursorPos.x, npos);
|
||||
if(left == 0)
|
||||
return true;
|
||||
|
||||
if( left > 0 )
|
||||
{
|
||||
// More to delete, continue on next line.
|
||||
|
||||
// First, check if line is empty:
|
||||
if(m_CursorLine->GetLength() == 0)
|
||||
{ // in this case, updating could probably be optimised
|
||||
{
|
||||
// in this case, updating could probably be optimised
|
||||
#ifdef WXLO_DEBUG
|
||||
wxASSERT(DeleteLines(1) == 0);
|
||||
#else
|
||||
@@ -1656,13 +1759,27 @@ wxLayoutList::Delete(CoordType npos)
|
||||
break; // cannot
|
||||
else
|
||||
{
|
||||
wasMerged = true;
|
||||
wxLayoutLine *next = m_CursorLine->GetNextLine();
|
||||
if ( next )
|
||||
totalHeight += next->GetHeight();
|
||||
m_CursorLine->MergeNextLine(this);
|
||||
left--;
|
||||
}
|
||||
}
|
||||
}
|
||||
while(left);
|
||||
m_CursorLine->RecalculatePositions(true, this); //FIXME needed?
|
||||
}
|
||||
while ( left> 0 );
|
||||
|
||||
// we need to update the whole tail of the line and the lines which
|
||||
// disappeared
|
||||
if ( wasMerged )
|
||||
{
|
||||
wxPoint position(m_CursorLine->GetPosition());
|
||||
SetUpdateRect(position.x + totalWidth + MSW_CORRECTION,
|
||||
position.y + totalHeight + MSW_CORRECTION);
|
||||
}
|
||||
|
||||
return left == 0;
|
||||
}
|
||||
|
||||
@@ -1671,8 +1788,9 @@ wxLayoutList::DeleteLines(int n)
|
||||
{
|
||||
wxASSERT(m_CursorLine);
|
||||
wxLayoutLine *line;
|
||||
SetUpdateRect(m_CursorScreenPos);
|
||||
SetUpdateRect(m_CursorScreenPos+m_CursorSize);
|
||||
|
||||
AddCursorPosToUpdateRect();
|
||||
|
||||
while(n > 0)
|
||||
{
|
||||
if(!m_CursorLine->GetNextLine())
|
||||
@@ -1761,8 +1879,7 @@ wxLayoutList::Layout(wxDC &dc, CoordType bottom, bool forceAll)
|
||||
m_CursorLine->GetNextLine() == NULL &&
|
||||
m_CursorLine == m_FirstLine));
|
||||
#endif
|
||||
SetUpdateRect(m_CursorScreenPos);
|
||||
SetUpdateRect(m_CursorScreenPos+m_CursorSize);
|
||||
AddCursorPosToUpdateRect();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1859,10 +1976,8 @@ wxLayoutList::GetSize(void) const
|
||||
void
|
||||
wxLayoutList::DrawCursor(wxDC &dc, bool active, wxPoint const &translate)
|
||||
{
|
||||
wxPoint coords;
|
||||
coords = m_CursorScreenPos;
|
||||
coords.x += translate.x;
|
||||
coords.y += translate.y;
|
||||
wxPoint coords(m_CursorScreenPos);
|
||||
coords += translate;
|
||||
|
||||
#ifdef WXLAYOUT_DEBUG
|
||||
WXLO_DEBUG(("Drawing cursor (%ld,%ld) at %ld,%ld, size %ld,%ld, line: %ld, len %ld",
|
||||
@@ -1871,8 +1986,13 @@ wxLayoutList::DrawCursor(wxDC &dc, bool active, wxPoint const &translate)
|
||||
(long)m_CursorSize.x, (long)m_CursorSize.y,
|
||||
(long)m_CursorLine->GetLineNumber(),
|
||||
(long)m_CursorLine->GetLength()));
|
||||
|
||||
wxLogStatus("Cursor is at (%d, %d)", m_CursorPos.x, m_CursorPos.y);
|
||||
#endif
|
||||
|
||||
#ifdef WXLAYOUT_USE_CARET
|
||||
m_caret->Move(coords);
|
||||
#else // !WXLAYOUT_USE_CARET
|
||||
dc.SetBrush(*wxBLACK_BRUSH);
|
||||
dc.SetLogicalFunction(wxXOR);
|
||||
dc.SetPen(wxPen(*wxBLACK,1,wxSOLID));
|
||||
@@ -1892,6 +2012,7 @@ wxLayoutList::DrawCursor(wxDC &dc, bool active, wxPoint const &translate)
|
||||
}
|
||||
dc.SetLogicalFunction(wxCOPY);
|
||||
//dc.SetBrush(wxNullBrush);
|
||||
#endif // WXLAYOUT_USE_CARET/!WXLAYOUT_USE_CARET
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2173,6 +2294,7 @@ wxLayoutList::GetSelection(wxLayoutDataObject *wxlo, bool invalidate)
|
||||
export->content.object->Write(string);
|
||||
delete export;
|
||||
}
|
||||
|
||||
wxlo->SetData(string.c_str(), string.Length()+1);
|
||||
}
|
||||
return llist;
|
||||
|
@@ -30,6 +30,12 @@
|
||||
# define WXMENU_LAYOUT_DBLCLICK 1113
|
||||
#endif
|
||||
|
||||
// use the wxWindows caret class instead of home grown cursor whenever possible
|
||||
#ifdef __WXMSW__
|
||||
#undef WXLAYOUT_USE_CARET
|
||||
#define WXLAYOUT_USE_CARET 1
|
||||
#endif // __WXMSW__
|
||||
|
||||
// do not enable debug mode within Mahogany
|
||||
#if defined(__WXDEBUG__) && ! defined(M_BASEDIR)
|
||||
# define WXLAYOUT_DEBUG
|
||||
@@ -72,11 +78,13 @@ typedef long CoordType;
|
||||
|
||||
// Forward declarations.
|
||||
class wxLayoutList;
|
||||
class wxLayoutLine;
|
||||
class wxLayoutObject;
|
||||
class wxDC;
|
||||
class wxColour;
|
||||
class wxFont;
|
||||
|
||||
class WXDLLEXPORT wxCaret;
|
||||
class WXDLLEXPORT wxColour;
|
||||
class WXDLLEXPORT wxDC;
|
||||
class WXDLLEXPORT wxFont;
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
|
||||
@@ -118,7 +126,7 @@ public:
|
||||
@param dc the wxDC to draw on
|
||||
@param llist the wxLayoutList
|
||||
*/
|
||||
virtual void Layout(wxDC &dc, class wxLayoutList *llist) = 0;
|
||||
virtual void Layout(wxDC &dc, wxLayoutList *llist) = 0;
|
||||
|
||||
/** Draws an object.
|
||||
@param dc the wxDC to draw on
|
||||
@@ -129,7 +137,7 @@ public:
|
||||
*/
|
||||
virtual void Draw(wxDC & /* dc */,
|
||||
wxPoint const & /* coords */,
|
||||
class wxLayoutList *wxllist,
|
||||
wxLayoutList *wxllist,
|
||||
CoordType begin = -1,
|
||||
CoordType end = -1) { }
|
||||
|
||||
@@ -154,7 +162,7 @@ public:
|
||||
virtual CoordType GetOffsetScreen(wxDC &dc, CoordType xpos) const { return 0; }
|
||||
|
||||
/// constructor
|
||||
wxLayoutObject() { m_UserData = NULL; }
|
||||
wxLayoutObject() { m_UserData = NULL; m_Line = NULL; }
|
||||
/// delete the user data
|
||||
virtual ~wxLayoutObject() { if(m_UserData) m_UserData->DecRef(); }
|
||||
|
||||
@@ -175,6 +183,20 @@ public:
|
||||
m_UserData->IncRef();
|
||||
}
|
||||
|
||||
/// returns the line we belong to (or NULL)
|
||||
wxLayoutLine *GetLine() const { return m_Line; }
|
||||
|
||||
/// attaches this object to the given line, it's an error to reattach us
|
||||
void AttachToLine(wxLayoutLine *line)
|
||||
{
|
||||
wxASSERT_MSG( !m_Line, "this layout object already belongs to a line" );
|
||||
|
||||
m_Line = line;
|
||||
}
|
||||
|
||||
/// unattaches the object (should reattach it immediately afterwards!)
|
||||
void UnattachFromLine() { if ( m_Line ) m_Line = (wxLayoutLine *)NULL; }
|
||||
|
||||
/** Return the user data.
|
||||
Increments the object's reference count. When no longer needed,
|
||||
caller must call DecRef() on the pointer returned.
|
||||
@@ -199,6 +221,9 @@ public:
|
||||
protected:
|
||||
/// optional data for application's use
|
||||
UserData *m_UserData;
|
||||
|
||||
/// the line of the text we belong to or NULL if we're not shown on screen
|
||||
wxLayoutLine *m_Line;
|
||||
};
|
||||
|
||||
/// Define a list type of wxLayoutObject pointers.
|
||||
@@ -222,9 +247,9 @@ public:
|
||||
wxLayoutObjectText(const wxString &txt = "");
|
||||
|
||||
virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_TEXT; }
|
||||
virtual void Layout(wxDC &dc, class wxLayoutList *llist);
|
||||
virtual void Layout(wxDC &dc, wxLayoutList *llist);
|
||||
virtual void Draw(wxDC &dc, wxPoint const &coords,
|
||||
class wxLayoutList *wxllist,
|
||||
wxLayoutList *wxllist,
|
||||
CoordType begin = -1,
|
||||
CoordType end = -1);
|
||||
/** Calculates and returns the size of the object.
|
||||
@@ -284,9 +309,9 @@ public:
|
||||
~wxLayoutObjectIcon() { if(m_Icon) delete m_Icon; }
|
||||
|
||||
virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_ICON; }
|
||||
virtual void Layout(wxDC &dc, class wxLayoutList *llist);
|
||||
virtual void Layout(wxDC &dc, wxLayoutList *llist);
|
||||
virtual void Draw(wxDC &dc, wxPoint const &coords,
|
||||
class wxLayoutList *wxllist,
|
||||
wxLayoutList *wxllist,
|
||||
CoordType begin = -1,
|
||||
CoordType end = -1);
|
||||
|
||||
@@ -372,7 +397,8 @@ public:
|
||||
bool underline);
|
||||
wxFont & GetFont(wxLayoutStyleInfo const &si)
|
||||
{
|
||||
return GetFont(si.family, si.size, si.style, si.weight, si.underline);
|
||||
return GetFont(si.family, si.size, si.style, si.weight,
|
||||
si.underline != 0);
|
||||
}
|
||||
private:
|
||||
wxFCEList m_FontList;
|
||||
@@ -389,9 +415,9 @@ class wxLayoutObjectCmd : public wxLayoutObject
|
||||
{
|
||||
public:
|
||||
virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_CMD; }
|
||||
virtual void Layout(wxDC &dc, class wxLayoutList *llist);
|
||||
virtual void Layout(wxDC &dc, wxLayoutList *llist);
|
||||
virtual void Draw(wxDC &dc, wxPoint const &coords,
|
||||
class wxLayoutList *wxllist,
|
||||
wxLayoutList *wxllist,
|
||||
CoordType begin = -1,
|
||||
CoordType end = -1);
|
||||
wxLayoutObjectCmd(int family = -1,
|
||||
@@ -419,9 +445,6 @@ private:
|
||||
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
/// forward declaration
|
||||
class wxLayoutList;
|
||||
|
||||
/** This class represents a single line of objects to be displayed.
|
||||
It knows its height and total size and whether it needs to be
|
||||
redrawn or not.
|
||||
@@ -457,6 +480,8 @@ public:
|
||||
void Append(wxLayoutObject * obj)
|
||||
{
|
||||
wxASSERT(obj);
|
||||
|
||||
obj->AttachToLine(this);
|
||||
m_ObjectList.push_back(obj);
|
||||
m_Length += obj->GetLength();
|
||||
}
|
||||
@@ -711,6 +736,11 @@ public:
|
||||
/// Destructor.
|
||||
~wxLayoutList();
|
||||
|
||||
#ifdef WXLAYOUT_USE_CARET
|
||||
/// give us the pointer to the caret to use
|
||||
void SetCaret(wxCaret *caret) { m_caret = caret; }
|
||||
#endif // WXLAYOUT_USE_CARET
|
||||
|
||||
/// Clear the list.
|
||||
void Clear(int family = wxROMAN,
|
||||
int size=WXLO_DEFAULTFONTSIZE,
|
||||
@@ -944,6 +974,15 @@ public:
|
||||
*/
|
||||
inline void SetUpdateRect(const wxPoint &p)
|
||||
{ SetUpdateRect(p.x,p.y); }
|
||||
/// adds the cursor position to the update rectangle
|
||||
void AddCursorPosToUpdateRect()
|
||||
{
|
||||
#ifndef WXLAYOUT_USE_CARET
|
||||
SetUpdateRect(m_CursorScreenPos);
|
||||
SetUpdateRect(m_CursorScreenPos+m_CursorSize);
|
||||
//#else - the caret will take care of refreshing itself
|
||||
#endif // !WXLAYOUT_USE_CARET
|
||||
}
|
||||
/// Invalidates the update rectangle.
|
||||
void InvalidateUpdateRect(void) { m_UpdateRectValid = false; }
|
||||
/// Returns the update rectangle.
|
||||
@@ -1018,12 +1057,16 @@ private:
|
||||
//@{
|
||||
/// Where the text cursor (column,line) is.
|
||||
wxPoint m_CursorPos;
|
||||
/// The size of the cursor.
|
||||
wxPoint m_CursorSize;
|
||||
/// Where the cursor should be drawn.
|
||||
wxPoint m_CursorScreenPos;
|
||||
/// The line where the cursor is.
|
||||
wxLayoutLine *m_CursorLine;
|
||||
/// The size of the cursor.
|
||||
wxPoint m_CursorSize;
|
||||
#ifdef WXLAYOUT_USE_CARET
|
||||
/// the caret
|
||||
wxCaret *m_caret;
|
||||
#endif // WXLAYOUT_USE_CARET
|
||||
//@}
|
||||
|
||||
/// A structure for the selection.
|
||||
@@ -1045,7 +1088,6 @@ private:
|
||||
//@}
|
||||
};
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
|
||||
The wxLayoutDataObject for exporting data to the clipboard in our
|
||||
|
@@ -10,7 +10,14 @@
|
||||
# pragma implementation "wxlparser.h"
|
||||
#endif
|
||||
|
||||
#include <wx/wxprec.h>
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
# pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include "Mpch.h"
|
||||
|
||||
#ifdef M_PREFIX
|
||||
# include "gui/wxllist.h"
|
||||
# include "gui/wxlparser.h"
|
||||
|
@@ -11,12 +11,13 @@
|
||||
#endif
|
||||
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
# pragma hdrstop
|
||||
#endif
|
||||
|
||||
|
||||
#include "Mpch.h"
|
||||
|
||||
#ifdef M_BASEDIR
|
||||
# ifndef USE_PCH
|
||||
# include "Mcommon.h"
|
||||
@@ -41,6 +42,10 @@
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/dataobj.h>
|
||||
|
||||
#ifdef WXLAYOUT_USE_CARET
|
||||
# include <wx/caret.h>
|
||||
#endif // WXLAYOUT_USE_CARET
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef WXLAYOUT_DEBUG
|
||||
@@ -71,7 +76,8 @@ BEGIN_EVENT_TABLE(wxLayoutWindow,wxScrolledWindow)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
wxLayoutWindow::wxLayoutWindow(wxWindow *parent)
|
||||
: wxScrolledWindow(parent, -1, wxDefaultPosition, wxDefaultSize,
|
||||
: wxScrolledWindow(parent, -1,
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
wxHSCROLL | wxVSCROLL | wxBORDER)
|
||||
|
||||
{
|
||||
@@ -85,6 +91,7 @@ wxLayoutWindow::wxLayoutWindow(wxWindow *parent)
|
||||
m_bitmap = new wxBitmap(4,4);
|
||||
m_bitmapSize = wxPoint(4,4);
|
||||
m_llist = new wxLayoutList();
|
||||
|
||||
m_BGbitmap = NULL;
|
||||
m_ScrollToCursor = false;
|
||||
SetWrapMargin(0);
|
||||
@@ -93,6 +100,15 @@ wxLayoutWindow::wxLayoutWindow(wxWindow *parent)
|
||||
EnableScrolling(true,true);
|
||||
m_maxx = max.x; m_maxy = max.y;
|
||||
m_Selecting = false;
|
||||
|
||||
#ifdef WXLAYOUT_USE_CARET
|
||||
// FIXME cursor size shouldn't be hardcoded
|
||||
wxCaret *caret = new wxCaret(this, 2, 20);
|
||||
SetCaret(caret);
|
||||
m_llist->SetCaret(caret);
|
||||
caret->Show();
|
||||
#endif // WXLAYOUT_USE_CARET
|
||||
|
||||
SetCursorVisibility(-1);
|
||||
SetCursor(wxCURSOR_IBEAM);
|
||||
SetDirty();
|
||||
@@ -121,12 +137,8 @@ wxLayoutWindow::Clear(int family,
|
||||
ResizeScrollbars(true);
|
||||
SetDirty();
|
||||
SetModified(false);
|
||||
wxRect r;
|
||||
int w,h;
|
||||
r.x = r.y = 0; GetSize(&w,&h);
|
||||
r.width = w;
|
||||
r.height = h;
|
||||
DoPaint(&r);
|
||||
|
||||
DoPaint((wxRect *)NULL);
|
||||
}
|
||||
|
||||
#ifdef __WXMSW__
|
||||
@@ -323,7 +335,10 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
|
||||
break;
|
||||
default:
|
||||
if(keyCode == 'c' && event.ControlDown())
|
||||
{
|
||||
// this should work even in read-only mode
|
||||
Copy();
|
||||
}
|
||||
if( IsEditable() )
|
||||
{
|
||||
/* First, handle control keys */
|
||||
@@ -353,9 +368,6 @@ wxLayoutWindow::OnChar(wxKeyEvent& event)
|
||||
case 'v':
|
||||
Paste();
|
||||
break;
|
||||
case 'c':
|
||||
Copy();
|
||||
break;
|
||||
case 'x':
|
||||
Cut();
|
||||
break;
|
||||
@@ -513,6 +525,11 @@ wxLayoutWindow::InternalPaint(const wxRect *updateRect)
|
||||
wxPaintDC dc( this );
|
||||
PrepareDC( dc );
|
||||
|
||||
#ifdef WXLAYOUT_USE_CARET
|
||||
// hide the caret before drawing anything
|
||||
GetCaret()->Hide();
|
||||
#endif // WXLAYOUT_USE_CARET
|
||||
|
||||
int x0,y0,x1,y1, dx, dy;
|
||||
|
||||
// Calculate where the top of the visible area is:
|
||||
@@ -604,7 +621,7 @@ wxLayoutWindow::InternalPaint(const wxRect *updateRect)
|
||||
// update rectangle (although they are drawn on the memDC, this is
|
||||
// needed to erase it):
|
||||
m_llist->InvalidateUpdateRect();
|
||||
if(m_CursorVisibility == 1)
|
||||
if(m_CursorVisibility != 0)
|
||||
m_llist->DrawCursor(*m_memDC,
|
||||
m_HaveFocus && IsEditable(), // draw a thick
|
||||
// cursor for editable windows with focus
|
||||
@@ -636,12 +653,19 @@ wxLayoutWindow::InternalPaint(const wxRect *updateRect)
|
||||
dc.Blit(x0,y0,x1,y1,m_memDC,0,0,wxCOPY,FALSE);
|
||||
}
|
||||
|
||||
#ifdef WXLAYOUT_USE_CARET
|
||||
// show the caret back after everything is redrawn
|
||||
m_caret->Show();
|
||||
#endif // WXLAYOUT_USE_CARET
|
||||
|
||||
ResetDirty();
|
||||
m_ScrollToCursor = false;
|
||||
if(m_StatusBar && m_StatusFieldCursor != -1)
|
||||
{
|
||||
wxString label;
|
||||
label.Printf(_("L:%d C:%d"), m_llist->GetCursorPos().x+1, m_llist->GetCursorPos().y+1);
|
||||
label.Printf(_("Ln:%d Col:%d"),
|
||||
m_llist->GetCursorPos().y+1,
|
||||
m_llist->GetCursorPos().x+1);
|
||||
m_StatusBar->SetStatusText(label, m_StatusFieldCursor);
|
||||
}
|
||||
}
|
||||
@@ -698,6 +722,7 @@ wxLayoutWindow::Paste(void)
|
||||
}
|
||||
wxTheClipboard->Close();
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* My attempt to get the primary selection, but it does not
|
||||
work. :-( */
|
||||
@@ -758,6 +783,7 @@ wxLayoutWindow::Copy(bool invalidate)
|
||||
wxTheClipboard->Close();
|
||||
return rc;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@@ -23,7 +23,7 @@
|
||||
#endif
|
||||
|
||||
|
||||
#define wxUSE_PRIVATE_CLIPBOARD_FORMAT 0
|
||||
#define wxUSE_PRIVATE_CLIPBOARD_FORMAT 1
|
||||
|
||||
enum
|
||||
{
|
||||
|
Reference in New Issue
Block a user