Membres inscrits :2359
Membres en ligne : 0
Invités en ligne : 4


|
Menu Snippets (navigation): |
Détails du snippet : [wxMenu] : Créer une RecentList |
Informations sur l'auteur de ce snippet : | |

Hors ligne
| Xaviou (Administrateur)
Lieu: Annecy (74)
Inscrit le : 27-08-2007
Messages: 1390
Snippets: 25
Tutoriels: 6
|
Introduction / Description : | |
Bonjour à tous.
Il est fréquent, lorsque l'on code une application qui lit des fichiers ou des dossiers, d'avoir à implémenter une "Recent List", afin d'offrir un accès rapide aux dernier éléments ouverts.
Voici la méthode que j'ai utilisé.
La déclaration de la classe : recentlist.h:
Code wxWidgets:#ifndef RECENTLIST_H_INCLUDED #define RECENTLIST_H_INCLUDED #include "wx/wxprec.h" #ifndef WX_PRECOMP #include "wx/wx.h" #endif class RecentList { public: RecentList(); virtual ~RecentList(); void Append(const wxString &sValue); void SetLastUsed(const wxString &sValue); int GetEntryCount(); int GetMaxEntries(); wxString GetEntry(int Index); void SetMaxEntries(int iNbEntries); void SetAssociatedMenu(wxMenu *Menu); private: void UpdateMenu(); int p_iMax; wxArrayString sEntry; wxMenu *p_Menu; }; #endif // RECENTLIST_H_INCLUDED L'implémentation de la classe : recentlist.cpp:
Code wxWidgets:#include "recentlist.h" RecentList::RecentList() { p_iMax=0; sEntry.Clear(); p_Menu=NULL; } RecentList::~RecentList() { } void RecentList::Append(const wxString &sValue) { wxString sTxt; if (((int)sEntry.Count()<p_iMax)&&(sValue!=wxEmptyString)) { sEntry.Add(sValue); UpdateMenu(); } } void RecentList::SetLastUsed(const wxString &sValue) { if (sValue==wxEmptyString) return; wxString pSVal=sValue; if (pSVal.Last()!='\\') pSVal+='\\'; int idx=sEntry.Index(pSVal,FALSE); wxString sTxt; // si l'entrée existe déjà dans la liste if (idx!=wxNOT_FOUND) { // Si l'entrée est déjà au début de la liste, // alors, il n'y a rien à faire => On sort if (idx==0) return; // sinon, on enlève l'entrée de son emplacement actuel sEntry.RemoveAt(idx); } // On insert l'entrée au début de celle-ci sEntry.Insert(pSVal,0); // Si on a dépassé le nombre maxi d'entrées voulues, alors, on enlève la dernière while ((int)sEntry.Count()>p_iMax) { sEntry.RemoveAt(sEntry.Count()-1); } // Mise à jour éventuelle du menu associé UpdateMenu(); } int RecentList::GetEntryCount() { return (int)sEntry.Count(); } int RecentList::GetMaxEntries() { return p_iMax; } wxString RecentList::GetEntry(int Index) { if (Index>(p_iMax-1)) return wxEmptyString; if (Index>(int)(sEntry.Count()-1)) return wxEmptyString; return sEntry[Index]; } void RecentList::SetMaxEntries(int iNbEntries) { if ((iNbEntries==0)||(iNbEntries==p_iMax)) return; // On ne peut mettre que 9 entrées maximum, sinon, il faut passer par des // IDs personnalisés if (iNbEntries>9) return; // Si on veut diminuer le nombre maximum d'entrées if (iNbEntries<p_iMax) { // on supprime la dernière entrée jusqu'à obtenir // le nombre correct de valeurs while(iNbEntries<(int)sEntry.Count()) { sEntry.RemoveAt(sEntry.Count()-1); } } // Dans les deux cas, on définit le nouveau nombre maximum d'entrées dans la liste p_iMax=iNbEntries; // et on met à jour le menu UpdateMenu(); } void RecentList::SetAssociatedMenu(wxMenu *Menu) { p_Menu=Menu; if (p_Menu==NULL) return; if ((int)Menu->GetMenuItemCount()>0) return; int imax; wxString sTxt; imax=p_iMax; if ((int)sEntry.Count()<imax) imax=sEntry.Count(); // On crée la première entrée du menu ici p_Menu->Append(wxID_FILE1,_T("Liste vide")); p_Menu->Enable(wxID_FILE1,false); UpdateMenu(); } void RecentList::UpdateMenu() { int i,imax,immax; wxString sTxt; if (p_Menu==NULL) return; immax=p_Menu->GetMenuItemCount(); imax=sEntry.Count(); if (immax!=imax) // Si on n'a pas le même nombre d'entrées que de menuitems { // il y a un cas particulier : 1 menuitem et 0 entrées dans la liste // c'est normal, l'item est "Liste Vide" if ((immax==1)&&(imax==0)) return; // Si on a plus de menuitems que d'entrées dans la liste, ce qui peut // se produire lors d'un changement du nombre maxi d'entrées while(immax>imax) { p_Menu->Destroy(wxID_FILE1+immax-1); immax--; } // Si on a moins de menuitems que d'entrées dans la liste while(immax<imax) { // On crée un menuitem avec un texte temporaire p_Menu->Append(wxID_FILE1+immax,_T("Recent Entry")); immax++; } } // Mise à jour des entrées du menu for (i=0;i<immax;i++) { sTxt.Printf("Ouvrir la zone \"%s\"",sEntry[i].c_str()); p_Menu->SetLabel(wxID_FILE1+i,_T(sEntry[i])); p_Menu->SetHelpString(wxID_FILE1+i,sTxt); } // Activation de la première entrée, si ce n'étais pas déjà fait p_Menu->Enable(wxID_FILE1,true); }
Le principe d'utilisation est (Ã mon avis) assez simple : - On mets une variable de type RecentList membre de la frame :
Code wxWidgets:- On crée le menu qui va recevoir la recent list.
Code wxWidgets:menuFile->AppendSeparator(); wxMenu *menuRecents=new wxMenu; menuFile->Append(IDM_RECENTS,_T("Ré-ouvrir"),menuRecents); menuFile->AppendSeparator(); - On associe ce menu à la recent list :
Code wxWidgets:m_recentlist.SetAssociatedMenu(menuRecents); - On initialise éventuellement la liste avec les données qu'elle doit contenir (dans l'ordre):
Code wxWidgets:m_recentlist.SetMaxEntries(9); for (int i=0;i<9;i++) m_recentlist.Append(wxString::Format(_T("Recent item #%d"),i+1)); - On n'oublie pas de mettre les entrées de menu dans la table des événements :
Code wxWidgets:EVT_MENU_RANGE(wxID_FILE1,wxID_FILE9,MainFrame::OnRecentClicked) - Et à chaque appel de "OnRecentClicked", on appelle la méthode SetLastUsed qui se charge de réorganiser tout ça. Si vous avez besoin d'un peu plus d'explications, n'hésitez pas. @+ Xav'
Mathelec (Membre)
Inscrit le : 26-11-2007
Messages: 44
Snippets: 0
Tutoriels: 0
Hors ligne |
Super snippet !
|
|
Menu Snippets (navigation): |
|