/**
* Cleans the lookup tables for the provided item and all children.
* @param item The item to start from
*/
void MaterialTreeView::CleanLookupTrees(HTREEITEM item) {

	idStr qt = GetQuicktreePath(item);
	quickTree.Remove(qt);

	CTreeCtrl& tree = GetTreeCtrl();

	//Clean special lookup tables
	DWORD type = tree.GetItemData(item);
	if(type == TYPE_FILE) {
		idStr file = GetMediaPath(item, TYPE_FILE);
		fileToTree.Remove(file);
	} else if(type == TYPE_MATERIAL) {
		idStr name = GetMediaPath(item, TYPE_MATERIAL);
		materialToTree.Remove(name);
	}

	//Clean all my children
	if(tree.ItemHasChildren(item)) {
		HTREEITEM childItem = tree.GetChildItem(item);
		while(childItem != NULL) {
			CleanLookupTrees(childItem);
			childItem = tree.GetNextSiblingItem(childItem);
		}
	}
}
/**
* Returns the filename of the provided item.
* @param item The item for which to generate the filename
* @param out The location the filename will be placed.
*/
bool MaterialTreeView::GetFileName(HTREEITEM item, idStr& out) {

	out = "";

	CTreeCtrl& tree = GetTreeCtrl();
	DWORD type = tree.GetItemData(item);

	if(type != TYPE_MATERIAL && type != TYPE_MATERIAL_FOLDER && type != TYPE_FILE)
		return false;

	if(type == TYPE_FILE) {
		out = GetMediaPath(item, TYPE_FILE);
		return true;
	}

	HTREEITEM parent = tree.GetParentItem( item );
	while ( parent != NULL ) {
		DWORD parentType = tree.GetItemData(parent);
		if(parentType == TYPE_FILE) {
			out = GetMediaPath(parent, TYPE_FILE);
			return true;
		}
		parent = tree.GetParentItem( parent );
	}

	return false;
}
/**
* Adds a new material.
*/
void MaterialTreeView::OnAddMaterial() {

	CTreeCtrl& tree = GetTreeCtrl();

	HTREEITEM item = tree.GetSelectedItem();
	DWORD itemType = tree.GetItemData(item);

	//Determine the file
	HTREEITEM parent = NULL;
	if(itemType != TYPE_FILE) {

		parent = tree.GetParentItem(item);
		while(1) {
			if(tree.GetItemData(parent) == TYPE_FILE)
				break;
			parent = tree.GetParentItem(parent);
		}
	} else {
		parent = item;
	}
	idStr filename = GetMediaPath(parent, TYPE_FILE);


	//Determine the material folder
	idStr materialFolder = "";
	switch(itemType) {
		case TYPE_MATERIAL:
			{
				HTREEITEM parentFolderItem = tree.GetParentItem(item);
				if(tree.GetItemData(parentFolderItem) == TYPE_MATERIAL_FOLDER)
					materialFolder = GetMediaPath(parentFolderItem, TYPE_MATERIAL_FOLDER);
			}
			break;
		case TYPE_MATERIAL_FOLDER:
			materialFolder = GetMediaPath(item, TYPE_MATERIAL_FOLDER);
			break;
		case TYPE_FILE:
			//There is no material folder
			break;
	}

	idStr name;
	int num = 1;
	while(1) {
		if(materialFolder.Length() > 0) {
			name = va("%s/newmaterial%d", materialFolder.c_str(), num);
		} else {
			name = va("newmaterial%d", num);
		}
		if(!declManager->FindMaterial(name, false))
			break;
		num++;
	}

	materialDocManager->AddMaterial(name.c_str(), filename.c_str());

}
/**
* Searches for a material given the supplied search parameters. Returns the tree item where
* the item was found or NULL if no material was found.
* @param item The tree item from where to start the search.
* @param searchData The parameters to use for the search.
*/
HTREEITEM MaterialTreeView::FindNextMaterial( HTREEITEM item, MaterialSearchData_t *searchData ) {
	CTreeCtrl &tree = GetTreeCtrl();
	DWORD type = tree.GetItemData( item );
	if( type == TYPE_MATERIAL ) {
		//check the tree name first
		idStr itemName = tree.GetItemText( item );
		int findPos = itemName.Find( searchData->searchText, false );
		if( findPos != -1 ) {
			//Todo: Include match whole word
			return item;
		}
		if( !searchData->nameOnly ) {
			//Check the material
			idStr materialName = GetMediaPath( item, TYPE_MATERIAL );
			if( materialDocManager->FindMaterial( materialName, searchData, false ) ) {
				return item;
			}
		}
	} else {
		//Just check the tree name
		idStr itemName = tree.GetItemText( item );
		int findPos = itemName.Find( searchData->searchText, false );
		if( findPos != -1 ) {
			//Todo: Include match whole word
			return item;
		}
	}
	return NULL;
}
/**
* Handles all of the little problems associated with renaming a folder.
*/
void MaterialTreeView::RenameMaterial( HTREEITEM item, const char *originalName ) {
	CTreeCtrl &tree = GetTreeCtrl();
	const idMaterial *material = declManager->FindMaterial( originalName );
	MaterialDoc *pMaterial;
	//pMaterial = materialDocManager->GetInProgressDoc(material);
	//if(!pMaterial) {
	pMaterial = materialDocManager->CreateMaterialDoc( const_cast<idMaterial *>( material ) );
	//}
	//Remove our old quick lookup value
	materialToTree.Remove( originalName );
	//Generate the new name
	idStr materialName;
	HTREEITEM parent = tree.GetParentItem( item );
	DWORD parentType = tree.GetItemData( parent );
	if( parentType == TYPE_MATERIAL_FOLDER ) {
		//Need to include the material folder
		materialName = GetMediaPath( parent, TYPE_MATERIAL_FOLDER );
		materialName += "/";
	}
	materialName += tree.GetItemText( item );
	//Add it to our quick lookup
	materialToTree.Set( materialName, item );
	//Finally make the change
	internalChange = true;
	pMaterial->SetMaterialName( materialName, false );
	internalChange = false;
}
/**
* Performs a paste operation.
*/
void MaterialTreeView::OnPaste() {
	CTreeCtrl &tree = GetTreeCtrl();
	HTREEITEM item = tree.GetSelectedItem();
	DWORD itemType = tree.GetItemData( item );
	//Paste a material
	if( item && materialDocManager->IsCopyMaterial() && itemType >= TYPE_FILE ) {
		//Generate the name
		if( itemType == TYPE_MATERIAL ) { //Backup one if a file is selected
			item = tree.GetParentItem( item );
			itemType = tree.GetItemData( item );
		}
		idStr materialName = "";
		if( itemType != TYPE_FILE ) {
			materialName = GetMediaPath( item, itemType ) + "/";
		}
		idStr copyName = materialDocManager->GetCopyMaterialName();
		idStr copyMaterialName;
		copyName.ExtractFileName( copyMaterialName );
		materialName += copyMaterialName;
		idStr filename;
		GetFileName( item, filename );
		//If the material name already exists add numbers until we don't find it
		materialName = materialDocManager->GetUniqueMaterialName( materialName );
		//Paste
		materialDocManager->PasteMaterial( materialName, filename );
	}
}
/**
* Changes the selected material when the select tree item changes.
*/
void MaterialTreeView::OnTvnSelchanged(NMHDR *pNMHDR, LRESULT *pResult) {

	LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);

	if(pNMTreeView->itemNew.hItem) {
		CTreeCtrl& tree = GetTreeCtrl();

		DWORD type = tree.GetItemData(pNMTreeView->itemNew.hItem);
		if(type == TYPE_MATERIAL) {
			idStr mediaName = GetMediaPath(pNMTreeView->itemNew.hItem, type);
			const idMaterial* material = declManager->FindMaterial(mediaName);

			materialDocManager->SetSelectedMaterial(const_cast<idMaterial*>(material));

		} else {

			materialDocManager->SetSelectedMaterial(NULL);
		}

	} else {

		materialDocManager->SetSelectedMaterial(NULL);
	}

	*pResult = 0;
}
void CSDLStateLocation::Load( CLocationObject* pLocation )
{
	m_pLocationObject = pLocation;

	pEngine->SetCurrentLocation( this );
	
	string sBackgroundImage = pLocation->GetBackgroundImage();
	if ( sBackgroundImage.length() > 0 ) {
		m_pBackground = new CSDLBaseObject;
		m_pBackground->LoadImageFromFile( GetMediaPath( pEngine->GetGameDir(), sBackgroundImage ) );

		// Center the image
		m_pBackground->SetPosX( 400 - (m_pBackground->GetWidth() / 2) );
		m_pBackground->SetPosY( 300 - (m_pBackground->GetHeight() / 2) );
	}

	pLocation->GetItems()->ResetIteration();
	CItemObject* pItemObject = 0;
	for ( unsigned int i = 0; i < pLocation->GetItems()->GetCount(); ++i )
	{
		pItemObject = pLocation->GetItems()->GetNextItem();

		CSDLGameItemObject* pGameItemObject = new CSDLGameItemObject;
		pGameItemObject->SetDescription( pItemObject->GetDescription() );
		pGameItemObject->SetPos( pItemObject->GetPosX(), pItemObject->GetPosY() );
		pGameItemObject->SetOnLoad( pItemObject->GetOnLoad() );
		pGameItemObject->SetOnClick( pItemObject->GetOnClick() );

		if ( pItemObject->GetHasImage() == true ) {
			pGameItemObject->LoadImageFromFile( GetMediaPath( pEngine->GetGameDir(), pItemObject->GetImageName() ) );
		} else {
			pGameItemObject->SetHoverDefaultRect( false );
			
			SDL_Rect stRect;
			stRect.x = pGameItemObject->GetPosX();
			stRect.y = pGameItemObject->GetPosY();
			stRect.w = pItemObject->GetWidth();
			stRect.h = pItemObject->GetHeight();
			pGameItemObject->SetHoverRect( stRect );
		}

		AddObject( pGameItemObject );
		
		pGameItemObject->LoadItem(); // Call the OnLoad-scripting if there is one
	}
}
/**
* Makes sure that a rename operation can be performed after a label edit is complete and
* performs the folder or material rename.
*/
void MaterialTreeView::OnTvnEndlabeledit( NMHDR *pNMHDR, LRESULT *pResult ) {
	LPNMTVDISPINFO pTVDispInfo = reinterpret_cast<LPNMTVDISPINFO>( pNMHDR );
	*pResult = 0;
	if( pTVDispInfo->item.pszText ) {
		//Convert any edited text to lower case to keep the name canonical
		idStr newLabel = pTVDispInfo->item.pszText;
		newLabel.ToLower();
		strncpy( pTVDispInfo->item.pszText, newLabel.c_str(), pTVDispInfo->item.cchTextMax );
		CTreeCtrl &tree = GetTreeCtrl();
		DWORD type = tree.GetItemData( pTVDispInfo->item.hItem );
		if( type == TYPE_MATERIAL ) {
			MaterialDoc *pMaterial = materialDocManager->GetCurrentMaterialDoc();
			//Remove our old quick lookup value
			materialToTree.Remove( pMaterial->name.c_str() );
			//Generate the new name
			idStr material;
			HTREEITEM parent = tree.GetParentItem( pTVDispInfo->item.hItem );
			DWORD parentType = tree.GetItemData( parent );
			if( parentType == TYPE_MATERIAL_FOLDER ) {
				//Need to include the material folder
				material = GetMediaPath( parent, TYPE_MATERIAL_FOLDER );
				material += "/";
			}
			material += pTVDispInfo->item.pszText;
			if( declManager->FindMaterial( material, false ) ) {
				//Can't rename because it conflicts with an existing file
				MessageBox( "Unable to rename material because it conflicts with another material", "Error" );
			} else {
				//Add it to our quick lookup
				materialToTree.Set( material, pTVDispInfo->item.hItem );
				//Finally make the change
				internalChange = true;
				pMaterial->SetMaterialName( material );
				internalChange = false;
				renamedFolder = pTVDispInfo->item.hItem;
				PostMessage( MSG_RENAME_MATERIAL_COMPLETE );
				*pResult = 1;
			}
		} else if( type == TYPE_MATERIAL_FOLDER ) {
			//Clean up the quicktree with the current tree before we allow the edit to commit
			CleanLookupTrees( pTVDispInfo->item.hItem );
			//Store some data so the we can make the appropriate changes after the commit
			renamedFolder = pTVDispInfo->item.hItem;
			affectedMaterials.Clear();
			GetMaterialPaths( renamedFolder, &affectedMaterials );
			PostMessage( MSG_RENAME_FOLDER_COMPLETE );
			RenameMaterialFolderModifier *mod = new RenameMaterialFolderModifier( materialDocManager, pTVDispInfo->item.pszText, this, pTVDispInfo->item.hItem, tree.GetItemText( pTVDispInfo->item.hItem ) );
			materialDocManager->AddMaterialUndoModifier( mod );
			*pResult = 1;
		}
	}
}
Example #10
0
/**
* Handles the end of a drag copy/move when the user releases the left mouse button.
*/
void MaterialTreeView::OnLButtonUp( UINT nFlags, CPoint point ) {
	CTreeCtrl &tree = GetTreeCtrl();
	if( bDragging ) {
		//Release mouse capture
		ReleaseCapture();
		//Delete the drag image
		dragImage->DragLeave( GetDesktopWindow() );
		dragImage->EndDrag();
		bDragging = false;
		delete dragImage;
		UINT flags;
		HTREEITEM item = tree.HitTest( point, &flags );
		if( item && ( TVHT_ONITEM & flags ) ) {
			DWORD itemType = tree.GetItemData( item );
			if( itemType == TYPE_MATERIAL ) { //Backup one if a file is selected
				item = tree.GetParentItem( item );
			}
			//Make sure we aren't dragging to the same place
			HTREEITEM dragItemParent = tree.GetParentItem( dragItem );
			if( dragItemParent != item ) {
				idStr dragFile;
				GetFileName( dragItem, dragFile );
				idStr filename;
				GetFileName( item, filename );
				//Move within a file copy across files
				if( !dragFile.Icmp( filename ) ) {
					materialDocManager->CopyMaterial( materialDocManager->GetCurrentMaterialDoc(), true );
				} else {
					materialDocManager->CopyMaterial( materialDocManager->GetCurrentMaterialDoc(), false );
				}
				//Generate the name
				idStr materialName = GetMediaPath( item, itemType );
				idStr copyName = materialDocManager->GetCopyMaterialName();
				idStr copyMaterialName;
				copyName.ExtractFileName( copyMaterialName );
				materialName += "/" + copyMaterialName;
				//If the material name already exists add numbers until we don't find it
				materialName = materialDocManager->GetUniqueMaterialName( materialName );
				//Paste
				materialDocManager->PasteMaterial( materialName, filename );
			}
		}
	}
	CTreeView::OnLButtonUp( nFlags, point );
}
Example #11
0
/**
* Creates a list of material paths for all materials under the provided item.
* @param item The base item for which to generate the list
* @param list The list in which the paths will be stored.
*/
void MaterialTreeView::GetMaterialPaths( HTREEITEM item, idList<MaterialTreeItem_t> *list ) {
	CTreeCtrl &tree = GetTreeCtrl();
	if( tree.ItemHasChildren( item ) ) {
		HTREEITEM childItem = tree.GetChildItem( item );
		while( childItem != NULL ) {
			DWORD childType = tree.GetItemData( childItem );
			if( childType == TYPE_MATERIAL ) {
				MaterialTreeItem_t mat;
				mat.materialName = GetMediaPath( childItem, TYPE_MATERIAL );
				mat.treeItem = childItem;
				list->Append( mat );
			} else if( childType == TYPE_MATERIAL_FOLDER ) {
				GetMaterialPaths( childItem, list );
			}
			childItem = tree.GetNextSiblingItem( childItem );
		}
	}
}
Example #12
0
	bool Renderer::Init(const RECT &windowRect, HWND hWnd)
	{
		if(!hWnd)
			return false;
		
		this->hWnd = hWnd;
		this->bbWidth = windowRect.right - windowRect.left;
		this->bbHeight = windowRect.bottom - windowRect.top;

		HRESULT result;

		result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&this->factory);
		if(FAILED(result))
		{
			OutputDebugString("\nCreateDXGIFactory() failed\n");
			return false;
		}

		result = this->factory->EnumAdapters(0, (IDXGIAdapter**)&this->adapter);
		if(FAILED(result))
		{
			OutputDebugString("\nfactory->EnumAdapters() failed\n");
			return false;
		}

		D3D_FEATURE_LEVEL featureLvl11 = D3D_FEATURE_LEVEL_11_0;

		DXGI_SWAP_CHAIN_DESC swapChainDescription;
		ZeroMemory(&swapChainDescription, sizeof(swapChainDescription));
	
		swapChainDescription.BufferCount = 2;
		swapChainDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
		//swapChainDescription.Flags = 0;

		swapChainDescription.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
		swapChainDescription.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
		swapChainDescription.BufferDesc.Width = this->bbWidth;
		swapChainDescription.BufferDesc.Height = this->bbHeight;
		swapChainDescription.BufferDesc.RefreshRate.Numerator = 60;
		swapChainDescription.BufferDesc.RefreshRate.Denominator = 1;
		swapChainDescription.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	
		swapChainDescription.Flags = 0;
		swapChainDescription.OutputWindow = this->hWnd;
	
		swapChainDescription.SampleDesc.Count = 1;
		swapChainDescription.SampleDesc.Quality = 0;

		swapChainDescription.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
		swapChainDescription.Windowed = TRUE;
		
	#ifdef _DEBUG
	
		result = D3D11CreateDeviceAndSwapChain(
					nullptr, 
					D3D_DRIVER_TYPE::D3D_DRIVER_TYPE_HARDWARE, 
					nullptr, 
					D3D11_CREATE_DEVICE_DEBUG,
					&featureLvl11, 
					1, 
					D3D11_SDK_VERSION,
					&swapChainDescription,
					(IDXGISwapChain**)&this->swapChain,
					(ID3D11Device**)&this->device,
					nullptr,
					(ID3D11DeviceContext**)&this->context);

		if(FAILED(result))
		{
			OutputDebugString("\nD3D11CreateDeviceAndSwapChain() failed\n");
			return false;
		}

	#else

		result = D3D11CreateDeviceAndSwapChain(
					nullptr, 
					D3D_DRIVER_TYPE::D3D_DRIVER_TYPE_HARDWARE, 
					nullptr, 
					nullptr, 
					&featureLvl11, 
					1, 
					D3D11_SDK_VERSION,
					&swapChainDescription,
					(IDXGISwapChain**)&this->SwapChain,
					(ID3D11Device**)&this->Device,
					nullptr,
					(ID3D11DeviceContext**)&this->Context);

		if(FAILED(result))
		{
			return false;
		}

	#endif

		ID3D11Texture2D *bbSurfacePtr = nullptr;
		result = this->swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&bbSurfacePtr);
		if(FAILED(result))
		{
			OutputDebugString("\nswapChain->GetBuffer() failed\n");
			return false;
		}
	
		result = this->device->CreateRenderTargetView(bbSurfacePtr, nullptr, (ID3D11RenderTargetView**)&this->RTView);
		if(FAILED(result))
		{
			OutputDebugString("\ndevice->createRenderTargetView failed\n");
			return false;
		}

		if(!this->createShadersAndInputLayouts())
			return false;

		this->context->OMSetRenderTargets(1, (ID3D11RenderTargetView**)&this->RTView, nullptr);
	
		D3D11_VIEWPORT viewport;
		ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));
		viewport.Height = this->bbHeight;
		viewport.Width = this->bbWidth;
		viewport.MaxDepth = 1.0f;
		viewport.MinDepth = 0.0f;
		viewport.TopLeftX = 0.0f;
		viewport.TopLeftY = 0.0f;
		this->context->RSSetViewports(1, &viewport);

		//create a state to disable depth stencil buffer
		// Clear the second depth stencil state before setting the parameters.
		D3D11_DEPTH_STENCIL_DESC depthDisabledStencilDesc;

		ZeroMemory(&depthDisabledStencilDesc, sizeof(depthDisabledStencilDesc));

		// Now create a second depth stencil state which turns off the Z buffer for 2D rendering.  The only difference is 
		// that DepthEnable is set to false, all other parameters are the same as the other depth stencil state.
		depthDisabledStencilDesc.DepthEnable = false;
		depthDisabledStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
		depthDisabledStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;
		depthDisabledStencilDesc.StencilEnable = true;
		depthDisabledStencilDesc.StencilReadMask = 0xFF;
		depthDisabledStencilDesc.StencilWriteMask = 0xFF;
		depthDisabledStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
		depthDisabledStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
		depthDisabledStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
		depthDisabledStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
		depthDisabledStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
		depthDisabledStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
		depthDisabledStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
		depthDisabledStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
		
		// Create the state using the device.
		result = this->device->CreateDepthStencilState(&depthDisabledStencilDesc, &this->depthStencilDisabled);
		if (FAILED(result))
		{
			return false;
		}

		this->context->OMGetDepthStencilState(&this->depthStencilEnabled, NULL);

		if(!this->createRasterizerStates())
			return false;

		this->viewMat = Matrix::Identity();

		if(!this->createCBuffers())
			return false;

		if(!this->createSamplers())
			return false;

		try
		{
			this->SBatch = new SpriteBatch(this->context);
			this->SFont = new SpriteFont(this->device, GetMediaPath(L"arial.spritefont").data());
		}
		catch(std::exception e)
		{
			OutputDebugString("\n");
			OutputDebugString(e.what());
			OutputDebugString("\n");
			return false;
		}

		return true;
	}
