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 "../../include/pdfwindow/PDFWindow.h"
      8 #include "../../include/pdfwindow/PWL_Wnd.h"
      9 #include "../../include/pdfwindow/PWL_ListCtrl.h"
     10 #include "../../include/pdfwindow/PWL_IconList.h"
     11 #include "../../include/pdfwindow/PWL_Utils.h"
     12 #include "../../include/pdfwindow/PWL_ScrollBar.h"
     13 #include "../../include/pdfwindow/PWL_Label.h"
     14 
     15 #define PWL_IconList_ITEM_ICON_LEFTMARGIN		10.0f
     16 #define PWL_IconList_ITEM_WIDTH					20.0f
     17 #define PWL_IconList_ITEM_HEIGHT				20.0f
     18 #define PWL_IconList_ITEM_SPACE					4.0f
     19 
     20 /* ------------------ CPWL_IconList_Item ------------------- */
     21 
     22 CPWL_IconList_Item::CPWL_IconList_Item() :
     23 	m_nIconIndex(-1),
     24 	m_pData(NULL),
     25 	m_bSelected(FALSE),
     26 	m_pText(NULL)
     27 {
     28 }
     29 
     30 CPWL_IconList_Item::~CPWL_IconList_Item()
     31 {
     32 }
     33 
     34 CFX_ByteString CPWL_IconList_Item::GetClassName() const
     35 {
     36 	return "CPWL_IconList_Item";
     37 }
     38 
     39 FX_FLOAT CPWL_IconList_Item::GetItemHeight(FX_FLOAT fLimitWidth)
     40 {
     41 	return PWL_IconList_ITEM_HEIGHT;
     42 }
     43 
     44 void CPWL_IconList_Item::DrawThisAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device)
     45 {
     46 	CPDF_Rect rcClient = GetClientRect();
     47 
     48 	if (m_bSelected)
     49 	{
     50 		if (this->IsEnabled())
     51 		{
     52 			CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcClient,
     53 				CPWL_Utils::PWLColorToFXColor(PWL_DEFAULT_SELBACKCOLOR,this->GetTransparency()));
     54 		}
     55 		else
     56 		{
     57 			CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcClient,
     58 				CPWL_Utils::PWLColorToFXColor(PWL_DEFAULT_LIGHTGRAYCOLOR,this->GetTransparency()));
     59 		}
     60 	}
     61 
     62 	CPDF_Rect rcIcon = rcClient;
     63 	rcIcon.left += PWL_IconList_ITEM_ICON_LEFTMARGIN;
     64 	rcIcon.right = rcIcon.left + PWL_IconList_ITEM_WIDTH;
     65 
     66 	CPWL_Utils::DrawIconAppStream(pDevice, pUser2Device, m_nIconIndex, rcIcon,
     67 		m_crIcon, m_pText->GetTextColor(), this->GetTransparency());
     68 }
     69 
     70 void CPWL_IconList_Item::SetSelect(FX_BOOL bSelected)
     71 {
     72 	m_bSelected = bSelected;
     73 
     74 	if (bSelected)
     75 		m_pText->SetTextColor(PWL_DEFAULT_WHITECOLOR);
     76 	else
     77 		m_pText->SetTextColor(PWL_DEFAULT_BLACKCOLOR);
     78 
     79 }
     80 
     81 FX_BOOL	CPWL_IconList_Item::IsSelected() const
     82 {
     83 	return m_bSelected;
     84 }
     85 
     86 void CPWL_IconList_Item::CreateChildWnd(const PWL_CREATEPARAM & cp)
     87 {
     88 	m_pText = new CPWL_Label;
     89 
     90 	PWL_CREATEPARAM lcp = cp;
     91 	lcp.pParentWnd = this;
     92 	lcp.dwFlags = PWS_CHILD | PWS_VISIBLE | PES_LEFT | PES_CENTER;
     93 	lcp.sTextColor = PWL_DEFAULT_BLACKCOLOR;
     94 	lcp.fFontSize = 12;
     95 	m_pText->Create(lcp);
     96 }
     97 
     98 void CPWL_IconList_Item::SetData(void* pData)
     99 {
    100 	m_pData = pData;
    101 }
    102 
    103 void CPWL_IconList_Item::SetIcon(FX_INT32 nIconIndex)
    104 {
    105 	m_nIconIndex = nIconIndex;
    106 }
    107 
    108 void CPWL_IconList_Item::SetText(const CFX_WideString& str)
    109 {
    110 	m_pText->SetText(str);
    111 }
    112 
    113 CFX_WideString CPWL_IconList_Item::GetText() const
    114 {
    115 	return m_pText->GetText();
    116 }
    117 
    118 void CPWL_IconList_Item::RePosChildWnd()
    119 {
    120 	CPDF_Rect rcClient = GetClientRect();
    121 
    122 	rcClient.left += (PWL_IconList_ITEM_ICON_LEFTMARGIN + PWL_IconList_ITEM_WIDTH + PWL_IconList_ITEM_ICON_LEFTMARGIN);
    123 
    124 	m_pText->Move(rcClient, TRUE, FALSE);
    125 }
    126 
    127 void CPWL_IconList_Item::SetIconFillColor(const CPWL_Color& color)
    128 {
    129 	m_crIcon = color;
    130 }
    131 
    132 void CPWL_IconList_Item::OnEnabled()
    133 {
    134 	if (m_bSelected)
    135 		m_pText->SetTextColor(PWL_DEFAULT_WHITECOLOR);
    136 	else
    137 		m_pText->SetTextColor(PWL_DEFAULT_BLACKCOLOR);
    138 
    139 	this->InvalidateRect();
    140 }
    141 
    142 void CPWL_IconList_Item::OnDisabled()
    143 {
    144 	m_pText->SetTextColor(PWL_DEFAULT_HEAVYGRAYCOLOR);
    145 
    146 	this->InvalidateRect();
    147 }
    148 
    149 /* ----------------- CPWL_IconList_Content ----------------- */
    150 
    151 CPWL_IconList_Content::CPWL_IconList_Content(FX_INT32 nListCount) :
    152 	m_nSelectIndex(-1),
    153 	m_pNotify(NULL),
    154 	m_bEnableNotify(TRUE),
    155 	m_bMouseDown(FALSE),
    156 	m_nListCount(nListCount)
    157 {
    158 }
    159 
    160 CPWL_IconList_Content::~CPWL_IconList_Content()
    161 {
    162 }
    163 
    164 void CPWL_IconList_Content::CreateChildWnd(const PWL_CREATEPARAM & cp)
    165 {
    166 	for (FX_INT32 i=0; i<m_nListCount; i++)
    167 	{
    168 		CPWL_IconList_Item* pNewItem = new CPWL_IconList_Item();
    169 
    170 		PWL_CREATEPARAM icp = cp;
    171 		icp.pParentWnd = this;
    172 		icp.dwFlags = PWS_CHILD | PWS_VISIBLE | PWS_NOREFRESHCLIP;
    173 		pNewItem->Create(icp);
    174 	}
    175 
    176 	this->SetItemSpace(PWL_IconList_ITEM_SPACE);
    177 	this->ResetContent(0);
    178 
    179 	if (CPWL_Wnd * pParent = this->GetParentWindow())
    180 	{
    181 		CPDF_Rect rcScroll = this->GetScrollArea();
    182 		this->GetScrollPos();
    183 
    184 		PWL_SCROLL_INFO sInfo;
    185 		sInfo.fContentMin = rcScroll.bottom;
    186 		sInfo.fContentMax = rcScroll.top;
    187 		sInfo.fPlateWidth = GetClientRect().Height();
    188 		sInfo.fSmallStep = 13.0f;
    189 		sInfo.fBigStep = sInfo.fPlateWidth;
    190 
    191 		pParent->OnNotify(this, PNM_SETSCROLLINFO, SBT_VSCROLL, (FX_INTPTR)&sInfo);
    192 	}
    193 }
    194 
    195 FX_BOOL	CPWL_IconList_Content::OnLButtonDown(const CPDF_Point & point)
    196 {
    197 	SetFocus();
    198 
    199 	SetCapture();
    200 	m_bMouseDown = TRUE;
    201 
    202 	FX_INT32 nItemIndex = FindItemIndex(point);
    203 	SetSelect(nItemIndex);
    204 	ScrollToItem(nItemIndex);
    205 
    206 	return TRUE;
    207 }
    208 
    209 FX_BOOL	CPWL_IconList_Content::OnLButtonUp(const CPDF_Point & point)
    210 {
    211 	m_bMouseDown = FALSE;
    212 	ReleaseCapture();
    213 
    214 	return TRUE;
    215 }
    216 
    217 FX_BOOL CPWL_IconList_Content::OnMouseMove(const CPDF_Point & point)
    218 {
    219 	if (m_bMouseDown)
    220 	{
    221 		FX_INT32 nItemIndex = FindItemIndex(point);
    222 		SetSelect(nItemIndex);
    223 		ScrollToItem(nItemIndex);
    224 	}
    225 
    226 	return TRUE;
    227 }
    228 
    229 FX_BOOL	CPWL_IconList_Content::OnKeyDown(FX_WORD nChar)
    230 {
    231 	switch (nChar)
    232 	{
    233 	case FWL_VKEY_Up:
    234 		if (m_nSelectIndex > 0)
    235 		{
    236 			FX_INT32 nItemIndex = m_nSelectIndex - 1;
    237 			SetSelect(nItemIndex);
    238 			ScrollToItem(nItemIndex);
    239 		}
    240 		return TRUE;
    241 	case FWL_VKEY_Down:
    242 		if (m_nSelectIndex < m_nListCount-1)
    243 		{
    244 			FX_INT32 nItemIndex = m_nSelectIndex + 1;
    245 			SetSelect(nItemIndex);
    246 			ScrollToItem(nItemIndex);
    247 		}
    248 		return TRUE;
    249 	}
    250 
    251 	return FALSE;
    252 }
    253 
    254 FX_INT32 CPWL_IconList_Content::FindItemIndex(const CPDF_Point& point)
    255 {
    256 	FX_INT32 nIndex = 0;
    257 	for (FX_INT32 i=0,sz=m_aChildren.GetSize(); i<sz; i++)
    258 	{
    259 		if (CPWL_Wnd * pChild = m_aChildren.GetAt(i))
    260 		{
    261 			CPDF_Rect rcWnd = pChild->ChildToParent(pChild->GetWindowRect());
    262 
    263 			if (point.y < rcWnd.top)
    264 			{
    265 				nIndex = i;
    266 			}
    267 		}
    268 	}
    269 
    270 	return nIndex;
    271 }
    272 
    273 void CPWL_IconList_Content::ScrollToItem(FX_INT32 nItemIndex)
    274 {
    275 	CPDF_Rect rcClient = GetClientRect();
    276 
    277 	if (CPWL_IconList_Item* pItem = GetListItem(nItemIndex))
    278 	{
    279 		CPDF_Rect rcOrigin = pItem->GetWindowRect();
    280 		CPDF_Rect rcWnd = pItem->ChildToParent(rcOrigin);
    281 
    282 		if (!(rcWnd.bottom > rcClient.bottom && rcWnd.top < rcClient.top))
    283 		{
    284 			CPDF_Point ptScroll = GetScrollPos();
    285 
    286 			if (rcWnd.top > rcClient.top)
    287 			{
    288 				ptScroll.y = rcOrigin.top;
    289 			}
    290 			else if (rcWnd.bottom < rcClient.bottom)
    291 			{
    292 				ptScroll.y = rcOrigin.bottom + rcClient.Height();
    293 			}
    294 
    295 			this->SetScrollPos(ptScroll);
    296 			this->ResetFace();
    297 			this->InvalidateRect();
    298 			if (CPWL_Wnd* pParent = this->GetParentWindow())
    299 			{
    300 				pParent->OnNotify(this, PNM_SETSCROLLPOS, SBT_VSCROLL, (FX_INTPTR)&ptScroll.y);
    301 			}
    302 		}
    303 	}
    304 }
    305 
    306 void CPWL_IconList_Content::SetSelect(FX_INT32 nIndex)
    307 {
    308 	if (m_nSelectIndex != nIndex)
    309 	{
    310 		SelectItem(m_nSelectIndex, FALSE);
    311 		SelectItem(nIndex, TRUE);
    312 		m_nSelectIndex = nIndex;
    313 
    314 		if (IPWL_IconList_Notify* pNotify = GetNotify())
    315 			pNotify->OnNoteListSelChanged(nIndex);
    316 	}
    317 }
    318 
    319 FX_INT32 CPWL_IconList_Content::GetSelect() const
    320 {
    321 	return m_nSelectIndex;
    322 }
    323 
    324 IPWL_IconList_Notify* CPWL_IconList_Content::GetNotify() const
    325 {
    326 	if (m_bEnableNotify)
    327 		return m_pNotify;
    328 	return NULL;
    329 }
    330 
    331 void CPWL_IconList_Content::SetNotify(IPWL_IconList_Notify* pNotify)
    332 {
    333 	m_pNotify = pNotify;
    334 }
    335 
    336 void CPWL_IconList_Content::EnableNotify(FX_BOOL bNotify)
    337 {
    338 	m_bEnableNotify = bNotify;
    339 }
    340 
    341 void CPWL_IconList_Content::SelectItem(FX_INT32 nItemIndex, FX_BOOL bSelect)
    342 {
    343 	if (CPWL_IconList_Item* pItem = GetListItem(nItemIndex))
    344 	{
    345 		pItem->SetSelect(bSelect);
    346 		pItem->InvalidateRect();
    347 	}
    348 }
    349 
    350 CPWL_IconList_Item* CPWL_IconList_Content::GetListItem(FX_INT32 nItemIndex) const
    351 {
    352 	if (nItemIndex >= 0 && nItemIndex<m_aChildren.GetSize())
    353 	{
    354 		if (CPWL_Wnd * pChild = m_aChildren.GetAt(nItemIndex))
    355 		{
    356 			if (pChild->GetClassName() == "CPWL_IconList_Item")
    357 			{
    358 				return (CPWL_IconList_Item*)pChild;
    359 			}
    360 		}
    361 	}
    362 
    363 	return NULL;
    364 }
    365 
    366 void CPWL_IconList_Content::SetListData(FX_INT32 nItemIndex, void* pData)
    367 {
    368 	if (CPWL_IconList_Item* pItem = GetListItem(nItemIndex))
    369 		pItem->SetData(pData);
    370 }
    371 
    372 void CPWL_IconList_Content::SetListIcon(FX_INT32 nItemIndex, FX_INT32 nIconIndex)
    373 {
    374 	if (CPWL_IconList_Item* pItem = GetListItem(nItemIndex))
    375 		pItem->SetIcon(nIconIndex);
    376 }
    377 
    378 void CPWL_IconList_Content::SetListString(FX_INT32 nItemIndex, const CFX_WideString& str)
    379 {
    380 	if (CPWL_IconList_Item* pItem = GetListItem(nItemIndex))
    381 		pItem->SetText(str);
    382 }
    383 
    384 CFX_WideString CPWL_IconList_Content::GetListString(FX_INT32 nItemIndex) const
    385 {
    386 	if (CPWL_IconList_Item* pItem = GetListItem(nItemIndex))
    387 		return pItem->GetText();
    388 
    389 	return L"";
    390 }
    391 
    392 void CPWL_IconList_Content::SetIconFillColor(const CPWL_Color& color)
    393 {
    394 	for (FX_INT32 i=0,sz=m_aChildren.GetSize(); i<sz; i++)
    395 	{
    396 		if (CPWL_Wnd * pChild = m_aChildren.GetAt(i))
    397 		{
    398 			if (pChild->GetClassName() == "CPWL_IconList_Item")
    399 			{
    400 				CPWL_IconList_Item* pItem = (CPWL_IconList_Item*)pChild;
    401 				pItem->SetIconFillColor(color);
    402 				pItem->InvalidateRect();
    403 			}
    404 		}
    405 	}
    406 
    407 }
    408 
    409 /* -------------------- CPWL_IconList --------------------- */
    410 
    411 CPWL_IconList::CPWL_IconList(FX_INT32 nListCount) :
    412 	m_pListContent(NULL),
    413 	m_nListCount(nListCount)
    414 {
    415 }
    416 
    417 CPWL_IconList::~CPWL_IconList()
    418 {
    419 }
    420 
    421 void CPWL_IconList::RePosChildWnd()
    422 {
    423 	CPWL_Wnd::RePosChildWnd();
    424 
    425 	if (m_pListContent)
    426 		m_pListContent->Move(GetClientRect(), TRUE, FALSE);
    427 }
    428 
    429 void CPWL_IconList::CreateChildWnd(const PWL_CREATEPARAM & cp)
    430 {
    431 	m_pListContent = new CPWL_IconList_Content(m_nListCount);
    432 
    433 	PWL_CREATEPARAM ccp = cp;
    434 	ccp.pParentWnd = this;
    435 	ccp.dwFlags = PWS_CHILD | PWS_VISIBLE;
    436 	m_pListContent->Create(ccp);
    437 }
    438 
    439 void CPWL_IconList::OnCreated()
    440 {
    441 	if (CPWL_ScrollBar* pScrollBar = this->GetVScrollBar())
    442 	{
    443 		pScrollBar->RemoveFlag(PWS_AUTOTRANSPARENT);
    444 		pScrollBar->SetTransparency(255);
    445 		pScrollBar->SetNotifyForever(TRUE);
    446 	}
    447 }
    448 
    449 void CPWL_IconList::OnNotify(CPWL_Wnd* pWnd, FX_DWORD msg, FX_INTPTR wParam, FX_INTPTR lParam)
    450 {
    451 	CPWL_Wnd::OnNotify(pWnd, msg, wParam, lParam);
    452 
    453 	if (wParam == SBT_VSCROLL)
    454 	{
    455 		switch (msg)
    456 		{
    457 		case PNM_SETSCROLLINFO:
    458 			if (PWL_SCROLL_INFO* pInfo = (PWL_SCROLL_INFO*)lParam)
    459 			{
    460 				if (CPWL_ScrollBar* pScrollBar = this->GetVScrollBar())
    461 				{
    462 					if (pInfo->fContentMax - pInfo->fContentMin > pInfo->fPlateWidth)
    463 					{
    464 						if (!pScrollBar->IsVisible())
    465 						{
    466 							pScrollBar->SetVisible(TRUE);
    467 							RePosChildWnd();
    468 						}
    469 						else
    470 						{
    471 						}
    472 					}
    473 					else
    474 					{
    475 						if (pScrollBar->IsVisible())
    476 						{
    477 							pScrollBar->SetVisible(FALSE);
    478 							RePosChildWnd();
    479 						}
    480 
    481 						if (m_pListContent)
    482 							m_pListContent->SetScrollPos(CPDF_Point(0.0f,0.0f));
    483 					}
    484 
    485 					pScrollBar->OnNotify(pWnd,PNM_SETSCROLLINFO,wParam,lParam);
    486 				}
    487 			}
    488 			return;
    489 		case PNM_SCROLLWINDOW:
    490 			if (m_pListContent)
    491 			{
    492 				m_pListContent->SetScrollPos(CPDF_Point(0.0f, *(FX_FLOAT*)lParam));
    493 				m_pListContent->ResetFace();
    494 				m_pListContent->InvalidateRect(NULL);
    495 			}
    496 			return;
    497 		case PNM_SETSCROLLPOS:
    498 			if (CPWL_ScrollBar* pScrollBar = this->GetVScrollBar())
    499 				pScrollBar->OnNotify(pWnd,PNM_SETSCROLLPOS,wParam,lParam);
    500 			return;
    501 		}
    502 	}
    503 }
    504 
    505 void CPWL_IconList::SetSelect(FX_INT32 nIndex)
    506 {
    507 	m_pListContent->SetSelect(nIndex);
    508 }
    509 
    510 void CPWL_IconList::SetTopItem(FX_INT32 nIndex)
    511 {
    512 	m_pListContent->ScrollToItem(nIndex);
    513 }
    514 
    515 FX_INT32 CPWL_IconList::GetSelect() const
    516 {
    517 	return m_pListContent->GetSelect();
    518 }
    519 
    520 void CPWL_IconList::SetNotify(IPWL_IconList_Notify* pNotify)
    521 {
    522 	m_pListContent->SetNotify(pNotify);
    523 }
    524 
    525 void CPWL_IconList::EnableNotify(FX_BOOL bNotify)
    526 {
    527 	m_pListContent->EnableNotify(bNotify);
    528 }
    529 
    530 void CPWL_IconList::SetListData(FX_INT32 nItemIndex, void* pData)
    531 {
    532 	m_pListContent->SetListData(nItemIndex, pData);
    533 }
    534 
    535 void CPWL_IconList::SetListIcon(FX_INT32 nItemIndex, FX_INT32 nIconIndex)
    536 {
    537 	m_pListContent->SetListIcon(nItemIndex, nIconIndex);
    538 }
    539 
    540 void CPWL_IconList::SetListString(FX_INT32 nItemIndex, const CFX_WideString& str)
    541 {
    542 	m_pListContent->SetListString(nItemIndex, str);
    543 }
    544 
    545 CFX_WideString CPWL_IconList::GetListString(FX_INT32 nItemIndex) const
    546 {
    547 	return m_pListContent->GetListString(nItemIndex);
    548 }
    549 
    550 void CPWL_IconList::SetIconFillColor(const CPWL_Color& color)
    551 {
    552 	m_pListContent->SetIconFillColor(color);
    553 }
    554 
    555 FX_BOOL	CPWL_IconList::OnMouseWheel(short zDelta, const CPDF_Point & point)
    556 {
    557 	CPDF_Point ptScroll = m_pListContent->GetScrollPos();
    558 	CPDF_Rect rcScroll = m_pListContent->GetScrollArea();
    559 	CPDF_Rect rcContents = m_pListContent->GetClientRect();
    560 
    561 	if (rcScroll.top - rcScroll.bottom > rcContents.Height())
    562 	{
    563 		CPDF_Point ptNew = ptScroll;
    564 
    565 		if (zDelta > 0)
    566 			ptNew.y += 30;
    567 		else
    568 			ptNew.y -= 30;
    569 
    570 		if (ptNew.y > rcScroll.top)
    571 			ptNew.y = rcScroll.top;
    572 		if (ptNew.y < rcScroll.bottom + rcContents.Height())
    573 			ptNew.y = rcScroll.bottom + rcContents.Height();
    574 		if (ptNew.y < rcScroll.bottom)
    575 			ptNew.y = rcScroll.bottom;
    576 
    577 		if (ptNew.y != ptScroll.y)
    578 		{
    579 			m_pListContent->SetScrollPos(ptNew);
    580 			m_pListContent->ResetFace();
    581 			m_pListContent->InvalidateRect(NULL);
    582 
    583 			if (CPWL_ScrollBar* pScrollBar = this->GetVScrollBar())
    584 				pScrollBar->OnNotify(this, PNM_SETSCROLLPOS, SBT_VSCROLL, (FX_INTPTR)&ptNew.y);
    585 
    586 			return TRUE;
    587 		}
    588 	}
    589 
    590 	return FALSE;
    591 }
    592 
    593