X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/18d084cf1f5cae86cc3c956678a8910455a293af..d1fe5895350d957b0200bde6c864a670dfe1f9ae:/user/wxLayout/wxllist.cpp diff --git a/user/wxLayout/wxllist.cpp b/user/wxLayout/wxllist.cpp index c7d98309d9..89b8c26112 100644 --- a/user/wxLayout/wxllist.cpp +++ b/user/wxLayout/wxllist.cpp @@ -14,7 +14,7 @@ #pragma implementation "wxllist.h" #endif -//#include "Mpch.h" +#include "Mpch.h" #include "wx/wxprec.h" @@ -24,8 +24,11 @@ #ifdef M_BASEDIR # include "gui/wxllist.h" +# define SHOW_SELECTIONS 1 #else # include "wxllist.h" +# include "wxlparser.h" +# define SHOW_SELECTIONS 1 #endif #ifndef USE_PCH @@ -102,29 +105,17 @@ void GrowRect(wxRect &r, CoordType x, CoordType y) r.height = y - r.y; } +#if 0 +// unused /// returns true if the point is in the rectangle static bool Contains(const wxRect &r, const wxPoint &p) { return r.x <= p.x && r.y <= p.y && (r.x+r.width) >= p.x && (r.y + r.height) >= p.y; } +#endif -/// Starts highlighting the selection -static -inline void StartHighlighting(wxDC &dc) -{ - dc.SetBrush(*wxBLACK_BRUSH); - dc.SetPen(wxPen(*wxBLACK,1,wxSOLID)); - dc.SetLogicalFunction(wxINVERT); -} - -/// Ends highlighting the selection -static -inline void EndHighlighting(wxDC &dc) -{ - dc.SetLogicalFunction(wxCOPY); -} //@} /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * @@ -164,6 +155,7 @@ wxLayoutObjectText::GetSize(CoordType *top, CoordType *bottom) const void wxLayoutObjectText::Draw(wxDC &dc, wxPoint const &coords, + wxLayoutList *wxllist, CoordType begin, CoordType end) { if(begin == -1) @@ -181,12 +173,12 @@ wxLayoutObjectText::Draw(wxDC &dc, wxPoint const &coords, dc.DrawText(str, xpos, ypos); dc.GetTextExtent(str, &width, &height, &descent); xpos += width; - StartHighlighting(dc); + wxllist->StartHighlighting(dc); str = m_Text.Mid(begin, end-begin); dc.DrawText(str, xpos, ypos); dc.GetTextExtent(str, &width, &height, &descent); xpos += width; - dc.SetLogicalFunction(wxCOPY); + wxllist->EndHighlighting(dc); str = m_Text.Mid(end, m_Text.Length()-end); dc.DrawText(str, xpos, ypos); } @@ -218,7 +210,7 @@ wxLayoutObjectText::GetOffsetScreen(wxDC &dc, CoordType xpos) const } void -wxLayoutObjectText::Layout(wxDC &dc) +wxLayoutObjectText::Layout(wxDC &dc, class wxLayoutList * ) { long descent = 0l; @@ -263,17 +255,15 @@ wxLayoutObjectIcon::wxLayoutObjectIcon(wxBitmap *icon) void wxLayoutObjectIcon::Draw(wxDC &dc, wxPoint const &coords, + wxLayoutList *wxllist, CoordType begin, CoordType /* len */) { - if(begin == 0) - StartHighlighting(dc); - dc.DrawBitmap(*m_Icon, coords.x, coords.y-m_Icon->GetHeight(), (m_Icon->GetMask() == NULL) ? FALSE : TRUE); } void -wxLayoutObjectIcon::Layout(wxDC & /* dc */) +wxLayoutObjectIcon::Layout(wxDC & /* dc */, class wxLayoutList * ) { } @@ -289,71 +279,125 @@ wxLayoutObjectIcon::GetSize(CoordType *top, CoordType *bottom) const /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - wxLayoutObjectIcon + wxLayoutObjectCmd * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +wxLayoutStyleInfo::wxLayoutStyleInfo(int ifamily, + int isize, + int istyle, + int iweight, + int iul, + wxColour *fg, + wxColour *bg) +{ + family = ifamily; size = isize; + style = istyle; weight = iweight; + underline = iul; + if(fg) + { + fg_valid = true; + fg_red = fg->Red(); + fg_blue = fg->Blue(); + fg_green = fg->Green(); + } + else + fg_valid = false; + if(bg) + { + bg_valid = true; + bg_red = bg->Red(); + bg_blue = bg->Blue(); + bg_green = bg->Green(); + } + else + bg_valid = false; +} + +#define SET_SI(what) tmp.what = (what != -1) ? what : ( si ? si->what : wxNORMAL); + + +wxFont * +wxLayoutStyleInfo::GetFont(wxLayoutStyleInfo *si) +{ + wxLayoutStyleInfo tmp; + + SET_SI(family); + SET_SI(size); + SET_SI(style); + SET_SI(weight); + SET_SI(underline); + + return new wxFont(tmp.size,tmp.family,tmp.style,tmp.weight,tmp.underline); + +} + wxLayoutObjectCmd::wxLayoutObjectCmd(int size, int family, int style, int - weight, bool underline, - wxColour &fg, wxColour &bg) + weight, int underline, + wxColour *fg, wxColour *bg) { - m_font = new wxFont(size,family,style,weight,underline); - m_ColourFG = fg; - m_ColourBG = bg; + m_StyleInfo = new + wxLayoutStyleInfo(size,family,style,weight,underline,fg,bg); + m_font = m_StyleInfo->GetFont(NULL); } wxLayoutObject * wxLayoutObjectCmd::Copy(void) { - wxLayoutStyleInfo si; - GetStyle(&si); + wxColour + * fg = NULL, + * bg = NULL; + if(m_StyleInfo->fg_valid) + fg = new + wxColour(m_StyleInfo->fg_red,m_StyleInfo->fg_green,m_StyleInfo->fg_blue); + if(m_StyleInfo->bg_valid) + bg = new + wxColour(m_StyleInfo->bg_red,m_StyleInfo->bg_green,m_StyleInfo->bg_blue); wxLayoutObjectCmd *obj = new wxLayoutObjectCmd( - si.size, si.family, si.style, si.weight, si.underline, - m_ColourFG, m_ColourBG); + m_StyleInfo->size, + m_StyleInfo->family, + m_StyleInfo->style, + m_StyleInfo->weight, + m_StyleInfo->underline, + fg, bg); obj->SetUserData(m_UserData); + + if(fg) delete fg; + if(bg) delete bg; return obj; } wxLayoutObjectCmd::~wxLayoutObjectCmd() { + delete m_StyleInfo; delete m_font; } -void -wxLayoutObjectCmd::GetStyle(wxLayoutStyleInfo *si) const +wxLayoutStyleInfo * +wxLayoutObjectCmd::GetStyle(void) const { - si->size = m_font->GetPointSize(); - si->family = m_font->GetFamily(); - si->style = m_font->GetStyle(); - si->underline = m_font->GetUnderlined(); - si->weight = m_font->GetWeight(); - - si->fg_red = m_ColourFG.Red(); - si->fg_green = m_ColourFG.Green(); - si->fg_blue = m_ColourFG.Blue(); - si->bg_red = m_ColourBG.Red(); - si->bg_green = m_ColourBG.Green(); - si->bg_blue = m_ColourBG.Blue(); + return m_StyleInfo; } void wxLayoutObjectCmd::Draw(wxDC &dc, wxPoint const & /* coords */, + wxLayoutList *wxllist, CoordType begin, CoordType /* len */) { - wxASSERT(m_font); + wxASSERT(m_StyleInfo); dc.SetFont(*m_font); - dc.SetTextForeground(m_ColourFG); - dc.SetTextBackground(m_ColourBG); + wxllist->ApplyStyle(m_StyleInfo, dc); } void -wxLayoutObjectCmd::Layout(wxDC &dc) +wxLayoutObjectCmd::Layout(wxDC &dc, class wxLayoutList * llist) { // this get called, so that recalculation uses right font sizes - Draw(dc, wxPoint(0,0)); + Draw(dc, wxPoint(0,0), llist); } @@ -395,9 +439,13 @@ wxLayoutLine::~wxLayoutLine() wxPoint wxLayoutLine::RecalculatePosition(wxLayoutList *llist) { + wxASSERT(m_Previous || GetLineNumber() == 0); + if(m_Previous) - m_Position = m_Previous->GetPosition() + - wxPoint(0,m_Previous->GetHeight()); + { + m_Position = m_Previous->GetPosition(); + m_Position.y += m_Previous->GetHeight(); + } else m_Position = wxPoint(0,0); llist->SetUpdateRect(m_Position); @@ -464,12 +512,12 @@ wxLayoutLine::FindObjectScreen(wxDC &dc, for(i = m_ObjectList.begin(); i != NULLIT; i++) { - (**i).Layout(dc); +//FIXME! (**i).Layout(dc, NULL); width = (**i).GetWidth(); if( x <= xpos && xpos <= x + width ) { *cxpos = cx + (**i).GetOffsetScreen(dc, xpos-x); - wxLogDebug("wxLayoutLine::FindObjectScreen: cursor xpos = %ld", *cxpos); +// WXLO_DEBUG(("wxLayoutLine::FindObjectScreen: cursor xpos = %ld", *cxpos)); if(found) *found = true; return i; } @@ -482,6 +530,38 @@ wxLayoutLine::FindObjectScreen(wxDC &dc, return m_ObjectList.tail(); } +/** Finds text in this line. + @param needle the text to find + @param xpos the position where to start the search + @return the cursoor coord where it was found or -1 +*/ +CoordType +wxLayoutLine::FindText(const wxString &needle, CoordType xpos = 0) const +{ + int + cpos = 0, + relpos = -1; + wxString const *text; + + for(wxLOiterator i = m_ObjectList.begin(); i != m_ObjectList.end(); i++) + { + if(cpos >= xpos) // search from here! + { + if((**i).GetType() == WXLO_TYPE_TEXT) + { + text = & ((wxLayoutObjectText*)(*i))->GetText(); + relpos = text->Find(needle); + if(relpos >= cpos-xpos) // -1 if not found + { + return cpos+relpos; + } + } + cpos += (**i).GetLength(); + } + } + return -1; // not found +} + bool wxLayoutLine::Insert(CoordType xpos, wxLayoutObject *obj) { @@ -686,10 +766,11 @@ wxLayoutLine::Draw(wxDC &dc, CoordType from, to, tempto; int highlight = llist->IsSelected(this, &from, &to); +// WXLO_DEBUG(("highlight=%d", highlight )); if(highlight == 1) // we need to draw the whole line inverted! - StartHighlighting(dc); + llist->StartHighlighting(dc); else - EndHighlighting(dc); + llist->EndHighlighting(dc); for(i = m_ObjectList.begin(); i != NULLIT; i++) { @@ -697,18 +778,23 @@ wxLayoutLine::Draw(wxDC &dc, { // parts of the line need highlighting tempto = xpos+(**i).GetLength(); - if(tempto >= from && tempto <= to) + if(tempto >= from && xpos <= to) { tempto = to-xpos; if(tempto > (**i).GetLength()) tempto = (**i).GetLength(); - (**i).Draw(dc, pos, from-xpos, to); + CoordType tmp = from-xpos; + if(tmp < 0) tmp = 0; + (**i).Draw(dc, pos, llist, from-xpos, tempto); } else - EndHighlighting(dc); + { + llist->EndHighlighting(dc); // FIXME! inefficient + (**i).Draw(dc, pos, llist); + } } else - (**i).Draw(dc, pos); + (**i).Draw(dc, pos, llist); pos.x += (**i).GetWidth(); xpos += (**i).GetLength(); } @@ -746,7 +832,7 @@ wxLayoutLine::Layout(wxDC &dc, for(i = m_ObjectList.begin(); i != NULLIT; i++) { - (**i).Layout(dc); + (**i).Layout(dc, llist); size = (**i).GetSize(&objTopHeight, &objBottomHeight); if(cursorPos && ! cursorFound) @@ -979,15 +1065,79 @@ wxLayoutLine::Debug(void) { wxString tmp; wxPoint pos = GetPosition(); - tmp.Printf("Line %ld, Pos (%ld,%ld), Height %ld", + WXLO_DEBUG(("Line %ld, Pos (%ld,%ld), Height %ld", (long int) GetLineNumber(), (long int) pos.x, (long int) pos.y, - (long int) GetHeight()); - - wxLogDebug(tmp); + (long int) GetHeight())); + if(m_ObjectList.begin() != NULLIT) + (**m_ObjectList.begin()).Debug(); + } #endif +void +wxLayoutLine::Copy(wxLayoutList *llist, + CoordType from, + CoordType to) +{ + CoordType firstOffset, lastOffset; + + if(to == -1) to = GetLength(); + + wxLOiterator first = FindObject(from, &firstOffset); + wxLOiterator last = FindObject(to, &lastOffset); + + // Common special case: only one object + if( *first == *last ) + { + if( (**first).GetType() == WXLO_TYPE_TEXT ) + { + llist->Insert(new wxLayoutObjectText( + ((wxLayoutObjectText + *)*first)->GetText().substr(firstOffset, + lastOffset-firstOffset)) + ); + return; + } + else // what can we do? + { + if(lastOffset > firstOffset) // i.e. +1 :-) + llist->Insert( (**first).Copy() ); + return; + } + } + + // If we reach here, we can safely copy the whole first object from + // the firstOffset position on: + if((**first).GetType() == WXLO_TYPE_TEXT && firstOffset != 0) + { + llist->Insert(new wxLayoutObjectText( + ((wxLayoutObjectText *)*first)->GetText().substr(firstOffset)) + ); + } + else if(firstOffset == 0) + llist->Insert( (**first).Copy() ); + // else nothing to copy :-( + + // Now we copy all objects before the last one: + wxLOiterator i = first; i++; + for( ; i != last; i++) + llist->Insert( (**i).Copy() ); + + // And now the last object: + if(lastOffset != 0) + { + if( (**last).GetType() == WXLO_TYPE_TEXT ) + { + llist->Insert(new wxLayoutObjectText( + ((wxLayoutObjectText *)*last)->GetText().substr(0,lastOffset)) + ); + } + else + llist->Insert( (**last).Copy() ); + } +} + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * The wxLayoutList object @@ -1034,6 +1184,14 @@ wxLayoutList::InternalClear(void) delete m_DefaultSetting; m_DefaultSetting = NULL; } + m_Selection.m_selecting = false; + m_Selection.m_valid = false; + + m_CurrentSetting.family = wxSWISS; + m_CurrentSetting.size = WXLO_DEFAULTFONTSIZE; + m_CurrentSetting.style = wxNORMAL; + m_CurrentSetting.weight = wxNORMAL; + m_CurrentSetting.underline = 0; } void @@ -1046,13 +1204,9 @@ wxLayoutList::SetFont(int family, int size, int style, int weight, if(style != -1) m_FontStyle = style; if(weight != -1) m_FontWeight = weight; if(underline != -1) m_FontUnderline = underline != 0; - - if(fg != NULL) m_ColourFG = *fg; - if(bg != NULL) m_ColourBG = *bg; - Insert( new wxLayoutObjectCmd(m_FontPtSize,m_FontFamily,m_FontStyle,m_FontWeight,m_FontUnderline, - m_ColourFG, m_ColourBG)); + fg, bg)); } void @@ -1069,36 +1223,43 @@ wxLayoutList::SetFont(int family, int size, int style, int weight, if( bg ) cbg = wxTheColourDatabase->FindColour(bg); - SetFont(family,size,style,weight,underline,cfg,cbg); + SetFont(size,family,style,weight,underline,cfg,cbg); } void wxLayoutList::Clear(int family, int size, int style, int weight, - int /* underline */, wxColour *fg, wxColour *bg) + int underline, wxColour *fg, wxColour *bg) { InternalClear(); - // set defaults - m_FontPtSize = size; - m_FontUnderline = false; - m_FontFamily = family; - m_FontStyle = style; - m_FontWeight = weight; - if(fg) m_ColourFG = *fg; - if(bg) m_ColourBG = *bg; - - m_ColourFG = *wxBLACK; - m_ColourBG = *wxWHITE; - if(m_DefaultSetting) delete m_DefaultSetting; - m_DefaultSetting = new - wxLayoutObjectCmd(m_FontPtSize,m_FontFamily,m_FontStyle, - m_FontWeight,m_FontUnderline, - m_ColourFG, m_ColourBG); + m_DefaultSetting = new + wxLayoutStyleInfo(family,size,style,weight,underline,fg,bg); } +wxPoint +wxLayoutList::FindText(const wxString &needle, const wxPoint &cpos) const +{ + int xpos; + + wxLayoutLine *line; + for(line = m_FirstLine; + line; + line = line->GetNextLine()) + { + if(line->GetLineNumber() >= cpos.y) + { + xpos = line->FindText(needle, + (line->GetLineNumber() == cpos.y) ? + cpos.x : 0); + if(xpos != -1) + return wxPoint(xpos, line->GetLineNumber()); + } + } + return wxPoint(-1,-1); +} bool @@ -1230,6 +1391,7 @@ wxLayoutList::Insert(wxString const &text) SetUpdateRect(m_CursorScreenPos+m_CursorSize); m_CursorLine->Insert(m_CursorPos.x, text); m_CursorPos.x += text.Length(); + m_CursorLine->RecalculatePositions(true, this); //FIXME needed? return true; } @@ -1241,6 +1403,7 @@ wxLayoutList::Insert(wxLayoutObject *obj) SetUpdateRect(m_CursorScreenPos+m_CursorSize); m_CursorLine->Insert(m_CursorPos.x, obj); m_CursorPos.x += obj->GetLength(); + m_CursorLine->RecalculatePositions(true, this); //FIXME needed? return true; } @@ -1256,6 +1419,7 @@ wxLayoutList::LineBreak(void) m_FirstLine = m_CursorLine->GetPreviousLine(); m_CursorPos.y++; m_CursorPos.x = 0; + m_CursorLine->RecalculatePositions(true, this); //FIXME needed? return true; } @@ -1277,6 +1441,7 @@ wxLayoutList::WrapLine(CoordType column) LineBreak(); Delete(1); // delete the space m_CursorPos.x = newpos; + m_CursorLine->RecalculatePositions(true, this); //FIXME needed? return true; } } @@ -1318,6 +1483,7 @@ wxLayoutList::Delete(CoordType npos) } } while(left); + m_CursorLine->RecalculatePositions(true, this); //FIXME needed? return left == 0; } @@ -1334,6 +1500,7 @@ wxLayoutList::DeleteLines(int n) { // we cannot delete this line, but we can clear it MoveCursorToBeginOfLine(); DeleteToEndOfLine(); + m_CursorLine->RecalculatePositions(2, this); return n-1; } //else: @@ -1355,7 +1522,7 @@ wxLayoutList::Recalculate(wxDC &dc, CoordType bottom) // first, make sure everything is calculated - this might not be // needed, optimise it later - m_DefaultSetting->Layout(dc); + ApplyStyle(m_DefaultSetting, dc); while(line) { line->RecalculatePosition(this); // so we don't need to do it all the time @@ -1386,7 +1553,7 @@ wxLayoutList::Layout(wxDC &dc, CoordType bottom) // first, make sure everything is calculated - this might not be // needed, optimise it later - m_DefaultSetting->Layout(dc); + ApplyStyle(m_DefaultSetting, dc); while(line) { if(line == m_CursorLine) @@ -1418,7 +1585,7 @@ wxLayoutList::Draw(wxDC &dc, wxLayoutLine *line = m_FirstLine; Layout(dc, bottom); - m_DefaultSetting->Draw(dc, wxPoint(0,0)); + ApplyStyle(m_DefaultSetting, dc); wxBrush brush(m_ColourBG, wxSOLID); dc.SetBrush(brush); @@ -1431,11 +1598,12 @@ wxLayoutList::Draw(wxDC &dc, if(bottom != -1 && line->GetPosition().y > bottom) break; line = line->GetNextLine(); } - // can only be 0 if we are on the first line and have no next line - wxASSERT(m_CursorSize.x != 0 || (m_CursorLine && - m_CursorLine->GetNextLine() == NULL && - m_CursorLine == m_FirstLine)); InvalidateUpdateRect(); + + WXLO_DEBUG(("Selection is %s : l%d,%ld/%ld,%ld", + m_Selection.m_valid ? "valid" : "invalid", + m_Selection.m_CursorA.x, m_Selection.m_CursorA.y, + m_Selection.m_CursorB.x, m_Selection.m_CursorB.y)); } wxLayoutObject * @@ -1448,7 +1616,7 @@ wxLayoutList::FindObjectScreen(wxDC &dc, wxPoint const pos, wxPoint p; // we need to run a layout here to get font sizes right :-( - m_DefaultSetting->Layout(dc); + ApplyStyle(m_DefaultSetting, dc); while(line) { p = line->GetPosition(); @@ -1495,6 +1663,7 @@ wxLayoutList::GetSize(void) const return maxPoint; } + void wxLayoutList::DrawCursor(wxDC &dc, bool active, wxPoint const &translate) { @@ -1516,11 +1685,19 @@ wxLayoutList::DrawCursor(wxDC &dc, bool active, wxPoint const &translate) dc.SetLogicalFunction(wxXOR); dc.SetPen(wxPen(*wxBLACK,1,wxSOLID)); if(active) - dc.DrawRectangle(coords.x, coords.y, m_CursorSize.x, - m_CursorSize.y); + { + dc.DrawRectangle(coords.x, coords.y, + m_CursorSize.x, m_CursorSize.y); + SetUpdateRect(coords.x, coords.y); + SetUpdateRect(coords.x+m_CursorSize.x, coords.y+m_CursorSize.y); + } else + { dc.DrawLine(coords.x, coords.y+m_CursorSize.y-1, - coords.x+m_CursorSize.x, coords.y+m_CursorSize.y-1); + coords.x, coords.y); + SetUpdateRect(coords.x, coords.y+m_CursorSize.y-1); + SetUpdateRect(coords.x, coords.y); + } dc.SetLogicalFunction(wxCOPY); //dc.SetBrush(wxNullBrush); } @@ -1543,20 +1720,20 @@ wxLayoutList::SetUpdateRect(CoordType x, CoordType y) void wxLayoutList::StartSelection(void) { - wxLogDebug("Starting selection at %ld/%ld", m_CursorPos.x, m_CursorPos.y); + WXLO_DEBUG(("Starting selection at %ld/%ld", m_CursorPos.x, m_CursorPos.y)); m_Selection.m_CursorA = m_CursorPos; + m_Selection.m_CursorB = m_CursorPos; m_Selection.m_selecting = true; m_Selection.m_valid = false; } void -wxLayoutList::EndSelection(void) +wxLayoutList::ContinueSelection(void) { - wxLogDebug("Ending selection at %ld/%ld", m_CursorPos.x, m_CursorPos.y); + wxASSERT(m_Selection.m_selecting == true); + wxASSERT(m_Selection.m_valid == false); + WXLO_DEBUG(("Continuing selection at %ld/%ld", m_CursorPos.x, m_CursorPos.y)); m_Selection.m_CursorB = m_CursorPos; - m_Selection.m_selecting = false; - m_Selection.m_valid = true; - // We always want m_CursorA <= m_CursorB! if(! (m_Selection.m_CursorA <= m_Selection.m_CursorB)) { @@ -1566,6 +1743,16 @@ wxLayoutList::EndSelection(void) } } +void +wxLayoutList::EndSelection(void) +{ + ContinueSelection(); + WXLO_DEBUG(("Ending selection at %ld/%ld", m_CursorPos.x, m_CursorPos.y)); + m_Selection.m_selecting = false; + m_Selection.m_valid = true; +} + + bool wxLayoutList::IsSelecting(void) { @@ -1575,6 +1762,8 @@ wxLayoutList::IsSelecting(void) bool wxLayoutList::IsSelected(const wxPoint &cursor) { + if(! m_Selection.m_valid && ! m_Selection.m_selecting) + return false; return m_Selection.m_CursorA <= cursor && cursor <= m_Selection.m_CursorB; } @@ -1592,6 +1781,9 @@ wxLayoutList::IsSelected(const wxLayoutLine *line, CoordType *from, { wxASSERT(line); wxASSERT(to); wxASSERT(from); + if(! m_Selection.m_valid && ! m_Selection.m_selecting) + return 0; + CoordType y = line->GetLineNumber(); if(m_Selection.m_CursorA.y < y && m_Selection.m_CursorB.y > y) return 1; @@ -1617,10 +1809,196 @@ wxLayoutList::IsSelected(const wxLayoutLine *line, CoordType *from, return 0; } +void +wxLayoutList::DeleteSelection(void) +{ + if(! m_Selection.m_valid) + return; + + m_Selection.m_valid = false; + + // Only delete part of the current line? + if(m_Selection.m_CursorA.y == m_Selection.m_CursorB.y) + { + MoveCursorTo(m_Selection.m_CursorA); + Delete(m_Selection.m_CursorB.x - m_Selection.m_CursorA.x); + return; + } + + + wxLayoutLine + * firstLine = NULL, + * lastLine = NULL; + + for(firstLine = m_FirstLine; + firstLine && firstLine->GetLineNumber() < m_Selection.m_CursorA.y; + firstLine=firstLine->GetNextLine()) + ; + if(!firstLine || firstLine->GetLineNumber() != m_Selection.m_CursorA.y) + return; + + + for(lastLine = m_FirstLine; + lastLine && lastLine->GetLineNumber() < m_Selection.m_CursorB.y; + lastLine=lastLine->GetNextLine()) + ; + if(!lastLine || lastLine->GetLineNumber() != m_Selection.m_CursorB.y) + return; + + + // We now know that the two lines are different: + + // First, delete what's left of this line: + MoveCursorTo(m_Selection.m_CursorA); + DeleteToEndOfLine(); + + wxLayoutLine *nextLine = firstLine->GetNextLine(); + while(nextLine && nextLine != lastLine) + nextLine = nextLine->DeleteLine(false, this); + + // Now nextLine = lastLine; + Delete(1); // This joins firstLine and nextLine + Delete(m_Selection.m_CursorB.x); // This deletes the first x + // positions + + /// Recalculate: + firstLine->RecalculatePositions(1, this); +} + +/// Starts highlighting the selection +void +wxLayoutList::StartHighlighting(wxDC &dc) +{ +#if SHOW_SELECTIONS + dc.SetTextForeground(m_ColourBG); + dc.SetTextBackground(m_ColourFG); +#endif +} + +/// Ends highlighting the selection +void +wxLayoutList::EndHighlighting(wxDC &dc) +{ +#if SHOW_SELECTIONS + dc.SetTextForeground(m_ColourFG); + dc.SetTextBackground(m_ColourBG); +#endif +} + + +wxLayoutList * +wxLayoutList::Copy(const wxPoint &from, + const wxPoint &to) +{ + wxLayoutLine + * firstLine = NULL, + * lastLine = NULL; + + for(firstLine = m_FirstLine; + firstLine && firstLine->GetLineNumber() < from.y; + firstLine=firstLine->GetNextLine()) + ; + if(!firstLine || firstLine->GetLineNumber() != from.y) + return NULL; + + for(lastLine = m_FirstLine; + lastLine && lastLine->GetLineNumber() < to.y; + lastLine=lastLine->GetNextLine()) + ; + if(!lastLine || lastLine->GetLineNumber() != to.y) + return NULL; + + if(to <= from) + { + wxLayoutLine *tmp = firstLine; + firstLine = lastLine; + lastLine = tmp; + } + + wxLayoutList *llist = new wxLayoutList(); + + if(firstLine == lastLine) + { + firstLine->Copy(llist, from.x, to.x); + } + else + { + // Extract objects from first line + firstLine->Copy(llist, from.x); + llist->LineBreak(); + // Extract all lines between + for(wxLayoutLine *line = firstLine->GetNextLine(); + line != lastLine; + line = line->GetNextLine()) + { + line->Copy(llist); + llist->LineBreak(); + } + // Extract objects from last line + lastLine->Copy(llist, 0, to.x); + } + return llist; +} + +wxLayoutList * +wxLayoutList::GetSelection(void) +{ + if(! m_Selection.m_valid) + { + if(m_Selection.m_selecting) + EndSelection(); + else + return NULL; + } + + m_Selection.m_valid = false; + return Copy( m_Selection.m_CursorA, m_Selection.m_CursorB ); +} + + + +#define COPY_SI(what) if(si->what != -1) m_CurrentSetting.what = si->what; + +void +wxLayoutList::ApplyStyle(wxLayoutStyleInfo *si, wxDC &dc) +{ + COPY_SI(family); + COPY_SI(size); + COPY_SI(style); + COPY_SI(weight); + COPY_SI(underline); + + + if(si->fg_valid) + { + m_CurrentSetting.fg_valid = true; + m_CurrentSetting.fg_red = si->fg_red; + m_CurrentSetting.fg_green = si->fg_green; + m_CurrentSetting.fg_blue = si->fg_blue; + } + if(si->bg_valid) + { + m_CurrentSetting.bg_valid = true; + m_CurrentSetting.bg_red = si->bg_red; + m_CurrentSetting.bg_green = si->bg_green; + m_CurrentSetting.bg_blue = si->bg_blue; + } + + m_ColourFG = wxColour(m_CurrentSetting.fg_red, + m_CurrentSetting.fg_green, + m_CurrentSetting.fg_blue); + m_ColourBG = wxColour(m_CurrentSetting.bg_red, + m_CurrentSetting.bg_green, + m_CurrentSetting.bg_blue); + dc.SetTextForeground(m_ColourFG); + dc.SetTextBackground(m_ColourBG); +} + + #ifdef WXLAYOUT_DEBUG void -wxLayoutList::Debug(void) +wxLayoutList::Debug(void) { wxLayoutLine *line;