Example #13
0
/**
* Adds a string list of materials to the tree creating the proper hierarchy.
* @param root The name of the root item or NULL for no root item.
* @param list The list of materials.
* @param includeFile If true the materials will be sorted by file.
*/
void MaterialTreeView::AddStrList( const char *root, idStrList *list, bool includeFile ) {
	CTreeCtrl &treeMedia = GetTreeCtrl();
	idStr		out, path;
	HTREEITEM	base = NULL;
	if( root ) {
		base = treeMedia.GetRootItem();
		if( base ) {
			out = treeMedia.GetItemText( base );
			if( stricmp( root, out ) ) {
				base = NULL;
			}
		}
		if( base == NULL ) {
			base = treeMedia.InsertItem( root );
			treeMedia.SetItemData( base, TYPE_ROOT );
		}
	}
	HTREEITEM	item = base;
	HTREEITEM	add;
	list->Sort();
	int	count = list->Num();
	idStr	last, qt;
	for( int i = 0; i < count; i++ ) {
		idStr *strItem = &( *list )[i];
		idStr name = strItem->c_str();
		idStr filename;
		bool afterFile = true;
		if( includeFile ) {
			int index = name.Find( "|" );
			if( index >= 0 ) {
				afterFile = false;
				filename = name.Right( name.Length() - index - 1 );
				name = name.Left( index );
			}
		}
		// now break the name down convert to slashes
		name.BackSlashesToSlashes();
		name.Strip( ' ' );
		int index;
		int len = last.Length();
		if( len == 0 ) {
			index = name.Last( '/' );
			if( index >= 0 ) {
				name.Left( index, last );
			}
		} else if( idStr::Icmpn( last, name, len ) == 0 && name.Last( '/' ) <= len ) {
			name.Right( name.Length() - len - 1, out );
			add = treeMedia.InsertItem( out, item );
			qt = root;
			qt += "/";
			qt += name;
			quickTree.Set( qt, add );
			treeMedia.SetItemImage( add, IMAGE_MATERIAL, IMAGE_MATERIAL );
			treeMedia.SetItemData( add, TYPE_MATERIAL );
			//Add the item to a quick lookup table
			idStr material = GetMediaPath( add, TYPE_MATERIAL );
			materialToTree.Set( material, add );
			continue;
		} else {
			last.Empty();
		}
		index = 0;
		item = base;
		path = "";
		while( index >= 0 ) {
			index = name.Find( '/' );
			if( index >= 0 ) {
				HTREEITEM newItem = NULL;
				HTREEITEM *check = NULL;
				name.Left( index, out );
				path += out;
				qt = root;
				qt += "/";
				qt += path;
				if( quickTree.Get( qt, &check ) ) {
					newItem = *check;
				}
				bool thisisfile = false;
				if( out == filename ) {
					thisisfile = true;
					afterFile = true;
				}
				if( newItem == NULL ) {
					newItem = treeMedia.InsertItem( out, item );
					qt = root;
					qt += "/";
					qt += path;
					quickTree.Set( qt, newItem );
					if( !afterFile || thisisfile ) {
						if( thisisfile ) {
							afterFile = true;
							treeMedia.SetItemImage( newItem, IMAGE_FILE, IMAGE_FILE );
							treeMedia.SetItemData( newItem, TYPE_FILE );
							//Add the item to a quick lookup table
							idStr file = GetMediaPath( newItem, TYPE_FILE );
							//common->Printf("Adding fileToTree: %s - %d\n", file.c_str(), newItem);
							fileToTree.Set( file, newItem );
						} else {
							treeMedia.SetItemImage( newItem, IMAGE_FOLDER, IMAGE_FOLDER );
							treeMedia.SetItemData( newItem, TYPE_FOLDER );
						}
					} else {
						treeMedia.SetItemImage( newItem, IMAGE_MATERIAL_FOLDER, IMAGE_MATERIAL_FOLDER );
						treeMedia.SetItemData( newItem, TYPE_MATERIAL_FOLDER );
					}
				}
				item = newItem;
				name.Right( name.Length() - index - 1, out );
				name = out;
				path += "/";
			} else {
				add = treeMedia.InsertItem( name, item );
				qt = root;
				qt += "/";
				qt += path;
				qt += name;
				quickTree.Set( qt, add );
				treeMedia.SetItemImage( add, IMAGE_MATERIAL, IMAGE_MATERIAL );
				treeMedia.SetItemData( add, TYPE_MATERIAL );
				path = "";
				//Add the item to a quick lookup table
				idStr material = GetMediaPath( add, TYPE_MATERIAL );
				materialToTree.Set( material, add );
			}
		}
	}
}