some small fixes to make it work a bit again under MSW:

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
This commit is contained in:
Vadim Zeitlin 1999-06-06 22:10:54 +00:00
parent f38c391ab0
commit d66f34ece7
5 changed files with 163 additions and 85 deletions

View File

@ -206,7 +206,7 @@ MyFrame::AddSampleText(wxLayoutList *llist)
llist->Insert("And here the source for the test program:"); llist->Insert("And here the source for the test program:");
llist->LineBreak(); llist->LineBreak();
llist->Insert("And here the source for the test program:"); llist->Insert("And here the source for the test program:");
#if 0
char buffer[1024]; char buffer[1024];
FILE *in = fopen("wxLayout.cpp","r"); FILE *in = fopen("wxLayout.cpp","r");
if(in) if(in)
@ -219,7 +219,7 @@ MyFrame::AddSampleText(wxLayoutList *llist)
wxLayoutImportText(llist, buffer); wxLayoutImportText(llist, buffer);
} }
} }
#endif
llist->MoveCursorTo(wxPoint(0,0)); llist->MoveCursorTo(wxPoint(0,0));
m_lwin->SetDirty(); m_lwin->SetDirty();
m_lwin->Refresh(); m_lwin->Refresh();
@ -331,6 +331,8 @@ void MyFrame::OnCommand( wxCommandEvent &event )
"This is a text\n" "This is a text\n"
"with embedded line\n" "with embedded line\n"
"breaks.\n"); "breaks.\n");
m_lwin->SetDirty();
m_lwin->Refresh();
break; break;
case ID_URL_TEST: case ID_URL_TEST:

View File

