1. bg bitmap reenabled
2. wxCaret positioning reenabled
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2681
c3d73ce0-8a6f-49c7-b76d-
6d57e0e08775
llist->Insert("And here the source for the test program:");
llist->LineBreak();
llist->Insert("And here the source for the test program:");
llist->Insert("And here the source for the test program:");
llist->LineBreak();
llist->Insert("And here the source for the test program:");
char buffer[1024];
FILE *in = fopen("wxLayout.cpp","r");
if(in)
char buffer[1024];
FILE *in = fopen("wxLayout.cpp","r");
if(in)
wxLayoutImportText(llist, buffer);
}
}
wxLayoutImportText(llist, buffer);
}
}
llist->MoveCursorTo(wxPoint(0,0));
m_lwin->SetDirty();
m_lwin->Refresh();
llist->MoveCursorTo(wxPoint(0,0));
m_lwin->SetDirty();
m_lwin->Refresh();
"This is a text\n"
"with embedded line\n"
"breaks.\n");
"This is a text\n"
"with embedded line\n"
"breaks.\n");
+ m_lwin->SetDirty();
+ m_lwin->Refresh();
Draw() just draws them with the current settings, without
re-layout()ing them again
Draw() just draws them with the current settings, without
re-layout()ing them again
- Each line has its own wxLayoutStyleInfo structure which gets updated
- from within Layout(). Thanks to this, we don't need to re-layout all
+ Each line has its own wxLayoutStyleInfo structure which gets updated
+ from within Layout(). Thanks to this, we don't need to re-layout all
lines if we want to draw one, but can just use its styleinfo to set
the right font.
lines if we want to draw one, but can just use its styleinfo to set
the right font.
#define WXLO_CURSORCHAR "E"
/** @name Helper functions */
//@{
#define WXLO_CURSORCHAR "E"
/** @name Helper functions */
//@{
+/// allows me to compare to wxPoints
+bool operator <=(wxPoint const &p1, wxPoint const &p2)
+{
+ return p1.y < p2.y || (p1.y == p2.y && p1.x <= p2.x);
+}
+
/*
The following STAY HERE until we have a working wxGTK again!!!
*/
/*
The following STAY HERE until we have a working wxGTK again!!!
*/
/// allows me to compare to wxPoints
bool operator ==(wxPoint const &p1, wxPoint const &p2)
{
/// allows me to compare to wxPoints
bool operator ==(wxPoint const &p1, wxPoint const &p2)
{
p1.y += p2.y;
return p1;
}
p1.y += p2.y;
return p1;
}
/// 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.y < p2.y || (p1.y == p2.y && p1.x <= p2.x);
}
/// grows a wxRect so that it includes the given point
}
/// grows a wxRect so that it includes the given point
wxLayoutList *wxllist,
CoordType begin, CoordType end)
{
wxLayoutList *wxllist,
CoordType begin, CoordType end)
{
+ if( end <= 0 )
+ {
+ // draw the whole object normally
dc.DrawText(m_Text, coords.x, coords.y-m_Top);
dc.DrawText(m_Text, coords.x, coords.y-m_Top);
else
{
// highlight the bit between begin and len
else
{
// highlight the bit between begin and len
CoordType
xpos = coords.x,
ypos = coords.y-m_Top;
CoordType
xpos = coords.x,
ypos = coords.y-m_Top;
if( end > (signed)m_Text.Length() )
end = m_Text.Length();
if( end > (signed)m_Text.Length() )
end = m_Text.Length();
- str = m_Text.Mid(0, begin);
+ wxString str = m_Text.Mid(0, begin);
dc.DrawText(str, xpos, ypos);
dc.GetTextExtent(str, &width, &height, &descent);
xpos += width;
dc.DrawText(str, xpos, ypos);
dc.GetTextExtent(str, &width, &height, &descent);
xpos += width;
// to update their styleinfo structure.
if(obj->GetType() == WXLO_TYPE_CMD)
MarkNextDirty(-1);
// to update their styleinfo structure.
if(obj->GetType() == WXLO_TYPE_CMD)
MarkNextDirty(-1);
CoordType offset;
wxLOiterator i = FindObject(xpos, &offset);
if(i == NULLIT)
CoordType offset;
wxLOiterator i = FindObject(xpos, &offset);
if(i == NULLIT)
- This function does all the recalculation, that is, it should only be
+ This function does all the recalculation, that is, it should only be
called from within wxLayoutList::Layout(), as it uses the current
list's styleinfo and updates it.
*/
called from within wxLayoutList::Layout(), as it uses the current
list's styleinfo and updates it.
*/
bool resetCursorMovedFlag,
const wxPoint& translate)
{
bool resetCursorMovedFlag,
const wxPoint& translate)
{
wxCHECK_RET( m_CursorLine, "no cursor line" );
if ( m_movedCursor )
wxCHECK_RET( m_CursorLine, "no cursor line" );
if ( m_movedCursor )
m_CursorPos.x,
/* suppress update */ true);
ApplyStyle(SiBackup, dc); // restore it
m_CursorPos.x,
/* suppress update */ true);
ApplyStyle(SiBackup, dc); // restore it
if ( resetCursorMovedFlag )
{
#ifdef WXLAYOUT_USE_CARET
if ( resetCursorMovedFlag )
{
#ifdef WXLAYOUT_USE_CARET
// This one we always Layout() to get the current cursor
// coordinates on the screen:
m_CursorLine->MarkDirty();
// This one we always Layout() to get the current cursor
// coordinates on the screen:
m_CursorLine->MarkDirty();
- // FIXME this is completely wrong - we should start by first *visible* line
- // (and stop on the last one) instead of looping over all lines!!
bool wasDirty = false;
wxLayoutLine *line = m_FirstLine;
while(line)
bool wasDirty = false;
wxLayoutLine *line = m_FirstLine;
while(line)
-wxLayoutList::StartSelection(wxPoint cpos)
+wxLayoutList::StartSelection(const wxPoint& cposOrig, const wxPoint& spos)
+ wxPoint cpos(cposOrig);
+ if ( cpos.x == -1 )
cpos = m_CursorPos;
WXLO_DEBUG(("Starting selection at %ld/%ld", cpos.x, cpos.y));
m_Selection.m_CursorA = cpos;
m_Selection.m_CursorB = cpos;
cpos = m_CursorPos;
WXLO_DEBUG(("Starting selection at %ld/%ld", cpos.x, cpos.y));
m_Selection.m_CursorA = cpos;
m_Selection.m_CursorB = cpos;
+ m_Selection.m_ScreenA = spos;
+ m_Selection.m_ScreenB = spos;
m_Selection.m_selecting = true;
m_Selection.m_valid = false;
}
void
m_Selection.m_selecting = true;
m_Selection.m_valid = false;
}
void
-wxLayoutList::ContinueSelection(wxPoint cpos)
+wxLayoutList::ContinueSelection(const wxPoint& cposOrig, const wxPoint& spos)
+ wxPoint cpos(cposOrig);
if(cpos.x == -1)
cpos = m_CursorPos;
if(cpos.x == -1)
cpos = m_CursorPos;
wxASSERT(m_Selection.m_selecting == true);
wxASSERT(m_Selection.m_valid == false);
WXLO_DEBUG(("Continuing selection at %ld/%ld", cpos.x, cpos.y));
wxASSERT(m_Selection.m_selecting == true);
wxASSERT(m_Selection.m_valid == false);
WXLO_DEBUG(("Continuing selection at %ld/%ld", cpos.x, cpos.y));
- if(m_Selection.m_CursorB <= cpos)
+
+ if ( m_Selection.m_CursorB <= cpos )
+ {
+ m_Selection.m_ScreenB = spos;
m_Selection.m_CursorB = cpos;
m_Selection.m_CursorB = cpos;
+ {
+ m_Selection.m_ScreenA = spos;
m_Selection.m_CursorA = cpos;
m_Selection.m_CursorA = cpos;
- // We always want m_CursorA <= m_CursorB!
- if(! (m_Selection.m_CursorA <= m_Selection.m_CursorB))
+ }
+
+ // we always want m_CursorA <= m_CursorB!
+ if( m_Selection.m_CursorA > m_Selection.m_CursorB )
+ // exchange the start/end points
wxPoint help = m_Selection.m_CursorB;
m_Selection.m_CursorB = m_Selection.m_CursorA;
m_Selection.m_CursorA = help;
wxPoint help = m_Selection.m_CursorB;
m_Selection.m_CursorB = m_Selection.m_CursorA;
m_Selection.m_CursorA = help;
+
+ help = m_Selection.m_ScreenB;
+ m_Selection.m_ScreenB = m_Selection.m_ScreenA;
+ m_Selection.m_ScreenA = help;
-wxLayoutList::EndSelection(wxPoint cpos)
+wxLayoutList::EndSelection(const wxPoint& cposOrig, const wxPoint& spos)
+ wxPoint cpos(cposOrig);
if(cpos.x == -1)
cpos = m_CursorPos;
ContinueSelection(cpos);
if(cpos.x == -1)
cpos = m_CursorPos;
ContinueSelection(cpos);
m_Selection.m_valid = true;
}
m_Selection.m_valid = true;
}
+void
+wxLayoutList::DiscardSelection()
+{
+ if ( !HasSelection() )
+ return;
+
+ m_Selection.m_valid =
+ m_Selection.m_selecting = false;
+
+ // invalidate the area which was previousle selected - and which is not
+ // selected any more
+ if ( m_Selection.HasValidScreenCoords() )
+ {
+ SetUpdateRect(m_Selection.m_ScreenA);
+ SetUpdateRect(m_Selection.m_ScreenB);
+ }
+ else
+ {
+ // TODO
+ }
+}
bool
wxLayoutList::IsSelecting(void)
bool
wxLayoutList::IsSelecting(void)
bool
wxLayoutList::IsSelected(const wxPoint &cursor)
{
bool
wxLayoutList::IsSelected(const wxPoint &cursor)
{
- if(! m_Selection.m_valid && ! m_Selection.m_selecting)
- return m_Selection.m_CursorA <= cursor
- && cursor <= m_Selection.m_CursorB;
+
+ return m_Selection.m_CursorA <= cursor && cursor <= m_Selection.m_CursorB;
- /// Begin selecting text.
- void StartSelection(wxPoint cpos = wxPoint(-1,-1));
+ /// Begin selecting text
+ void StartSelection(const wxPoint& cpos = wxPoint(-1,-1),
+ const wxPoint& spos = wxPoint(-1,-1));
// Continue selecting text
// Continue selecting text
- void ContinueSelection(wxPoint cpos = wxPoint(-1,-1));
+ void ContinueSelection(const wxPoint& cpos = wxPoint(-1,-1),
+ const wxPoint& spos = wxPoint(-1,-1));
- void EndSelection(wxPoint cpos = wxPoint(-1,-1));
+ void EndSelection(const wxPoint& cpos = wxPoint(-1,-1),
+ const wxPoint& spos = wxPoint(-1,-1));
+ /// Discard the current selection
+ void DiscardSelection();
/// Are we still selecting text?
bool IsSelecting(void);
/// Are we still selecting text?
bool IsSelecting(void);
+ /// Is the given point (text coords) selected?
bool IsSelected(const wxPoint &cursor);
bool IsSelected(const wxPoint &cursor);
+ /// Do we have a non null selection?
+ bool HasSelection() const
+ { return m_Selection.m_valid || m_Selection.m_selecting; }
/** Return the selection as a wxLayoutList.
@param invalidate if true, the selection will be invalidated after this and can no longer be used.
/** Return the selection as a wxLayoutList.
@param invalidate if true, the selection will be invalidated after this and can no longer be used.
#ifdef WXLAYOUT_DEBUG
void Debug(void);
#endif
#ifdef WXLAYOUT_DEBUG
void Debug(void);
#endif
private:
/// Clear the list.
void InternalClear(void);
private:
/// Clear the list.
void InternalClear(void);
#endif // WXLAYOUT_USE_CARET
//@}
#endif // WXLAYOUT_USE_CARET
//@}
- /// A structure for the selection.
+ /// selection.state and begin/end coordinates
struct Selection
{
Selection() { m_valid = false; m_selecting = false; }
bool m_valid;
bool m_selecting;
struct Selection
{
Selection() { m_valid = false; m_selecting = false; }
bool m_valid;
bool m_selecting;
+
+ // returns true if we already have the screen coordinates of the
+ // selection start and end
+ bool HasValidScreenCoords() const
+ { return m_ScreenA.x != -1 && m_ScreenB.x != -1; }
+
+ // the start and end of the selection coordinates in pixels
+ wxPoint m_ScreenA, m_ScreenB;
+
+ // these coordinates are in text positions, not in pixels
wxPoint m_CursorA, m_CursorB;
} m_Selection;
/** @name Font parameters. */
wxPoint m_CursorA, m_CursorB;
} m_Selection;
/** @name Font parameters. */
// ===========================================================================
/* LEAVE IT HERE UNTIL WXGTK WORKS AGAIN!!! */
// ===========================================================================
/* LEAVE IT HERE UNTIL WXGTK WORKS AGAIN!!! */
/// allows me to compare to wxPoints
static bool operator != (wxPoint const &p1, wxPoint const &p2)
{
return p1.x != p2.x || p1.y != p2.y;
}
/// allows me to compare to wxPoints
static bool operator != (wxPoint const &p1, wxPoint const &p2)
{
return p1.x != p2.x || p1.y != p2.y;
}
+#endif // __WXGTK__
+
+#ifndef wxWANTS_CHARS
+ #define wxWANTS_CHARS 0
+#endif
// ----------------------------------------------------------------------------
// wxLayoutWindow
// ----------------------------------------------------------------------------
// wxLayoutWindow
: wxScrolledWindow(parent, -1,
wxDefaultPosition, wxDefaultSize,
wxHSCROLL | wxVSCROLL |
: wxScrolledWindow(parent, -1,
wxDefaultPosition, wxDefaultSize,
wxHSCROLL | wxVSCROLL |
- wxBORDER
- //FIXME |wxWANTS_CHARS
- )
+ wxBORDER |
+ wxWANTS_CHARS)
{
SetStatusBar(NULL); // don't use statusbar
m_Editable = false;
{
SetStatusBar(NULL); // don't use statusbar
m_Editable = false;
- m_llist->StartSelection();
+ m_llist->StartSelection(wxPoint(-1, -1), m_ClickPosition);
+ DoPaint(); // TODO: we don't have to redraw everything!
- m_llist->ContinueSelection(cursorPos);
- DoPaint(FALSE);
+ m_llist->ContinueSelection(cursorPos, m_ClickPosition);
+ DoPaint(); // TODO: we don't have to redraw everything!
}
}
if(m_Selecting && ! event.LeftIsDown())
{
}
}
if(m_Selecting && ! event.LeftIsDown())
{
- m_llist->EndSelection(cursorPos);
+ m_llist->EndSelection(cursorPos, m_ClickPosition);
+ DoPaint(); // TODO: we don't have to redraw everything!
- if(u) u->DecRef();
- return;
- }
- // always move cursor to mouse click:
- if(eventId == WXLOWIN_MENU_LCLICK)
+ if ( u )
+ {
+ u->DecRef();
+ u = NULL;
+ }
+ }
+ else if(eventId == WXLOWIN_MENU_LCLICK)
+ // always move cursor to mouse click:
m_llist->MoveCursorTo(cursorPos);
m_llist->MoveCursorTo(cursorPos);
+ // clicking a mouse removes the selection
+ if ( m_llist->HasSelection() )
+ {
+ m_llist->DiscardSelection();
+ DoPaint(); // TODO: we don't have to redraw everything!
+ }
+
// Calculate where the top of the visible area is:
int x0, y0;
ViewStart(&x0,&y0);
// Calculate where the top of the visible area is:
int x0, y0;
ViewStart(&x0,&y0);
#endif // 0
#ifdef __WXGTK__
#endif // 0
#ifdef __WXGTK__
- DoPaint(FALSE); // DoPaint suppresses flicker under GTK
+ DoPaint(); // DoPaint suppresses flicker under GTK
- if(!m_doSendEvents) // nothing to do
+ // notify about mouse events?
+ if( m_doSendEvents )
- if(u) u->DecRef();
- return;
- }
+ // only do the menu if activated, editable and not on a clickable object
+ if(eventId == WXLOWIN_MENU_RCLICK
+ && IsEditable()
+ && (! obj || u == NULL))
+ {
+ PopupMenu(m_PopupMenu, m_ClickPosition.x, m_ClickPosition.y);
+ if(u) u->DecRef();
+ return;
+ }
- // only do the menu if activated, editable and not on a clickable object
- if(eventId == WXLOWIN_MENU_RCLICK
- && IsEditable()
- && (! obj || u == NULL))
- {
- PopupMenu(m_PopupMenu, m_ClickPosition.x, m_ClickPosition.y);
- if(u) u->DecRef();
- return;
+ // find the object at this position
+ if(obj)
+ {
+ wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, eventId);
+ commandEvent.SetEventObject( this );
+ commandEvent.SetClientData((char *)obj);
+ GetEventHandler()->ProcessEvent(commandEvent);
+ }
- if(u) u->DecRef();
- // find the object at this position
- if(obj)
- {
- wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, eventId);
- commandEvent.SetEventObject( this );
- commandEvent.SetClientData((char *)obj);
- GetEventHandler()->ProcessEvent(commandEvent);
- }
m_memDC->SetPen(wxPen(m_llist->GetDefaultStyleInfo().GetBGColour(),
0,wxTRANSPARENT));
m_memDC->SetLogicalFunction(wxCOPY);
m_memDC->SetPen(wxPen(m_llist->GetDefaultStyleInfo().GetBGColour(),
0,wxTRANSPARENT));
m_memDC->SetLogicalFunction(wxCOPY);
- /* Either fill the background with the background bitmap, or clear
- it. */
+ // fill the background with the background bitmap
if(m_BGbitmap)
{
CoordType
if(m_BGbitmap)
{
CoordType
m_memDC->DrawBitmap(*m_BGbitmap, x, y);
m_memDC->SetBackgroundMode(wxTRANSPARENT);
}
m_memDC->DrawBitmap(*m_BGbitmap, x, y);
m_memDC->SetBackgroundMode(wxTRANSPARENT);
}
- else
- {
- // clear the background: (must not be done if we use the update rectangle!)
- m_memDC->SetBackgroundMode(wxSOLID);
- m_memDC->DrawRectangle(0,0,x1, y1);
- }
- m_memDC->Clear();
- /* This is the important bit: we tell the list to draw itself: */
+ // This is the important bit: we tell the list to draw itself
#if WXLO_DEBUG_URECT
if(updateRect)
{
#if WXLO_DEBUG_URECT
if(updateRect)
{
inline int SetCursorVisibility(int visibility = -1)
{ int v =m_CursorVisibility;
m_CursorVisibility = visibility; return v;}
inline int SetCursorVisibility(int visibility = -1)
{ int v =m_CursorVisibility;
m_CursorVisibility = visibility; return v;}
/// Pastes text from clipboard.
void Paste(void);
/** Copies selection to clipboard.
/// Pastes text from clipboard.
void Paste(void);
/** Copies selection to clipboard.
bool Find(const wxString &needle,
wxPoint * fromWhere = NULL);
bool Find(const wxString &needle,
wxPoint * fromWhere = NULL);
void EnablePopup(bool enable = true) { m_DoPopupMenu = enable; }
/** Sets the wrap margin.
@param margin set this to 0 to disable it
*/
void SetWrapMargin(CoordType margin) { m_WrapMargin = margin; }
void EnablePopup(bool enable = true) { m_DoPopupMenu = enable; }
/** Sets the wrap margin.
@param margin set this to 0 to disable it
*/
void SetWrapMargin(CoordType margin) { m_WrapMargin = margin; }
/** Redraws the window.
Internally, this stores the parameter and calls a refresh on
wxMSW, draws directly on wxGTK.
/** Redraws the window.
Internally, this stores the parameter and calls a refresh on
wxMSW, draws directly on wxGTK.
m_StatusBar = bar; m_StatusFieldLabel = labelfield;
m_StatusFieldCursor = cursorfield;
}
m_StatusBar = bar; m_StatusFieldLabel = labelfield;
m_StatusFieldCursor = cursorfield;
}
/// generic function for mouse events processing
void OnMouse(int eventId, wxMouseEvent& event);
/// as the name says
/// generic function for mouse events processing
void OnMouse(int eventId, wxMouseEvent& event);
/// as the name says