#include "dcpomatic_button.h"
#include "wx_util.h"
-#include "lib/warnings.h"
-DCPOMATIC_DISABLE_WARNINGS
+#include <dcp/warnings.h>
+LIBDCP_DISABLE_WARNINGS
#include <wx/listctrl.h>
#include <wx/wx.h>
-DCPOMATIC_ENABLE_WARNINGS
+LIBDCP_ENABLE_WARNINGS
#include <vector>
bool growable;
};
+
+namespace EditableListButton
+{
+ static int constexpr NEW = 0x1;
+ static int constexpr EDIT = 0x2;
+ static int constexpr REMOVE = 0x4;
+};
+
+
/** @param T type of things being edited.
* @param S dialog to edit a thing.
* @param get Function to get a std::vector of the things being edited.
std::function<std::vector<T> ()> get,
std::function<void (std::vector<T>)> set,
std::function<std::string (T, int)> column,
- bool can_edit = true,
- bool title = true
+ bool title,
+ int buttons
)
: wxPanel (parent)
, _get (get)
, _set (set)
, _columns (columns)
, _column (column)
- , _edit (0)
, _default_width (200)
{
_sizer = new wxBoxSizer (wxHORIZONTAL);
/* With the GTK3 backend wxListCtrls are hard to pick out from the background of the
* window, so put a border in to help.
*/
- wxPanel* border = new wxPanel (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL | wxBORDER_THEME);
+ auto border = new wxPanel (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL | wxBORDER_THEME);
_list = new wxListCtrl (border, wxID_ANY, wxDefaultPosition, wxSize(total_width, 100), style);
- wxBoxSizer* border_sizer = new wxBoxSizer (wxHORIZONTAL);
+ auto border_sizer = new wxBoxSizer (wxHORIZONTAL);
border_sizer->Add (_list, 1, wxALL | wxEXPAND, 2);
border->SetSizer (border_sizer);
#else
#endif
{
- wxSizer* s = new wxBoxSizer (wxVERTICAL);
- _add = new Button (this, _("Add..."));
- s->Add (_add, 1, wxEXPAND | wxTOP | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
- if (can_edit) {
+ auto s = new wxBoxSizer (wxVERTICAL);
+ if (buttons & EditableListButton::NEW) {
+ _add = new Button (this, _("Add..."));
+ s->Add (_add, 1, wxEXPAND | wxTOP | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
+ }
+ if (buttons & EditableListButton::EDIT) {
_edit = new Button (this, _("Edit..."));
s->Add (_edit, 1, wxEXPAND | wxTOP | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
}
- _remove = new Button (this, _("Remove"));
- s->Add (_remove, 1, wxEXPAND | wxTOP | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
+ if (buttons & EditableListButton::REMOVE) {
+ _remove = new Button (this, _("Remove"));
+ s->Add (_remove, 1, wxEXPAND | wxTOP | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
+ }
_sizer->Add (s, 0, wxLEFT, DCPOMATIC_SIZER_X_GAP);
}
- _add->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&EditableList::add_clicked, this));
+ if (_add) {
+ _add->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&EditableList::add_clicked, this));
+ }
if (_edit) {
_edit->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&EditableList::edit_clicked, this));
}
- _remove->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&EditableList::remove_clicked, this));
+ if (_remove) {
+ _remove->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&EditableList::remove_clicked, this));
+ }
_list->Bind (wxEVT_COMMAND_LIST_ITEM_SELECTED, boost::bind (&EditableList::selection_changed, this));
_list->Bind (wxEVT_COMMAND_LIST_ITEM_DESELECTED, boost::bind (&EditableList::selection_changed, this));
{
_list->DeleteAllItems ();
- std::vector<T> current = _get ();
- for (typename std::vector<T>::iterator i = current.begin (); i != current.end(); ++i) {
- add_to_control (*i);
+ auto current = _get ();
+ for (auto const& i: current) {
+ add_to_control (i);
}
}
{
int item = _list->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
if (item == -1) {
- return boost::optional<T> ();
+ return {};
}
- std::vector<T> all = _get ();
+ auto all = _get ();
DCPOMATIC_ASSERT (item >= 0 && item < int (all.size ()));
return all[item];
}
if (_edit) {
_edit->Enable (i >= 0);
}
- _remove->Enable (i >= 0);
+ if (_remove) {
+ _remove->Enable (i >= 0);
+ }
SelectionChanged ();
}
S* dialog = new S (this);
if (dialog->ShowModal() == wxID_OK) {
- boost::optional<T> const v = dialog->get ();
+ auto const v = dialog->get ();
+ static_assert(std::is_same<typename std::remove_const<decltype(v)>::type, boost::optional<T>>::value, "get() must return boost::optional<T>");
if (v) {
add_to_control (v.get ());
- std::vector<T> all = _get ();
+ auto all = _get ();
all.push_back (v.get ());
_set (all);
}
S* dialog = new S (this);
dialog->set (all[item]);
if (dialog->ShowModal() == wxID_OK) {
- boost::optional<T> const v = dialog->get ();
+ auto const v = dialog->get ();
+ static_assert(std::is_same<typename std::remove_const<decltype(v)>::type, boost::optional<T>>::value, "get() must return boost::optional<T>");
if (!v) {
return;
}
}
_list->DeleteItem (i);
- std::vector<T> all = _get ();
+ auto all = _get ();
all.erase (all.begin() + i);
_set (all);
std::vector<EditableListColumn> _columns;
std::function<std::string (T, int)> _column;
- wxButton* _add;
- wxButton* _edit;
- wxButton* _remove;
+ wxButton* _add = nullptr;
+ wxButton* _edit = nullptr;
+ wxButton* _remove = nullptr;
wxListCtrl* _list;
wxBoxSizer* _sizer;
int _default_width;