Home | History | Annotate | Download | only in pdfwindow
      1 // Copyright 2014 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "fpdfsdk/include/pdfwindow/PWL_ListCtrl.h"
      8 #include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"
      9 
     10 CPWL_ListCtrl::CPWL_ListCtrl()
     11     : m_rcContent(0, 0, 0, 0),
     12       m_ptScroll(0, 0),
     13       m_fItemSpace(0.0f),
     14       m_fTopSpace(0.0f),
     15       m_fBottomSpace(0.0f) {}
     16 
     17 CPWL_ListCtrl::~CPWL_ListCtrl() {}
     18 
     19 void CPWL_ListCtrl::SetScrollPos(const CPDF_Point& point) {
     20   m_ptScroll = point;
     21 
     22   if (m_ptScroll.x < m_rcContent.left)
     23     m_ptScroll.x = m_rcContent.left;
     24 
     25   if (m_ptScroll.x > m_rcContent.right)
     26     m_ptScroll.x = m_rcContent.right;
     27 
     28   if (m_ptScroll.y > m_rcContent.top)
     29     m_ptScroll.y = m_rcContent.top;
     30 
     31   if (m_ptScroll.y < m_rcContent.bottom)
     32     m_ptScroll.y = m_rcContent.bottom;
     33 }
     34 
     35 CPDF_Point CPWL_ListCtrl::GetScrollPos() const {
     36   return m_ptScroll;
     37 }
     38 
     39 CPDF_Rect CPWL_ListCtrl::GetScrollArea() const {
     40   return m_rcContent;
     41 }
     42 
     43 void CPWL_ListCtrl::ResetFace() {
     44   ResetAll(FALSE, 0);
     45 }
     46 
     47 void CPWL_ListCtrl::ResetContent(int32_t nStart) {
     48   if (nStart < 0)
     49     nStart = 0;
     50   if (nStart >= 0 && nStart < m_aChildren.GetSize())
     51     ResetAll(TRUE, nStart);
     52 }
     53 
     54 FX_FLOAT CPWL_ListCtrl::GetContentsHeight(FX_FLOAT fLimitWidth) {
     55   FX_FLOAT fRet = m_fTopSpace;
     56 
     57   FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
     58 
     59   if (fLimitWidth > fBorderWidth * 2) {
     60     for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
     61       if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
     62         FX_FLOAT fLeft = pChild->GetItemLeftMargin();
     63         FX_FLOAT fRight = pChild->GetItemRightMargin();
     64 
     65         fRet += pChild->GetItemHeight(fLimitWidth - fBorderWidth * 2 - fLeft -
     66                                       fRight);
     67         fRet += m_fItemSpace;
     68       }
     69     }
     70 
     71     fRet -= m_fItemSpace;
     72   }
     73 
     74   fRet += m_fBottomSpace;
     75 
     76   return fRet;
     77 }
     78 
     79 void CPWL_ListCtrl::ResetAll(FX_BOOL bMove, int32_t nStart) {
     80   CPDF_Rect rcClient = GetClientRect();
     81 
     82   FX_FLOAT fWidth = rcClient.Width();
     83 
     84   FX_FLOAT fy = 0.0f - m_fTopSpace;
     85 
     86   if (nStart - 1 >= 0 && nStart - 1 < m_aChildren.GetSize())
     87     if (CPWL_Wnd* pChild = m_aChildren.GetAt(nStart - 1))
     88       fy = pChild->GetWindowRect().bottom - m_fItemSpace;
     89 
     90   for (int32_t i = nStart, sz = m_aChildren.GetSize(); i < sz; i++) {
     91     if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
     92       FX_FLOAT fLeft = pChild->GetItemLeftMargin();
     93       FX_FLOAT fRight = pChild->GetItemRightMargin();
     94 
     95       pChild->SetChildMatrix(CFX_Matrix(1, 0, 0, 1,
     96                                         rcClient.left - m_ptScroll.x,
     97                                         rcClient.top - m_ptScroll.y));
     98 
     99       if (bMove) {
    100         FX_FLOAT fItemHeight = pChild->GetItemHeight(fWidth - fLeft - fRight);
    101         pChild->Move(CPDF_Rect(fLeft, fy - fItemHeight, fWidth - fRight, fy),
    102                      TRUE, FALSE);
    103         fy -= fItemHeight;
    104         fy -= m_fItemSpace;
    105       }
    106     }
    107   }
    108 
    109   fy += m_fItemSpace;
    110 
    111   fy -= m_fBottomSpace;
    112 
    113   if (bMove) {
    114     m_rcContent.left = 0;
    115     m_rcContent.top = 0;
    116     m_rcContent.right = fWidth;
    117     m_rcContent.bottom = fy;
    118   }
    119 }
    120 
    121 void CPWL_ListCtrl::SetItemSpace(FX_FLOAT fSpace) {
    122   m_fItemSpace = fSpace;
    123 }
    124 
    125 void CPWL_ListCtrl::SetTopSpace(FX_FLOAT fSpace) {
    126   m_fTopSpace = fSpace;
    127 }
    128 
    129 void CPWL_ListCtrl::SetBottomSpace(FX_FLOAT fSpace) {
    130   m_fBottomSpace = fSpace;
    131 }
    132 
    133 void CPWL_ListCtrl::RePosChildWnd() {
    134   ResetFace();
    135 }
    136 
    137 void CPWL_ListCtrl::DrawChildAppearance(CFX_RenderDevice* pDevice,
    138                                         CFX_Matrix* pUser2Device) {
    139   pDevice->SaveState();
    140   CPDF_Rect rcClient = GetClientRect();
    141   CPDF_Rect rcTemp = rcClient;
    142   pUser2Device->TransformRect(rcTemp);
    143   FX_RECT rcClip((int32_t)rcTemp.left, (int32_t)rcTemp.bottom,
    144                  (int32_t)rcTemp.right, (int32_t)rcTemp.top);
    145 
    146   pDevice->SetClip_Rect(&rcClip);
    147 
    148   for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
    149     if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) {
    150       CPDF_Rect rcChild = pChild->ChildToParent(pChild->GetWindowRect());
    151       if (!(rcChild.top < rcClient.bottom || rcChild.bottom > rcClient.top)) {
    152         CFX_Matrix mt = pChild->GetChildMatrix();
    153         if (mt.IsIdentity()) {
    154           pChild->DrawAppearance(pDevice, pUser2Device);
    155         } else {
    156           mt.Concat(*pUser2Device);
    157           pChild->DrawAppearance(pDevice, &mt);
    158         }
    159       }
    160     }
    161   }
    162 
    163   pDevice->RestoreState();
    164 }
    165 
    166 int32_t CPWL_ListCtrl::GetItemIndex(CPWL_Wnd* pItem) {
    167   for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) {
    168     if (pItem == m_aChildren.GetAt(i))
    169       return i;
    170   }
    171 
    172   return -1;
    173 }
    174 
    175 CPDF_Point CPWL_ListCtrl::InToOut(const CPDF_Point& point) const {
    176   CPDF_Rect rcClient = GetClientRect();
    177 
    178   return CPDF_Point(point.x + rcClient.left - m_ptScroll.x,
    179                     point.y + rcClient.top - m_ptScroll.y);
    180 }
    181 
    182 CPDF_Point CPWL_ListCtrl::OutToIn(const CPDF_Point& point) const {
    183   CPDF_Rect rcClient = GetClientRect();
    184 
    185   return CPDF_Point(point.x - rcClient.left + m_ptScroll.x,
    186                     point.y - rcClient.top + m_ptScroll.y);
    187 }
    188 
    189 CPDF_Rect CPWL_ListCtrl::InToOut(const CPDF_Rect& rect) const {
    190   CPDF_Rect rcClient = GetClientRect();
    191 
    192   return CPDF_Rect(rect.left + rcClient.left - m_ptScroll.x,
    193                    rect.bottom + rcClient.top - m_ptScroll.y,
    194                    rect.right + rcClient.left - m_ptScroll.x,
    195                    rect.top + rcClient.top - m_ptScroll.y);
    196 }
    197 
    198 CPDF_Rect CPWL_ListCtrl::OutToIn(const CPDF_Rect& rect) const {
    199   CPDF_Rect rcClient = GetClientRect();
    200 
    201   return CPDF_Rect(rect.left - rcClient.left + m_ptScroll.x,
    202                    rect.bottom - rcClient.top + m_ptScroll.y,
    203                    rect.right - rcClient.left + m_ptScroll.x,
    204                    rect.top - rcClient.top + m_ptScroll.y);
    205 }
    206