@ -14,11 +14,11 @@
Draw() just draws them with the current settings, without Draw() just draws them with the current settings, without
re-layout()ing them again re-layout()ing them again
Each line has its own wxLayoutStyleInfo structure which gets updated Each line has its own wxLayoutStyleInfo structure which gets updated
from within Layout(). Thanks to this, we don't need to re-layout all 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 lines if we want to draw one, but can just use its styleinfo to set
the right font. the right font.
*/ */
#ifdef __GNUG__ #ifdef __GNUG__
@ -98,9 +98,16 @@
#define WXLO_CURSORCHAR "E" #define WXLO_CURSORCHAR "E"
/** @name Helper functions */ /** @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!!!
*/ */
#ifdef __WXGTK__
/// 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)
{ {
@ -119,11 +126,12 @@ wxPoint & operator += (wxPoint &p1, wxPoint const &p2)
p1.y += p2.y; p1.y += p2.y;
return p1; return p1;
} }
#endif // wxGTK
/// 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); return !(p1 <= p2);
} }
/// grows a wxRect so that it includes the given point /// grows a wxRect so that it includes the given point
@ -251,12 +259,14 @@ wxLayoutObjectText::Draw(wxDC &dc, wxPoint const &coords,
wxLayoutList *wxllist, wxLayoutList *wxllist,
CoordType begin, CoordType end) CoordType begin, CoordType end)
{ {
if( end <= 0) 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 else
{ {
// highlight the bit between begin and len // highlight the bit between begin and len
wxString str;
CoordType CoordType
xpos = coords.x, xpos = coords.x,
ypos = coords.y-m_Top; ypos = coords.y-m_Top;
@ -266,7 +276,7 @@ wxLayoutObjectText::Draw(wxDC &dc, wxPoint const &coords,
if( end > (signed)m_Text.Length() ) if( end > (signed)m_Text.Length() )
end = 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.DrawText(str, xpos, ypos);
dc.GetTextExtent(str, &width, &height, &descent); dc.GetTextExtent(str, &width, &height, &descent);
xpos += width; xpos += width;
@ -799,7 +809,7 @@ wxLayoutLine::Insert(CoordType xpos, wxLayoutObject *obj)
// to update their styleinfo structure. // to update their styleinfo structure.
if(obj->GetType() == WXLO_TYPE_CMD) if(obj->GetType() == WXLO_TYPE_CMD)
MarkNextDirty(-1); MarkNextDirty(-1);
CoordType offset; CoordType offset;
wxLOiterator i = FindObject(xpos, &offset); wxLOiterator i = FindObject(xpos, &offset);
if(i == NULLIT) if(i == NULLIT)
@ -1056,7 +1066,7 @@ wxLayoutLine::Draw(wxDC &dc,
} }
/* /*
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 called from within wxLayoutList::Layout(), as it uses the current
list's styleinfo and updates it. list's styleinfo and updates it.
*/ */
@ -2079,7 +2089,6 @@ wxLayoutList::UpdateCursorScreenPos(wxDC &dc,
bool resetCursorMovedFlag, bool resetCursorMovedFlag,
const wxPoint& translate) const wxPoint& translate)
{ {
return;
wxCHECK_RET( m_CursorLine, "no cursor line" ); wxCHECK_RET( m_CursorLine, "no cursor line" );
if ( m_movedCursor ) if ( m_movedCursor )
@ -2092,7 +2101,7 @@ wxLayoutList::UpdateCursorScreenPos(wxDC &dc,
m_CursorPos.x, m_CursorPos.x,
/* suppress update */ true); /* suppress update */ true);
ApplyStyle(SiBackup, dc); // restore it ApplyStyle(SiBackup, dc); // restore it
if ( resetCursorMovedFlag ) if ( resetCursorMovedFlag )
{ {
#ifdef WXLAYOUT_USE_CARET #ifdef WXLAYOUT_USE_CARET
@ -2135,8 +2144,6 @@ wxLayoutList::Layout(wxDC &dc, CoordType bottom, bool forceAll)
// This one we always Layout() to get the current cursor // This one we always Layout() to get the current cursor
// coordinates on the screen: // coordinates on the screen:
m_CursorLine->MarkDirty(); 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; bool wasDirty = false;
wxLayoutLine *line = m_FirstLine; wxLayoutLine *line = m_FirstLine;
while(line) while(line)
@ -2352,41 +2359,60 @@ wxLayoutList::SetUpdateRect(CoordType x, CoordType y)
} }
void void
wxLayoutList::StartSelection(wxPoint cpos) wxLayoutList::StartSelection(const wxPoint& cposOrig, const wxPoint& spos)
{ {
if(cpos.x == -1) wxPoint cpos(cposOrig);
if ( cpos.x == -1 )
cpos = m_CursorPos; cpos = m_CursorPos;
WXLO_DEBUG(("Starting selection at %ld/%ld", cpos.x, cpos.y)); WXLO_DEBUG(("Starting selection at %ld/%ld", cpos.x, cpos.y));
m_Selection.m_CursorA = cpos; m_Selection.m_CursorA = cpos;
m_Selection.m_CursorB = cpos; m_Selection.m_CursorB = cpos;
m_Selection.m_ScreenA = spos;
m_Selection.m_ScreenB = spos;
m_Selection.m_selecting = true; m_Selection.m_selecting = true;
m_Selection.m_valid = false; m_Selection.m_valid = false;
} }
void void
wxLayoutList::ContinueSelection(wxPoint cpos) wxLayoutList::ContinueSelection(const wxPoint& cposOrig, const wxPoint& spos)
{ {
wxPoint cpos(cposOrig);
if(cpos.x == -1) if(cpos.x == -1)
cpos = m_CursorPos; cpos = m_CursorPos;
wxASSERT(m_Selection.m_selecting == true); wxASSERT(m_Selection.m_selecting == true);
wxASSERT(m_Selection.m_valid == false); wxASSERT(m_Selection.m_valid == false);
WXLO_DEBUG(("Continuing selection at %ld/%ld", cpos.x, cpos.y)); WXLO_DEBUG(("Continuing selection at %ld/%ld", cpos.x, cpos.y));
if(m_Selection.m_CursorB <= cpos)
m_Selection.m_CursorB = cpos; if ( m_Selection.m_CursorB <= cpos )
else
m_Selection.m_CursorA = cpos;
// We always want m_CursorA <= m_CursorB!
if(! (m_Selection.m_CursorA <= m_Selection.m_CursorB))
{ {
m_Selection.m_ScreenB = spos;
m_Selection.m_CursorB = cpos;
}
else
{
m_Selection.m_ScreenA = spos;
m_Selection.m_CursorA = cpos;
}
// 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; wxPoint help = m_Selection.m_CursorB;
m_Selection.m_CursorB = m_Selection.m_CursorA; m_Selection.m_CursorB = m_Selection.m_CursorA;
m_Selection.m_CursorA = help; m_Selection.m_CursorA = help;
help = m_Selection.m_ScreenB;
m_Selection.m_ScreenB = m_Selection.m_ScreenA;
m_Selection.m_ScreenA = help;
} }
} }
void void
wxLayoutList::EndSelection(wxPoint cpos) wxLayoutList::EndSelection(const wxPoint& cposOrig, const wxPoint& spos)
{ {
wxPoint cpos(cposOrig);
if(cpos.x == -1) if(cpos.x == -1)
cpos = m_CursorPos; cpos = m_CursorPos;
ContinueSelection(cpos); ContinueSelection(cpos);
@ -2395,6 +2421,27 @@ wxLayoutList::EndSelection(wxPoint 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 bool
wxLayoutList::IsSelecting(void) wxLayoutList::IsSelecting(void)
@ -2405,10 +2452,10 @@ wxLayoutList::IsSelecting(void)
bool bool
wxLayoutList::IsSelected(const wxPoint &cursor) wxLayoutList::IsSelected(const wxPoint &cursor)
{ {
if(! m_Selection.m_valid && ! m_Selection.m_selecting) if ( !HasSelection() )
return false; return false;
return m_Selection.m_CursorA <= cursor
&& cursor <= m_Selection.m_CursorB; return m_Selection.m_CursorA <= cursor && cursor <= m_Selection.m_CursorB;
} }

View File

@ -1025,15 +1025,24 @@ public:
} }
//@} //@}
/// Begin selecting text. /// Begin selecting text
void StartSelection(wxPoint cpos = wxPoint(-1,-1)); 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));
/// End selecting text. /// End selecting text.
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? /// Are we still selecting text?
bool IsSelecting(void); 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. /** Return the selection as a wxLayoutList.
@param invalidate if true, the selection will be invalidated after this and can no longer be used. @param invalidate if true, the selection will be invalidated after this and can no longer be used.
@ -1066,6 +1075,7 @@ public:
#ifdef WXLAYOUT_DEBUG #ifdef WXLAYOUT_DEBUG
void Debug(void); void Debug(void);
#endif #endif
private: private:
/// Clear the list. /// Clear the list.
void InternalClear(void); void InternalClear(void);
@ -1094,12 +1104,22 @@ private:
#endif // WXLAYOUT_USE_CARET #endif // WXLAYOUT_USE_CARET
//@} //@}
/// A structure for the selection. /// selection.state and begin/end coordinates
struct Selection struct Selection
{ {
Selection() { m_valid = false; m_selecting = false; } Selection() { m_valid = false; m_selecting = false; }
bool m_valid; bool m_valid;
bool m_selecting; 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; wxPoint m_CursorA, m_CursorB;
} m_Selection; } m_Selection;
/** @name Font parameters. */ /** @name Font parameters. */

View File

@ -101,11 +101,17 @@ END_EVENT_TABLE()
// =========================================================================== // ===========================================================================
/* LEAVE IT HERE UNTIL WXGTK WORKS AGAIN!!! */ /* LEAVE IT HERE UNTIL WXGTK WORKS AGAIN!!! */
#ifdef __WXGTK__
/// allows me to compare to wxPoints /// allows me to compare to wxPoints
static bool operator != (wxPoint const &p1, wxPoint const &p2) static 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;
} }
#endif // __WXGTK__
#ifndef wxWANTS_CHARS
#define wxWANTS_CHARS 0
#endif
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxLayoutWindow // wxLayoutWindow
@ -115,9 +121,8 @@ wxLayoutWindow::wxLayoutWindow(wxWindow *parent)
: wxScrolledWindow(parent, -1, : wxScrolledWindow(parent, -1,
wxDefaultPosition, wxDefaultSize, wxDefaultPosition, wxDefaultSize,
wxHSCROLL | wxVSCROLL | wxHSCROLL | wxVSCROLL |
wxBORDER wxBORDER |
//FIXME |wxWANTS_CHARS wxWANTS_CHARS)
)
{ {
SetStatusBar(NULL); // don't use statusbar SetStatusBar(NULL); // don't use statusbar
m_Editable = false; m_Editable = false;
@ -240,31 +245,41 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
{ {
if(! m_Selecting) if(! m_Selecting)
{ {
m_llist->StartSelection(); m_llist->StartSelection(wxPoint(-1, -1), m_ClickPosition);
m_Selecting = true; m_Selecting = true;
DoPaint(FALSE); DoPaint(); // TODO: we don't have to redraw everything!
} }
else else
{ {
m_llist->ContinueSelection(cursorPos); m_llist->ContinueSelection(cursorPos, m_ClickPosition);
DoPaint(FALSE); 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);
m_Selecting = false; m_Selecting = false;
DoPaint(FALSE); DoPaint(); // TODO: we don't have to redraw everything!
} }
if(u) u->DecRef();
return;
}
// always move cursor to mouse click: if ( u )
if(eventId == WXLOWIN_MENU_LCLICK) {
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: // Calculate where the top of the visible area is:
int x0, y0; int x0, y0;
ViewStart(&x0,&y0); ViewStart(&x0,&y0);
@ -285,35 +300,35 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event)
#endif // 0 #endif // 0
#ifdef __WXGTK__ #ifdef __WXGTK__
DoPaint(FALSE); // DoPaint suppresses flicker under GTK DoPaint(); // DoPaint suppresses flicker under GTK
#endif // wxGTK #endif // wxGTK
} }
if(!m_doSendEvents) // nothing to do // notify about mouse events?
if( m_doSendEvents )
{ {
if(u) u->DecRef(); // only do the menu if activated, editable and not on a clickable object
return; 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);
}
} }
// only do the menu if activated, editable and not on a clickable object if( u )
if(eventId == WXLOWIN_MENU_RCLICK u->DecRef();
&& IsEditable()
&& (! obj || u == NULL))
{
PopupMenu(m_PopupMenu, m_ClickPosition.x, m_ClickPosition.y);
if(u) u->DecRef();
return;
}
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);
}
} }
/* /*
@ -669,9 +684,9 @@ wxLayoutWindow::InternalPaint(const wxRect *updateRect)
m_memDC->SetPen(wxPen(m_llist->GetDefaultStyleInfo().GetBGColour(), m_memDC->SetPen(wxPen(m_llist->GetDefaultStyleInfo().GetBGColour(),
0,wxTRANSPARENT)); 0,wxTRANSPARENT));
m_memDC->SetLogicalFunction(wxCOPY); m_memDC->SetLogicalFunction(wxCOPY);
m_memDC->Clear();
/* Either fill the background with the background bitmap, or clear // fill the background with the background bitmap
it. */
if(m_BGbitmap) if(m_BGbitmap)
{ {
CoordType CoordType
@ -683,15 +698,8 @@ wxLayoutWindow::InternalPaint(const wxRect *updateRect)
m_memDC->DrawBitmap(*m_BGbitmap, x, y); m_memDC->DrawBitmap(*m_BGbitmap, x, y);
m_memDC->SetBackgroundMode(wxTRANSPARENT); 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 WXLO_DEBUG_URECT
if(updateRect) if(updateRect)
{ {

View File

@ -89,7 +89,7 @@ public:
inline int SetCursorVisibility(int visibility = -1) inline int SetCursorVisibility(int visibility = -1)
{ int v =m_CursorVisibility; { int v =m_CursorVisibility;
m_CursorVisibility = visibility; return v;} m_CursorVisibility = visibility; return v;}
/// Pastes text from clipboard. /// Pastes text from clipboard.
void Paste(void); void Paste(void);
/** Copies selection to clipboard. /** Copies selection to clipboard.
@ -102,14 +102,14 @@ public:
bool Find(const wxString &needle, bool Find(const wxString &needle,
wxPoint * fromWhere = NULL); wxPoint * fromWhere = NULL);
void EnablePopup(bool enable = true) { m_DoPopupMenu = enable; } void EnablePopup(bool enable = true) { m_DoPopupMenu = enable; }
/** Sets the wrap margin. /** Sets the wrap margin.
@param margin set this to 0 to disable it @param margin set this to 0 to disable it
*/ */
void SetWrapMargin(CoordType margin) { m_WrapMargin = margin; } void SetWrapMargin(CoordType margin) { m_WrapMargin = margin; }
/** Redraws the window. /** Redraws the window.
Internally, this stores the parameter and calls a refresh on Internally, this stores the parameter and calls a refresh on
wxMSW, draws directly on wxGTK. wxMSW, draws directly on wxGTK.
@ -172,7 +172,8 @@ public:
m_StatusBar = bar; m_StatusFieldLabel = labelfield; m_StatusBar = bar; m_StatusFieldLabel = labelfield;
m_StatusFieldCursor = cursorfield; m_StatusFieldCursor = cursorfield;
} }
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);
/// as the name says /// as the name says