X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Fwx%2Feditable_list.h;h=eb06f4cf8869a835273f2c44ac8b2a04941db5ba;hb=2eab969654eca2ef4b222790c8b730a6eb709565;hp=731434186001cb5d220b08d58b0d6dcc27350202;hpb=162901a5cb0b5be55e2d64ecbf98ed92265dc234;p=dcpomatic.git diff --git a/src/wx/editable_list.h b/src/wx/editable_list.h index 731434186..eb06f4cf8 100644 --- a/src/wx/editable_list.h +++ b/src/wx/editable_list.h @@ -1,24 +1,35 @@ /* - Copyright (C) 2012 Carl Hetherington + Copyright (C) 2012-2016 Carl Hetherington - This program is free software; you can redistribute it and/or modify + This file is part of DCP-o-matic. + + DCP-o-matic is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + DCP-o-matic is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with DCP-o-matic. If not, see . */ +#ifndef DCPOMATIC_EDITABLE_LIST_H +#define DCPOMATIC_EDITABLE_LIST_H + +#include "wx_util.h" #include +#include +#include +#include +/** @param T type of things being edited. + * @param S dialog to edit a thing. + */ template class EditableList : public wxPanel { @@ -28,61 +39,94 @@ public: std::vector columns, boost::function ()> get, boost::function)> set, - boost::function column + boost::function column, + bool can_edit = true, + bool title = true, + int column_width = 200 ) : wxPanel (parent) , _get (get) , _set (set) , _columns (columns.size ()) , _column (column) + , _edit (0) { - wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); - SetSizer (s); - - wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); - table->AddGrowableCol (0, 1); - s->Add (table, 1, wxALL | wxEXPAND, 8); + _sizer = new wxBoxSizer (wxHORIZONTAL); + SetSizer (_sizer); - _list = new wxListCtrl (this, wxID_ANY, wxDefaultPosition, wxSize (columns.size() * 200, 100), wxLC_REPORT | wxLC_SINGLE_SEL); + long style = wxLC_REPORT | wxLC_SINGLE_SEL; + if (title) { + style |= wxLC_NO_HEADER; + } + _list = new wxListCtrl (this, wxID_ANY, wxDefaultPosition, wxSize (columns.size() * column_width, 100), style); for (size_t i = 0; i < columns.size(); ++i) { wxListItem ip; ip.SetId (i); ip.SetText (std_to_wx (columns[i])); - ip.SetWidth (200); + ip.SetWidth (column_width); _list->InsertColumn (i, ip); } - table->Add (_list, 1, wxEXPAND | wxALL); + _sizer->Add (_list, 1, wxEXPAND); { wxSizer* s = new wxBoxSizer (wxVERTICAL); _add = new wxButton (this, wxID_ANY, _("Add...")); s->Add (_add, 0, wxTOP | wxBOTTOM, 2); - _edit = new wxButton (this, wxID_ANY, _("Edit...")); - s->Add (_edit, 0, wxTOP | wxBOTTOM, 2); + if (can_edit) { + _edit = new wxButton (this, wxID_ANY, _("Edit...")); + s->Add (_edit, 0, wxTOP | wxBOTTOM, 2); + } _remove = new wxButton (this, wxID_ANY, _("Remove")); s->Add (_remove, 0, wxTOP | wxBOTTOM, 2); - table->Add (s, 0); - } - - std::vector current = _get (); - for (typename std::vector::iterator i = current.begin (); i != current.end(); ++i) { - add_to_control (*i); + _sizer->Add (s, 0, wxLEFT, DCPOMATIC_SIZER_X_GAP); } _add->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&EditableList::add_clicked, this)); - _edit->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&EditableList::edit_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)); _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->Bind (wxEVT_SIZE, boost::bind (&EditableList::resized, this, _1)); + + refresh (); selection_changed (); + } + + void refresh () + { + _list->DeleteAllItems (); + std::vector current = _get (); + for (typename std::vector::iterator i = current.begin (); i != current.end(); ++i) { + add_to_control (*i); + } } -private: + boost::optional selection () const + { + int item = _list->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item == -1) { + return boost::optional (); + } + + std::vector all = _get (); + DCPOMATIC_ASSERT (item >= 0 && item < int (all.size ())); + return all[item]; + } + + void layout () + { + _sizer->Layout (); + } + + boost::signals2::signal SelectionChanged; + +private: void add_to_control (T item) { @@ -99,23 +143,28 @@ private: void selection_changed () { int const i = _list->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - _edit->Enable (i >= 0); + if (_edit) { + _edit->Enable (i >= 0); + } _remove->Enable (i >= 0); + + SelectionChanged (); } void add_clicked () { - T new_item; S* dialog = new S (this); - dialog->set (new_item); - dialog->ShowModal (); - add_to_control (dialog->get ()); - - std::vector all = _get (); - all.push_back (dialog->get ()); - _set (all); - + if (dialog->ShowModal() == wxID_OK) { + boost::optional const v = dialog->get (); + if (v) { + add_to_control (v.get ()); + std::vector all = _get (); + all.push_back (v.get ()); + _set (all); + } + } + dialog->Destroy (); } @@ -127,14 +176,20 @@ private: } std::vector all = _get (); - assert (item >= 0 && item < int (all.size ())); + DCPOMATIC_ASSERT (item >= 0 && item < int (all.size ())); S* dialog = new S (this); dialog->set (all[item]); - dialog->ShowModal (); - all[item] = dialog->get (); + if (dialog->ShowModal() == wxID_OK) { + boost::optional const v = dialog->get (); + if (!v) { + return; + } + + all[item] = v.get (); + } dialog->Destroy (); - + for (int i = 0; i < _columns; ++i) { _list->SetItem (item, i, std_to_wx (_column (all[item], i))); } @@ -148,7 +203,7 @@ private: if (i == -1) { return; } - + _list->DeleteItem (i); std::vector all = _get (); all.erase (all.begin() + i); @@ -175,4 +230,7 @@ private: wxButton* _edit; wxButton* _remove; wxListCtrl* _list; + wxBoxSizer* _sizer; }; + +#endif