Added aqua_speed for rite geo 50 tryker
[ryzomcore.git] / nel / tools / 3d / tile_edit / TileCtrl.cpp
blob3ba085c2b3eb40e97d2aadf865dc235312281a02
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include "stdafx.h"
18 #include "TileCtrl.h"
19 #include "browse.h"
23 BEGIN_MESSAGE_MAP(TileCtrl, CListCtrl)
24 //{{AFX_MSG_MAP(TileCtrl)
25 ON_WM_PAINT()
26 ON_WM_DROPFILES()
27 ON_WM_RBUTTONDOWN()
28 ON_WM_LBUTTONDOWN()
29 ON_WM_LBUTTONDBLCLK()
30 ON_WM_VSCROLL()
31 //}}AFX_MSG_MAP
32 END_MESSAGE_MAP()
34 /////////////////////////////////////////////////////////////////////////////
35 // TileCtrl message handlers
39 //gloabal
40 int CALLBACK CompareFunc(LPARAM lParam1,LPARAM lParam2,LPARAM lParamSort)
42 TileCtrl *theCtrl = (TileCtrl*)lParamSort;
43 int i1=((TileInfo*)lParam1)->id;
44 int i2=((TileInfo*)lParam2)->id;
45 if (i1==i2) return 0;
46 if (i1<i2) return -1;
47 else return 1;
54 //TileInfo
55 TileInfo::TileInfo()
57 Loaded=h=g=b=d=0; Bits = NULL;
58 Selected = 0;
68 //Edge
69 _Edge::_Edge()
71 line = 0;
74 _Edge::~_Edge()
76 if (line) delete line;
79 _Edge::_Edge(const _Edge& edge)
81 line = new char[edge.size*3];
82 memcpy(line,edge.line,edge.size*3);
83 size = edge.size;
86 int _Edge::operator == (const _Edge & ed) const
88 if (ed.size!=size) return 0;
89 for (int i=0;i<size*3;i++)
91 if (ed.line[i]!=line[i]) return 0;
93 return 1;
96 void _Edge::CreateH(TileInfo *tile)
98 size = tile->BmpInfo.bmiHeader.biWidth-2; //on n'inclut pas les coins dans les bordures
99 line = new char[3*size];
100 for (int i=0;i<size;i++)
102 line[i*3]=((char*)tile->Bits)[(i+1)*3+(tile->BmpInfo.bmiHeader.biWidth)*(tile->BmpInfo.bmiHeader.biHeight-1)*3];
103 line[i*3+1]=((char*)tile->Bits)[(i+1)*3+1+(tile->BmpInfo.bmiHeader.biWidth)*(tile->BmpInfo.bmiHeader.biHeight-1)*3];
104 line[i*3+2]=((char*)tile->Bits)[(i+1)*3+2+(tile->BmpInfo.bmiHeader.biWidth)*(tile->BmpInfo.bmiHeader.biHeight-1)*3];
108 void _Edge::CreateB(TileInfo *tile)
110 size = tile->BmpInfo.bmiHeader.biWidth-2; //on n'inclut pas les coins dans les bordures
111 line = new char[3*size];
112 for (int i=0;i<size;i++)
114 line[i*3]=((char*)tile->Bits)[(i+1)*3];
115 line[i*3+1]=((char*)tile->Bits)[(i+1)*3+1];
116 line[i*3+2]=((char*)tile->Bits)[(i+1)*3+2];
120 void _Edge::CreateG(TileInfo *tile)
122 size = tile->BmpInfo.bmiHeader.biHeight-2; //on n'inclut pas les coins dans les bordures
123 line = new char[3*size];
124 for (int i=0;i<size;i++)
126 line[i*3]=((char*)tile->Bits)[(i+1)*3*tile->BmpInfo.bmiHeader.biWidth];
127 line[i*3+1]=((char*)tile->Bits)[(i+1)*3*tile->BmpInfo.bmiHeader.biWidth+1];
128 line[i*3+2]=((char*)tile->Bits)[(i+1)*3*tile->BmpInfo.bmiHeader.biWidth+2];
132 void _Edge::CreateD(TileInfo *tile)
134 size = tile->BmpInfo.bmiHeader.biHeight-2; //on n'inclut pas les coins dans les bordures
135 line = new char[3*size];
136 for (int i=0;i<size;i++)
138 line[i*3]=((char*)tile->Bits)[(i+1)*3*tile->BmpInfo.bmiHeader.biWidth+(tile->BmpInfo.bmiHeader.biWidth-1)*3];
139 line[i*3+1]=((char*)tile->Bits)[(i+1)*3*tile->BmpInfo.bmiHeader.biWidth+1+(tile->BmpInfo.bmiHeader.biWidth-1)*3];
140 line[i*3+2]=((char*)tile->Bits)[(i+1)*3*tile->BmpInfo.bmiHeader.biWidth+2+(tile->BmpInfo.bmiHeader.biWidth-1)*3];
151 //TileList
152 TileList::TileList()
154 last_id = 0;
155 i=NULL;
158 int TileList::Add(const char *path)
160 TileInfo *info = new TileInfo;
161 info->id = last_id++;
162 if (path)
164 info->path = new char[strlen(path)];
165 strcpy(info->path,path);
167 theList.insert(theList.end(),info);
168 if (i==NULL) i=theList.begin();
169 else i++;
170 return 1;
173 void TileList::Delete(tilelist::iterator i,int n)
175 for (int k=0;k<n;k++)
177 if ((*i)->Loaded)
179 delete (*i)->Bits;
180 (*i)->Loaded=0;
181 // TODO : delete DIB section
183 i++;
187 void TileList::DeleteAll()
189 int size = theList.size();
190 if (size==0) return;
191 Delete(theList.begin()++,size);
194 char buffer_bidon[SIZE_BIG*SIZE_BIG*3];
195 void TileList::Reload(CDC *pDC,tilelist::iterator iFirst,int n) //recharge en memoire une tranche de tiles
197 /*tilelist::iterator p = iFirst;
198 for (int i=0;i<n;i++)
200 if (!(*p)->Loaded && _LoadBitmap((*p)->path,&(*p)->BmpInfo,&(*p)->Bits))
202 (*p)->Loaded=1;
203 (*p)->DibSection = CreateDIBSection(pDC->m_hDC,&(*p)->BmpInfo,DIB_RGB_COLORS,(void**)&buffer_bidon,0,0);
205 p++;
215 //TileCtrl
216 TileCtrl::TileCtrl()
218 sizetile_x = SIZE_SMALL; sizetile_y = SIZE_SMALL;
219 spacing_x = SPACING_SMALL_X; spacing_y = SPACING_SMALL_Y;
220 Zoom=1; Texture = 1; Sort = 1; InfoTexte = 1;
221 count_ = 0; ViewTileMode = 0;
222 iFirst = iLast = 0;
223 scrollpos = 0;
226 TileCtrl::~TileCtrl()
230 void TileCtrl::Init()
232 spacing_x = 10; spacing_y = 10; spacing_tile_text = 5;
233 sizeicon_x = spacing_tile_text + sizetile_x;
234 sizeicon_y = spacing_tile_text + sizetile_y;
235 pipo_buffer = (void *)new char[sizetile_x * sizetile_y * 3];
236 bmp = new CBitmap;
237 bmp->CreateBitmap(sizetile_x,sizetile_y,1,24,pipo_buffer);
238 pImList = new CImageList;
239 pImList->Create(sizetile_x,sizetile_y,ILC_COLOR24,0,1);
240 pImList->Add(bmp,(CBitmap*)NULL);
241 SetImageList(pImList,0);
242 char name[256];
243 char *defautpath = ((SelectionTerritoire*)GetParent()->GetParent())->DefautPath.GetBuffer(256);
244 /*sprintf(name,"%s%s",defautpath,"croix.bmp");
245 if (_LoadBitmap(name,&TileCroix.BmpInfo,&TileCroix.Bits,false,false))
247 int size=TileCroix.BmpInfo.bmiHeader.biHeight*TileCroix.BmpInfo.bmiHeader.biWidth*TileCroix.BmpInfo.bmiHeader.biBitCount/8;
248 char *temp = new char[size];
249 TileCroix.DibSection = CreateDIBSection(GetDC()->m_hDC,&TileCroix.BmpInfo,DIB_RGB_COLORS,(void**)&temp,0,0);
251 count_=1;
254 void TileCtrl::Delete()
256 count_=0; pImList = 0;
259 int TileCtrl::GetNbTileLine(void)
261 RECT rect; GetClientRect(&rect);
262 return ((rect.right - rect.left - spacing_x)/(sizeicon_x + spacing_x));
265 int TileCtrl::GetNbTileColumn(void)
267 RECT rect; GetClientRect(&rect);
268 return ((rect.bottom - rect.top - spacing_y)/(sizeicon_y + spacing_y));
271 void TileCtrl::GetVisibility(int &First,int &Last) //retourne l'indice du premier et du dernier item visible dans la fenetre
273 RECT rect;
274 int i = GetNbTileLine();
275 int j = GetNbTileColumn();
276 GetClientRect(&rect);
277 First = (rect.top + scrollpos - spacing_y)/(sizeicon_y + spacing_y);
278 if (First<0) First = 0;
279 else First *= i;
280 Last = First + i*(j+1);
281 if (InfoList.theList.size()>0 && Last>=InfoList.theList.size()) Last = InfoList.theList.size()-1;
284 int TileCtrl::GetIndex(LPPOINT pt) //retourne l'index d'un incone a partir de sa position dans le fenetre
285 //si le curseur n'est pas sur un icon, retourne -1
287 int i = GetNbTileLine();
288 if ((pt->y+scrollpos)<spacing_y) return -1;
289 int y = (pt->y + scrollpos - spacing_y)%(spacing_y + sizeicon_y);
290 if (y>sizeicon_y) return -1;
291 int il = (pt->y + scrollpos - spacing_y)/(spacing_y + sizeicon_y);
292 int x = (pt->x - spacing_x)%(spacing_x + sizeicon_x);
293 if (x>sizeicon_x) return -1;
294 int ic = (pt->x - spacing_x)/(spacing_x + sizeicon_x);
295 int ret = ic + il*i;
296 if (i<InfoList.theList.size()) return i;
297 else return -1;
300 POINT TileCtrl::GetPos(int i) //fonction inverse de GetIndex
302 POINT ret;
303 int nl = GetNbTileLine();
304 ret.x = (i%nl)*(spacing_x + sizeicon_x) + spacing_x;
305 ret.y = (i/nl)*(spacing_y + sizeicon_y) + spacing_y + scrollpos;
306 return ret;
309 void TileCtrl::UpdateBuffer() //gestion du cache
311 int c = InfoList.theList.size();
312 if (!c) return;
314 if (iFirst==-1) //le buffer est vide
316 int NbItem =c-iFV; //nbitem : nb d'item a charger
317 if (NbItem>BUFFERSIZE) NbItem = BUFFERSIZE;
318 tilelist::iterator p=InfoList.theList.begin();
319 for (int i=0;i<iFV;i++) p++;
320 ASSERT(p!=InfoList.theList.end());
321 InfoList.Reload(GetDC(),p,NbItem);
322 iFirst = iFV;
323 iLast = iFV + NbItem-1;
325 else
327 if (iFV<iFirst) iFirst = iFV;
328 else if (iLV>iLast) iLast = iLV;
330 tilelist::iterator p=InfoList.theList.begin();
331 for (int i=0;i<iFirst;i++) p++;
332 InfoList.Reload(GetDC(),p,iLast-iFirst+1);
336 void TileCtrl::CheckTile(TileInfo *theTile)
338 _Edge h,b,g,d;
339 b.CreateB(theTile);
340 h.CreateH(theTile);
341 g.CreateG(theTile);
342 d.CreateD(theTile);
344 _Edge test = b;
346 int found=0;
347 int i=0;
348 for (edgelist::iterator p=EdgeList.begin();p!=EdgeList.end();++p)
350 if (b==*p)
352 found=1;
353 theTile->b=i;
354 break;
356 i++;
358 if (!found)
360 EdgeList.insert(EdgeList.end(),b);
361 theTile->b=i;
364 found=0;
365 i=0;
366 for (p=EdgeList.begin();p!=EdgeList.end();++p)
368 if (h==*p)
370 found=1;
371 theTile->h=i;
372 break;
374 i++;
376 if (!found)
378 EdgeList.insert(EdgeList.end(),h);
379 theTile->h=i;
382 found=0;
383 i=0;
384 for (p=EdgeList.begin();p!=EdgeList.end();++p)
386 if (g==*p)
388 found=1;
389 theTile->g=i;
390 break;
392 i++;
394 if (!found)
396 EdgeList.insert(EdgeList.end(),g);
397 theTile->g=i;
400 found=0;
401 i=0;
402 for (p=EdgeList.begin();p!=EdgeList.end();++p)
404 if (d==*p)
406 found=1;
407 theTile->d=i;
408 break;
410 i++;
412 if (!found)
414 EdgeList.insert(EdgeList.end(),d);
415 theTile->d=i;
420 void TileCtrl::DeleteTile(int i)
422 /* for (tilelist::iterator p=InfoList.theList.begin();p!=InfoList.theList.end();++p)
424 if (*p==(TileInfo*)GetItemData(i))
426 InfoList.Delete(p,1);
430 //this->DeleteItem(i); //temp, should first delete the bitmap file and the DIB section
431 /*TileInfo *info = (TileInfo*)GetItemData(i);
432 if (info && info->Loaded)
434 //delete info->DibSection;
435 delete info->Bits;
436 if (info->id==last_id-1) {
437 do {
438 DeleteItem(i--);
439 last_id--;
440 } while(i>=0 && !((TileInfo*)GetItemData(i))->Loaded);
442 else
444 info->Loaded=0;
445 LVITEM item;
446 item.mask=LVIF_STATE;
447 item.stateMask=LVIS_SELECTED;
448 item.state=0;
449 SetItemState(i,&item);
452 SortItems(CompareFunc,(DWORD)this);*/
455 int TileCtrl::IsSelected(int i)
457 POSITION pos = this->GetFirstSelectedItemPosition();
458 for (int k=0;k<GetSelectedCount();k++)
460 if (GetNextSelectedItem(pos)==i) return 1;
462 return 0;
465 void TileCtrl::DrawTile(int i,CDC *pDC)
467 TileInfo *bmp;// = (TileInfo*)this->GetItemData(i);
468 tilelist::iterator p=InfoList.theList.begin();
469 for (int k=0;k<i && p!=InfoList.theList.end();k++) p++;
470 if (p==InfoList.theList.end()) return;
471 bmp = *p;
472 if (bmp)
474 POINT pt;
475 pt = GetPos(i);
476 if (!bmp->Loaded)
478 StretchDIBits(pDC->m_hDC,pt.x,pt.y,
479 sizeicon_x,sizeicon_y,0,0,
480 TileCroix.BmpInfo.bmiHeader.biWidth,TileCroix.BmpInfo.bmiHeader.biHeight,
481 TileCroix.Bits,&TileCroix.BmpInfo,DIB_RGB_COLORS,SRCCOPY);
483 else
485 RECT rect;
486 GetClientRect(&rect);
487 StretchDIBits(pDC->m_hDC,pt.x,pt.y,
488 rect.right - rect.left,rect.bottom - rect.top,0,0,
489 bmp->BmpInfo.bmiHeader.biWidth,bmp->BmpInfo.bmiHeader.biHeight,
490 bmp->Bits,&bmp->BmpInfo,DIB_RGB_COLORS,SRCCOPY);
493 CString str= GetItemText(i,0);
494 char temp[100];
495 char Name[256];
496 if (InfoTexte==2)
498 _splitpath(str.GetBuffer(256),temp,temp,Name,temp);
500 else
502 sprintf(Name,"%d",bmp->id);
507 void TileCtrl::ShadeRect( CDC *pDC, CRect& rect )
509 // Bit pattern for a monochrome brush with every
510 // other pixel turned off
511 WORD Bits[8] = { 0x0055, 0x00aa, 0x0055, 0x00aa,
512 0x0055, 0x00aa, 0x0055, 0x00aa };
514 CBitmap bmBrush;
515 CBrush brush;
517 // Need a monochrome pattern bitmap
518 bmBrush.CreateBitmap( 8, 8, 1, 1, &Bits );
520 // Create the pattern brush
521 brush.CreatePatternBrush( &bmBrush );
523 CBrush *pOldBrush = pDC->SelectObject( &brush );
525 // Turn every other pixel to black
526 COLORREF clrBk = pDC->SetBkColor( RGB(255,255,255) );
527 COLORREF clrText = pDC->SetTextColor( RGB(0,0,0) );
528 // 0x00A000C9 is the ROP code to AND the brush with the destination
529 pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(),
530 (DWORD)0x00A000C9); //DPa - raster code
532 pDC->SetBkColor( RGB(0,0,0) );
533 pDC->SetTextColor( GetSysColor(COLOR_HIGHLIGHT) );
534 // 0x00FA0089 is the ROP code to OR the brush with the destination
535 pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(),
536 (DWORD)0x00FA0089); //DPo - raster code
538 // Restore the device context
539 pDC->SelectObject( pOldBrush );
540 pDC->SetBkColor( clrBk );
541 pDC->SetTextColor( clrText );
544 void TileCtrl::OnPaint()
546 CPaintDC dc(this); // device context for painting
547 // TODO: Add your message handler code here
548 Browse *parent = (Browse*)this->GetParent();
549 GetVisibility(iFV,iLV);
550 UpdateBuffer();
551 int olds = sizetile_x;
552 if (Zoom==1) {sizetile_x = sizetile_y = SIZE_SMALL; spacing_x = SPACING_SMALL_X; spacing_y = SPACING_SMALL_Y;}
553 if (Zoom==2) {sizetile_x = sizetile_y = SIZE_NORMAL; spacing_x = SPACING_NORMAL_X; spacing_y = SPACING_NORMAL_Y;}
554 if (Zoom==3) {sizetile_x = sizetile_y = SIZE_BIG; spacing_x = SPACING_BIG_X; spacing_y = SPACING_BIG_Y;}
555 if (olds!=sizetile_x && InfoList.theList.size())
557 bmp->DeleteObject();
558 bmp->CreateBitmap(sizetile_x,sizetile_y,1,24,pipo_buffer);
559 pImList->DeleteImageList();
561 pImList->Create(sizetile_x,sizetile_y,ILC_COLOR24,0,1);
562 pImList->Add(bmp,(CBitmap *)0);
563 //SetIconSpacing(spacing_x,spacing_y);
564 SetImageList(pImList,0);
566 CFont font;
567 font.CreateFont(-10,0,0,0,FW_THIN,false,false,false,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,FIXED_PITCH,NULL);
568 CFont* oldFont=dc.SelectObject(&font);
569 for (int i=iFV;i<=iLV;i++) DrawTile(i,&dc);
570 ::ReleaseDC (*this, dc);
571 dc.SelectObject(oldFont);
572 // Do not call CListCtrl::OnPaint() for painting messages
575 void TileCtrl::OnDropFiles(HDROP hDropInfo)
577 // TODO: Add your message handler code here and/or call default
578 //first : on verifie s'il les tiles doivent etre inseres
579 char FileName[256];
580 int count=DragQueryFile(hDropInfo,0xffffffff,FileName,256); //count = nombre de fichiers dans le drop
583 POINT pos;
584 DragQueryPoint(hDropInfo,&pos); //retrieve cursor position
585 for (int i=0;i<count;i++)
587 DragQueryFile(hDropInfo,i,FileName,256);
588 if (!InfoList.Add(FileName)) return;
589 // InfoList.Reload(GetDC(),InfoList.i,1);
590 int iItem = InfoList.theList.size();
591 char num[10];
592 sprintf(num,"%d",iItem);
593 InsertItem(iItem,num,0);
594 SetItemData(iItem,(DWORD)*InfoList.i);
597 i = InfoList.theList.size();
598 // UpdateBuffer();
599 CListCtrl::OnDropFiles(hDropInfo);
602 void TileCtrl::InsertItemInCtrlList(tilelist::iterator iFirst,tilelist::iterator iLast)
604 int iItem = InfoList.theList.size();
605 for (tilelist::iterator i=iFirst;i!=iLast;++i)
607 char num[10];
608 sprintf(num,"%d",iItem);
609 InsertItem(iItem,num,0);
610 SetItemData(iItem++,(DWORD)(*i));
614 LRESULT TileCtrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
616 // TODO: Add your specialized code here and/or call the base class
617 if (message==WM_MOUSEMOVE)
619 MousePos.x = LOWORD(lParam);
620 MousePos.y = HIWORD(lParam);
622 if (message==WM_DRAWITEM)
624 int toto=0;
626 if (message==WM_CLOSE) Delete();
627 if (message==WM_COMMAND) //The user had selected an item on popup menu
629 int id=LOWORD(wParam);
630 if (id==3)
632 CFileDialog *load = new CFileDialog(true,"bmp",NULL,OFN_ALLOWMULTISELECT | OFN_ENABLESIZING,"*.bmp ||",this->GetParent());
633 if (load->DoModal()==IDOK)
635 POSITION p = load->GetStartPosition(); //la doc dit que p=NULL quand il n'y a pas de selection : c'est faux, genial les MFC
636 while (p)
638 CString str = load->GetNextPathName(p);
639 if (str!=CString(""))
641 const char *pathname = (LPCTSTR)str;
642 InfoList.Add(pathname);
643 InfoList.Reload(GetDC(),InfoList.i,1);
644 CheckTile(*InfoList.i);
648 delete load;
649 //UpdateBuffer();
651 else if (id==1)
653 POSITION p = this->GetFirstSelectedItemPosition();
654 while (p)
656 int i = this->GetNextSelectedItem(p);
657 DeleteTile(i);
659 //UpdateBuffer();
661 else if (id==0)
663 CFileDialog *load = new CFileDialog(true,"bmp",NULL,OFN_ENABLESIZING,"*.bmp ||",this->GetParent());
664 if (load->DoModal()==IDOK)
666 POSITION p = load->GetStartPosition(); //la doc dit que p=NULL quand il n'y a pas de selection : c'est faux, genial les MFC
667 CString str = load->GetNextPathName(p);
668 if (str!=CString(""))
670 const char *pathname = (LPCTSTR)str;
671 POSITION sel = GetFirstSelectedItemPosition();
672 InfoList.Add(pathname);
673 // InfoList.Reload(GetDC(),InfoList.i,1);
674 int iItem = InfoList.theList.size();
675 char num[10];
676 sprintf(num,"%d",iItem);
677 InsertItem(iItem,num,0);
678 SetItemData(iItem,(DWORD)*InfoList.i);
681 delete load;
682 //UpdateBuffer();
684 else if (id==2)
686 ViewTileMode = 1;
687 Browse *parent = (Browse*) this->GetParent();
688 POSITION sel = GetFirstSelectedItemPosition();
689 int i = GetNextSelectedItem(sel);
690 parent->TileSelected = (TileInfo*)GetItemData(i);
691 parent->SendMessage(WM_PAINT,0,0);
692 //UpdateBuffer();
694 else if (id==4)
696 ViewTileMode = 0; int iItem=0;
697 ((Browse*)GetParent())->TileSelected = NULL;
698 GetParent()->SendMessage(WM_PAINT,0,0);
699 DeleteAllItems();
700 InsertItemInCtrlList(InfoList.theList.begin(),InfoList.theList.end());
701 //UpdateBuffer();
703 SendMessage(WM_PAINT,0,0);
705 return CListCtrl::WindowProc(message, wParam, lParam);
709 void TileCtrl::OnRButtonDown(UINT nFlags, CPoint point)
711 // TODO: Add your message handler code here and/or call default
712 RECT wndpos; CMenu popup;
713 GetParent->GetWindowRect(&wndpos);
714 popup.CreatePopupMenu();
715 if (!ViewTileMode)
717 popup.AppendMenu(GetSelectedCount()==1 ? MF_STRING : MF_STRING | MF_GRAYED,0,"Remplacer...");
718 popup.AppendMenu(GetSelectedCount()>0 ? MF_STRING : MF_STRING | MF_GRAYED,1,"Supprimer");
719 popup.AppendMenu(MF_STRING,3,"Inserer...");
721 popup.TrackPopupMenu(TPM_LEFTALIGN,MousePos.x+wndpos.left,MousePos.y+wndpos.top,GetParent(),NULL);
722 CListCtrl::OnRButtonDown(nFlags, point);
725 void TileCtrl::OnLButtonDown(UINT nFlags, CPoint point)
727 // TODO: Add your message handler code here and/or call default
729 SendMessage(WM_PAINT,0,0);
730 CListCtrl::OnLButtonDown(nFlags, point);
733 void TileCtrl::OnLButtonDblClk(UINT nFlags, CPoint point)
735 // TODO: Add your message handler code here and/or call default
736 if (GetSelectedCount()==1)
738 ViewTileMode = 1;
739 Browse *parent = (Browse*) this->GetParent();
740 POSITION sel = GetFirstSelectedItemPosition();
741 int i = GetNextSelectedItem(sel);
742 parent->TileSelected = (TileInfo*)GetItemData(i);
743 parent->SendMessage(WM_PAINT,0,0);
744 CListCtrl::OnLButtonDblClk(nFlags, point);
748 void TileCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
750 // TODO: Add your message handler code here and/or call default
751 CListCtrl::OnVScroll(nSBCode, nPos, pScrollBar);