]> git.saurik.com Git - wxWidgets.git/commitdiff
subcell selection
authorVáclav Slavík <vslavik@fastmail.fm>
Tue, 3 Jun 2003 13:48:59 +0000 (13:48 +0000)
committerVáclav Slavík <vslavik@fastmail.fm>
Tue, 3 Jun 2003 13:48:59 +0000 (13:48 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@20889 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

src/html/htmlcell.cpp
src/html/htmlwin.cpp

index 1e86ed4112da287db7ac714a95471b7e86797457..a57c6320d9b259755983b27a1bed09d2f71659a3 100644 (file)
@@ -233,13 +233,66 @@ wxHtmlWordCell::wxHtmlWordCell(const wxString& word, wxDC& dc) : wxHtmlCell()
 }
 
 
+// Splits m_Word into up to three parts according to selection, returns
+// substring before, in and after selection and the points (in relative coords)
+// where s2 and s3 start:
+void wxHtmlWordCell::Split(wxDC& dc, 
+                           const wxPoint& selFrom, const wxPoint& selTo,
+                           wxString& s1, wxString& s2, wxString& s3,
+                           unsigned& pos1, unsigned& pos2)
+{
+    wxPoint pt1 = (selFrom == wxDefaultPosition) ?
+                   wxDefaultPosition : selFrom - GetAbsPos();
+    wxPoint pt2 = (selTo == wxDefaultPosition) ?
+                   wxPoint(m_Width, -1) : selTo - GetAbsPos();
+
+    wxCoord charW, charH;
+    unsigned len = m_Word.length();
+    unsigned i = 0;
+    pos1 = 0;
+    s1 = s2 = s3 = wxEmptyString;
+
+    // before selection:
+    while ( pt1.x > 0 && i < len )
+    {
+        dc.GetTextExtent(m_Word[i], &charW, &charH);
+        pt1.x -= charW;
+        if ( pt1.x >= 0 )
+        {
+            pos1 += charW;
+            i++;
+        }
+    }
 
-void wxHtmlWordCell::Draw(wxDC& dc, int x, int y,
-                          int WXUNUSED(view_y1), int WXUNUSED(view_y2),
-                          wxHtmlRenderingState& state)
+    // in selection:
+    unsigned j = i;
+    pos2 = pos1;
+        pt2.x -= pos2;
+    while ( pt2.x > 0 && j < len )
+    {
+        dc.GetTextExtent(m_Word[j], &charW, &charH);
+        pt2.x -= charW;
+        if ( pt2.x >= 0 )
+        {
+            pos2 += charW;
+            j++;
+        }
+    }
+    
+    s1 = m_Word.Mid(0, i);
+    s2 = m_Word.Mid(i, j-i);
+    s3 = m_Word.Mid(j);
+#if 0 // FIXME
+    printf("  '%s' %i '%s' %i '%s'\n", s1.mb_str(), pos1,
+            s2.mb_str(), pos2,s3.mb_str());
+#endif
+}
+
+
+static void SwitchSelState(wxDC& dc, wxHtmlRenderingState& state,
+                           bool toSelection)
 {
-    if (state.GetSelectionState() != wxHTML_SEL_OUT &&
-        dc.GetBackgroundMode() != wxSOLID)
+    if ( toSelection )
     {
         dc.SetBackgroundMode(wxSOLID);
         dc.SetTextBackground(
@@ -247,16 +300,67 @@ void wxHtmlWordCell::Draw(wxDC& dc, int x, int y,
         dc.SetTextForeground(
                 wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT));
     }
-    else if (state.GetSelectionState() == wxHTML_SEL_OUT &&
-             dc.GetBackgroundMode() == wxSOLID)
+    else
     {
         dc.SetBackgroundMode(wxTRANSPARENT);
         dc.SetTextForeground(state.GetFgColour());
         dc.SetTextBackground(state.GetBgColour());
     }
+}
 
-    // FIXME - use selection
-    dc.DrawText(m_Word, x + m_PosX, y + m_PosY);
+
+void wxHtmlWordCell::Draw(wxDC& dc, int x, int y,
+                          int WXUNUSED(view_y1), int WXUNUSED(view_y2),
+                          wxHtmlRenderingState& state)
+{
+#if 0 // useful for debugging
+    dc.DrawRectangle(x+m_PosX,y+m_PosY,m_Width,m_Height);
+#endif
+
+    if ( state.GetSelectionState() == wxHTML_SEL_CHANGING )
+    {
+        // Selection changing, we must draw the word piecewise:
+    
+        unsigned ofs1, ofs2;
+        wxString textBefore, textInside, textAfter;
+        wxHtmlSelection *s = state.GetSelection();
+        
+        Split(dc, 
+              this == s->GetFromCell() ? s->GetFromPos() : wxDefaultPosition,
+              this == s->GetToCell() ? s->GetToPos() : wxDefaultPosition,
+              textBefore, textInside, textAfter, ofs1, ofs2);
+        dc.DrawText(textBefore, x + m_PosX, y + m_PosY);
+        int w1,w2,w3,h123;
+        dc.GetTextExtent(textBefore, &w1,&h123);
+        dc.GetTextExtent(textInside, &w2,&h123);
+        dc.GetTextExtent(textAfter, &w3,&h123);
+        if ( !textInside.empty() )
+        {
+            SwitchSelState(dc, state, true);
+            dc.DrawText(textInside, x + m_PosX + ofs1, y + m_PosY);
+        }
+        if ( !textAfter.empty() )
+        {
+            SwitchSelState(dc, state, false);
+            dc.DrawText(textAfter, x + m_PosX + ofs2, y + m_PosY);
+        }
+    }
+    else
+    {
+        // Not changing selection state, draw the word in single mode:
+
+        if ( state.GetSelectionState() != wxHTML_SEL_OUT &&
+             dc.GetBackgroundMode() != wxSOLID )
+        {
+            SwitchSelState(dc, state, true);
+        }
+        else if ( state.GetSelectionState() == wxHTML_SEL_OUT &&
+                  dc.GetBackgroundMode() == wxSOLID )
+        {
+            SwitchSelState(dc, state, false);
+        }
+        dc.DrawText(m_Word, x + m_PosX, y + m_PosY);
+    }
 }
     
 
index bf886c6bd4d08d8f9a5a4ef8804aa23113438888..3b227b2325645358fc93aee5a54ecb9a86aa9bf5 100644 (file)
@@ -814,15 +814,17 @@ void wxHtmlWindow::OnIdle(wxIdleEvent& WXUNUSED(event))
             {
                 if (goingDown)
                 {
-                    m_tmpSelFromCell = m_Cell->FindCellByPos(x, y,
-                                                 wxHTML_FIND_NEAREST_AFTER);
+                    m_tmpSelFromCell = m_Cell->FindCellByPos(
+                                         m_tmpSelFromPos.x,m_tmpSelFromPos.y,
+                                         wxHTML_FIND_NEAREST_AFTER);
                     if (!m_tmpSelFromCell)
                         m_tmpSelFromCell = m_Cell->GetFirstTerminal();
                 }
                 else
                 {
-                    m_tmpSelFromCell = m_Cell->FindCellByPos(x, y,
-                                                 wxHTML_FIND_NEAREST_BEFORE);
+                    m_tmpSelFromCell = m_Cell->FindCellByPos(
+                                         m_tmpSelFromPos.x,m_tmpSelFromPos.y,
+                                         wxHTML_FIND_NEAREST_BEFORE);
                     if (!m_tmpSelFromCell)
                         m_tmpSelFromCell = m_Cell->GetLastTerminal();
                 }