Skip to content

Commit

Permalink
#5127: Implement context menu with a "Remove from Favourites" option.
Browse files Browse the repository at this point in the history
Since the wxListView items cannot store much apart from the name, the FavouritesBrowser needs to keep a local shadow structure in memory to save the info we need for removing the items from the favourites set.
  • Loading branch information
codereader committed Jan 6, 2021
1 parent 67a1290 commit 7ea6e7d
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 4 deletions.
51 changes: 48 additions & 3 deletions radiant/ui/favourites/FavouritesBrowser.cpp
Expand Up @@ -10,13 +10,16 @@
#include <wx/checkbox.h>

#include "module/StaticModule.h"
#include "wxutil/menu/IconTextMenuItem.h"

namespace ui
{

namespace
{
const char* const TAB_NAME = "favourites";
const char* const ADD_TO_FAVOURITES = N_("Add to Favourites");
const char* const REMOVE_FROM_FAVOURITES = N_("Remove from Favourites");
}

FavouritesBrowser::FavouritesBrowser() :
Expand All @@ -40,8 +43,9 @@ void FavouritesBrowser::construct()
_mainWidget = new wxPanel(_tempParent, wxID_ANY);
_mainWidget->SetSizer(new wxBoxSizer(wxVERTICAL));

_listView = new wxListCtrl(_mainWidget, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_LIST);
_listView = new wxListView(_mainWidget, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_LIST);
_listView->Bind(wxEVT_PAINT, &FavouritesBrowser::onListCtrlPaint, this);
_listView->Bind(wxEVT_CONTEXT_MENU, &FavouritesBrowser::onContextMenu, this);

_iconList.reset(new wxImageList(16, 16));
_listView->SetImageList(_iconList.get(), wxIMAGE_LIST_SMALL);
Expand All @@ -54,6 +58,25 @@ void FavouritesBrowser::construct()

_mainWidget->GetSizer()->Add(toolHBox, 0, wxEXPAND);
_mainWidget->GetSizer()->Add(_listView, 1, wxEXPAND);

constructPopupMenu();
}

void FavouritesBrowser::clearItems()
{
_listView->ClearAll();
_listItems.clear();
}

void FavouritesBrowser::constructPopupMenu()
{
_popupMenu.reset(new wxutil::PopupMenu);

_popupMenu->addItem(
new wxutil::StockIconTextMenuItem(_(REMOVE_FROM_FAVOURITES), wxART_DEL_BOOKMARK),
std::bind(&FavouritesBrowser::onRemoveFromFavourite, this),
[this]() { return _listView->GetSelectedItemCount() > 0; }
);
}

void FavouritesBrowser::setupCategories()
Expand Down Expand Up @@ -129,7 +152,7 @@ wxToolBar* FavouritesBrowser::createLeftToolBar()
void FavouritesBrowser::reloadFavourites()
{
_updateNeeded = false;
_listView->ClearAll();
clearItems();

for (const auto& category : _categories)
{
Expand All @@ -150,7 +173,11 @@ void FavouritesBrowser::reloadFavourites()
displayName = displayName.substr(slashPos == std::string::npos ? 0 : slashPos + 1);
}

_listView->InsertItem(_listView->GetItemCount(), displayName, category.iconIndex);
auto index = _listView->InsertItem(_listView->GetItemCount(), displayName, category.iconIndex);

// Keep the item info locally, store a pointer to it in the list item user data
auto& listItem = _listItems.emplace_back(FavouriteItem{ category.type, fav });
_listView->SetItemPtrData(index, reinterpret_cast<wxUIntPtr>(&listItem));
}
}
}
Expand Down Expand Up @@ -253,6 +280,24 @@ void FavouritesBrowser::onListCtrlPaint(wxPaintEvent& ev)
ev.Skip();
}

void FavouritesBrowser::onContextMenu(wxContextMenuEvent& ev)
{
_popupMenu->show(_listView);
}

void FavouritesBrowser::onRemoveFromFavourite()
{
long item = _listView->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);

while (item != -1)
{
auto* data = reinterpret_cast<FavouriteItem*>(_listView->GetItemData(item));
GlobalFavouritesManager().removeFavourite(data->type, data->fullPath);

item = _listView->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
}
}

module::StaticModule<FavouritesBrowser> favouritesBrowserModule;

}
19 changes: 18 additions & 1 deletion radiant/ui/favourites/FavouritesBrowser.h
Expand Up @@ -3,21 +3,31 @@
#include "imodule.h"
#include "icommandsystem.h"
#include "idecltypes.h"

#include <wx/listctrl.h>
#include <wx/imaglist.h>
#include <wx/toolbar.h>
#include <sigc++/connection.h>

#include "wxutil/menu/PopupMenu.h"

namespace ui
{

class FavouritesBrowser :
public RegisterableModule
{
private:
// Holds the data used to construct the wxListItem
struct FavouriteItem
{
decl::Type type;
std::string fullPath;
};

wxFrame* _tempParent;
wxWindow* _mainWidget;
wxListCtrl* _listView;
wxListView* _listView;

std::unique_ptr<wxImageList> _iconList;

Expand All @@ -33,10 +43,13 @@ class FavouritesBrowser :
// Maps decl type to icon index
std::list<FavouriteCategory> _categories;
std::list<sigc::connection> changedConnections;
std::list<FavouriteItem> _listItems;

wxCheckBox* _showFullPath;
bool _updateNeeded;

wxutil::PopupMenuPtr _popupMenu;

public:
FavouritesBrowser();

Expand All @@ -53,11 +66,15 @@ class FavouritesBrowser :
void onFavouritesChanged();
void reloadFavourites();
void setupCategories();
void constructPopupMenu();
void clearItems();

void onRemoveFromFavourite();
void togglePage(const cmd::ArgumentList& args);
void onCategoryToggled(wxCommandEvent& ev);
void onShowFullPathToggled(wxCommandEvent& ev);
void onListCtrlPaint(wxPaintEvent& ev);
void onContextMenu(wxContextMenuEvent& ev);
};

}

0 comments on commit 7ea6e7d

Please sign in to comment.