Beispiel #1
0
void DesktopShellView::PositionIcons(int dir)
{
	DWORD spacing = ListView_GetItemSpacing(_hwndListView, FALSE);

	RECT work_area;
	SystemParametersInfo(SPI_GETWORKAREA, 0, &work_area, 0);

	/* disable default allignment */
	SetWindowStyle(_hwndListView, GetWindowStyle(_hwndListView)&~LVS_ALIGNMASK);//|LVS_ALIGNTOP|LVS_AUTOARRANGE);

	const POINTS& dir1 = s_align_dir1[_icon_algo];
	const POINTS& dir2 = s_align_dir2[_icon_algo];
	const POINTS& start_pos = s_align_start[_icon_algo];

	int dir_x1 = dir1.x;
	int dir_y1 = dir1.y;
	int dir_x2 = dir2.x;
	int dir_y2 = dir2.y;

	int cx = LOWORD(spacing);
	int cy = HIWORD(spacing);

	int dx1 = dir_x1 * cx;
	int dy1 = dir_y1 * cy;
	int dx2 = dir_x2 * cx;
	int dy2 = dir_y2 * cy;

	int xoffset = (cx-32)/2;
	int yoffset = 4/*(cy-32)/2*/;

	int start_x = start_pos.x * (work_area.right - cx) + xoffset;
	int start_y = start_pos.y * (work_area.bottom - cy) + yoffset;

	int x = start_x;
	int y = start_y;

	int all = ListView_GetItemCount(_hwndListView);
	int i1, i2;

	if (dir > 0) {
		i1 = 0;
		i2 = all;
	} else {
		i1 = all-1;
		i2 = -1;
	}

	IconMap pos_idx;
	int cnt = 0;
	int xhv = start_x;
	int yhv = start_y;

	for(int idx=i1; idx!=i2; idx+=dir) {
		pos_idx[IconPos(y, x)] = idx;

		if (_icon_algo == ARRANGE_BORDER_DOWN) {
			if (++cnt & 1)
				x = work_area.right - x - cx + 2*xoffset;
			else {
				y += dy1;

				if (y + cy - 2 * yoffset > work_area.bottom) {
					y = start_y;
					start_x += dx2;
					x = start_x;
				}
			}

			continue;
		}
		else if (_icon_algo == ARRANGE_BORDER_HV) {
			if (++cnt & 1)
				x = work_area.right - x - cx + 2*xoffset;
			else if (cnt & 2) {
				yhv += cy;
				y = yhv;
				x = start_x;

				if (y + cy - 2 * yoffset > work_area.bottom) {
					start_x += cx;
					xhv = start_x;
					x = xhv;
					start_y += cy;
					yhv = start_y;
					y = yhv;
				}
			} else {
				xhv += cx;
				x = xhv;
				y = start_y;

				if (x + cx - 2 * xoffset > work_area.right) {
					start_x += cx;
					xhv = start_x;
					x = xhv;
					start_y += cy;
					yhv = start_y;
					y = yhv;
				}
			}

			continue;
		}
		else if (_icon_algo == ARRANGE_ROUNDABOUT) {

			///@todo

		}

		x += dx1;
		y += dy1;

		if (x<0 || x+cx-2*xoffset>work_area.right) {
			x = start_x;
			y += dy2;
		} else if (y<0 || y+cy-2*yoffset>work_area.bottom) {
			y = start_y;
			x += dx2;
		}
	}

	 // use a little trick to get the icons where we want them to be...

	//for(IconMap::const_iterator it=pos_idx.end(); --it!=pos_idx.begin(); ) {
	//	const IconPos& pos = it->first;

	//	ListView_SetItemPosition32(_hwndListView, it->second, pos.second, pos.first);
	//}

	for(IconMap::const_iterator it=pos_idx.begin(); it!=pos_idx.end(); ++it) {
		const IconPos& pos = it->first;

		ListView_SetItemPosition32(_hwndListView, it->second, pos.second, pos.first);
	}
}
void inline CShellBrowser::InsertAwaitingItems(BOOL bInsertIntoGroup)
{
	LVITEM lv;
	ULARGE_INTEGER ulFileSize;
	unsigned int nPrevItems;
	int nAdded = 0;
	int iItemIndex;

	nPrevItems = ListView_GetItemCount(m_hListView);

	m_nAwaitingAdd = (int)m_AwaitingAddList.size();

	if((nPrevItems + m_nAwaitingAdd) == 0)
	{
		if(m_bApplyFilter)
			SendMessage(m_hOwner,WM_USER_FILTERINGAPPLIED,m_ID,TRUE);
		else
			SendMessage(m_hOwner,WM_USER_FOLDEREMPTY,m_ID,TRUE);

		m_nTotalItems = 0;

		return;
	}
	else if(!m_bApplyFilter)
	{
		SendMessage(m_hOwner,WM_USER_FOLDEREMPTY,m_ID,FALSE);
	}

	/* Make the listview allocate space (for internal data structures)
	for all the items at once, rather than individually.
	Acts as a speed optimization. */
	ListView_SetItemCount(m_hListView,m_nAwaitingAdd + nPrevItems);

	lv.mask			= LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM;

	if(bInsertIntoGroup)
		lv.mask		|= LVIF_GROUPID;

	/* Constant for each item. */
	lv.iSubItem		= 0;

	if(m_bAutoArrange)
		NListView::ListView_SetAutoArrange(m_hListView,FALSE);

	for(auto itr = m_AwaitingAddList.begin();itr != m_AwaitingAddList.end();itr++)
	{
		if(!IsFileFiltered(itr->iItemInternal))
		{
			lv.iItem	= itr->iItem;
			lv.pszText	= ProcessItemFileName(itr->iItemInternal);
			lv.iImage	= I_IMAGECALLBACK;
			lv.lParam	= itr->iItemInternal;

			if(bInsertIntoGroup)
			{
				lv.iGroupId	= DetermineItemGroup(itr->iItemInternal);
			}

			/* Insert the item into the list view control. */
			iItemIndex = ListView_InsertItem(m_hListView,&lv);

			if(itr->bPosition && m_ViewMode != VM_DETAILS)
			{
				POINT ptItem;

				if(itr->iAfter != -1)
				{
					ListView_GetItemPosition(m_hListView,itr->iAfter,&ptItem);
				}
				else
				{
					ptItem.x = 0;
					ptItem.y = 0;
				}

				/* The item will end up in the position AFTER iAfter. */
				ListView_SetItemPosition32(m_hListView,iItemIndex,ptItem.x,ptItem.y);
			}

			if(m_ViewMode == VM_TILES)
			{
				SetTileViewItemInfo(iItemIndex,itr->iItemInternal);
			}

			if(m_bNewItemCreated)
			{
				LPITEMIDLIST pidlComplete = NULL;

				pidlComplete = ILCombine(m_pidlDirectory,m_pExtraItemInfo[(int)itr->iItemInternal].pridl);

				if(CompareIdls(pidlComplete,m_pidlNewItem))
					m_bNewItemCreated = FALSE;

				m_iIndexNewItem = iItemIndex;

				CoTaskMemFree(pidlComplete);
			}

			/* If the file is marked as hidden, ghost it out. */
			if(m_pwfdFiles[itr->iItemInternal].dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
			{
				ListView_SetItemState(m_hListView,iItemIndex,LVIS_CUT,LVIS_CUT);
			}
			
			/* Add the current file's size to the running size of the current directory. */
			/* A folder may or may not have 0 in its high file size member.
			It should either be zeroed, or never counted. */
			ulFileSize.LowPart = m_pwfdFiles[itr->iItemInternal].nFileSizeLow;
			ulFileSize.HighPart = m_pwfdFiles[itr->iItemInternal].nFileSizeHigh;

			m_ulTotalDirSize.QuadPart += ulFileSize.QuadPart;

			nAdded++;
		}
		else
		{
			m_FilteredItemsList.push_back(itr->iItemInternal);
		}
	}

	if(m_bAutoArrange)
		NListView::ListView_SetAutoArrange(m_hListView,TRUE);

	m_nTotalItems = nPrevItems + nAdded;

	if(m_ViewMode == VM_DETAILS)
	{
		TCHAR szDrive[MAX_PATH];
		BOOL bNetworkRemovable = FALSE;

		QueueUserAPC(SetAllColumnDataAPC,m_hThread,(ULONG_PTR)this);

		StringCchCopy(szDrive,SIZEOF_ARRAY(szDrive),m_CurDir);
		PathStripToRoot(szDrive);

		if(GetDriveType(szDrive) == DRIVE_REMOVABLE ||
			GetDriveType(szDrive) == DRIVE_REMOTE)
		{
			bNetworkRemovable = TRUE;
		}

		/* If the user has selected to disable folder sizes
		on removable drives or networks, and we are currently
		on such a drive, do not calculate folder sizes. */
		if(m_bShowFolderSizes && !(m_bDisableFolderSizesNetworkRemovable && bNetworkRemovable))
			QueueUserAPC(SetAllFolderSizeColumnDataAPC,m_hFolderSizeThread,(ULONG_PTR)this);
	}

	PositionDroppedItems();

	m_AwaitingAddList.clear();
	m_nAwaitingAdd = 0;
}